Skip to content
Snippets Groups Projects
Commit d793e7be authored by Martin Lowe's avatar Martin Lowe :no_entry: Committed by Martin Lowe
Browse files

Create a solution version endpoint #43


Added new endpoint for solution versions. Updated listings to import
data from new listing versions table. Updated quarkus to version 0.28.
Removed brittle ResourceDataType annotation.

Change-Id: I1f108666b10cfa55de098f74e586688b8656ab90
Signed-off-by: Martin Lowe's avatarMartin Lowe <martin.lowe@eclipse-foundation.org>
parent 2428a4b6
No related branches found
No related tags found
No related merge requests found
...@@ -26,7 +26,6 @@ import org.eclipsefoundation.marketplace.dto.filter.DtoFilter; ...@@ -26,7 +26,6 @@ import org.eclipsefoundation.marketplace.dto.filter.DtoFilter;
import org.eclipsefoundation.marketplace.helper.StreamHelper; import org.eclipsefoundation.marketplace.helper.StreamHelper;
import org.eclipsefoundation.marketplace.model.MongoQuery; import org.eclipsefoundation.marketplace.model.MongoQuery;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
import org.eclipsefoundation.marketplace.model.ResourceDataType;
import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; import org.eclipsefoundation.marketplace.namespace.UrlParameterNames;
import org.eclipsefoundation.marketplace.service.CachingService; import org.eclipsefoundation.marketplace.service.CachingService;
import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.jboss.resteasy.annotations.jaxrs.PathParam;
...@@ -40,7 +39,6 @@ import org.slf4j.LoggerFactory; ...@@ -40,7 +39,6 @@ import org.slf4j.LoggerFactory;
*/ */
@RequestScoped @RequestScoped
@Path("/error") @Path("/error")
@ResourceDataType(ErrorReport.class)
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public class ErrorReportResource { public class ErrorReportResource {
......
...@@ -29,7 +29,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper; ...@@ -29,7 +29,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper;
import org.eclipsefoundation.marketplace.model.Error; import org.eclipsefoundation.marketplace.model.Error;
import org.eclipsefoundation.marketplace.model.MongoQuery; import org.eclipsefoundation.marketplace.model.MongoQuery;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
import org.eclipsefoundation.marketplace.model.ResourceDataType;
import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; import org.eclipsefoundation.marketplace.namespace.UrlParameterNames;
import org.eclipsefoundation.marketplace.service.CachingService; import org.eclipsefoundation.marketplace.service.CachingService;
import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.jboss.resteasy.annotations.jaxrs.PathParam;
...@@ -42,7 +41,6 @@ import org.slf4j.LoggerFactory; ...@@ -42,7 +41,6 @@ import org.slf4j.LoggerFactory;
* @author Martin Lowe * @author Martin Lowe
*/ */
@RequestScoped @RequestScoped
@ResourceDataType(Install.class)
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/installs") @Path("/installs")
......
...@@ -32,7 +32,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper; ...@@ -32,7 +32,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper;
import org.eclipsefoundation.marketplace.model.Error; import org.eclipsefoundation.marketplace.model.Error;
import org.eclipsefoundation.marketplace.model.MongoQuery; import org.eclipsefoundation.marketplace.model.MongoQuery;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
import org.eclipsefoundation.marketplace.model.ResourceDataType;
import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; import org.eclipsefoundation.marketplace.namespace.UrlParameterNames;
import org.eclipsefoundation.marketplace.service.CachingService; import org.eclipsefoundation.marketplace.service.CachingService;
import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.jboss.resteasy.annotations.jaxrs.PathParam;
...@@ -46,7 +45,6 @@ import com.mongodb.client.result.DeleteResult; ...@@ -46,7 +45,6 @@ import com.mongodb.client.result.DeleteResult;
* *
* @author Martin Lowe * @author Martin Lowe
*/ */
@ResourceDataType(Listing.class)
@Path("/listings") @Path("/listings")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
......
/* Copyright (c) 2019 Eclipse Foundation and others.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License 2.0
* which is available at http://www.eclipse.org/legal/epl-v20.html,
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipsefoundation.marketplace.resource;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.eclipsefoundation.marketplace.dao.MongoDao;
import org.eclipsefoundation.marketplace.dto.ListingVersion;
import org.eclipsefoundation.marketplace.dto.filter.DtoFilter;
import org.eclipsefoundation.marketplace.helper.StreamHelper;
import org.eclipsefoundation.marketplace.model.Error;
import org.eclipsefoundation.marketplace.model.MongoQuery;
import org.eclipsefoundation.marketplace.model.RequestWrapper;
import org.eclipsefoundation.marketplace.namespace.UrlParameterNames;
import org.eclipsefoundation.marketplace.service.CachingService;
import org.jboss.resteasy.annotations.jaxrs.PathParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mongodb.client.result.DeleteResult;
/**
* Resource for retrieving {@linkplain ListingVersion}s from the MongoDB
* instance.
*
* @author Martin Lowe
*/
@RequestScoped
@Path("/listing_versions")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ListingVersionResource {
private static final Logger LOGGER = LoggerFactory.getLogger(ListingVersionResource.class);
@Inject
MongoDao dao;
@Inject
CachingService<List<ListingVersion>> cachingService;
@Inject
RequestWrapper params;
@Inject
DtoFilter<ListingVersion> dtoFilter;
@GET
public Response select() {
MongoQuery<ListingVersion> q = new MongoQuery<>(params, dtoFilter, cachingService);
// retrieve the possible cached object
Optional<List<ListingVersion>> cachedResults = cachingService.get("all", params,
() -> StreamHelper.awaitCompletionStage(dao.get(q)));
if (!cachedResults.isPresent()) {
LOGGER.error("Error while retrieving cached ListingVersions");
return Response.serverError().build();
}
// return the results as a response
return Response.ok(cachedResults.get()).build();
}
/**
* Endpoint for /ListingVersion/ to post a new ListingVersion to the persistence layer.
*
* @param listingVersion the ListingVersion object to insert into the database.
* @return response for the browser
*/
@PUT
public Response putListingVersion(ListingVersion listingVersion) {
MongoQuery<ListingVersion> q = new MongoQuery<>(params, dtoFilter, cachingService);
// add the object, and await the result
StreamHelper.awaitCompletionStage(dao.add(q, Arrays.asList(listingVersion)));
// return the results as a response
return Response.ok().build();
}
/**
* Endpoint for /listingVersions/\<listingVersionId\> to retrieve a specific ListingVersion from the
* database.
*
* @param listingVersionId the ListingVersion ID
* @return response for the browser
*/
@GET
@Path("/{listingVersionId}")
public Response select(@PathParam("listingVersionId") String listingVersionId) {
params.addParam(UrlParameterNames.ID, listingVersionId);
MongoQuery<ListingVersion> q = new MongoQuery<>(params, dtoFilter, cachingService);
// retrieve a cached version of the value for the current listing
Optional<List<ListingVersion>> cachedResults = cachingService.get(listingVersionId, params,
() -> StreamHelper.awaitCompletionStage(dao.get(q)));
if (!cachedResults.isPresent()) {
LOGGER.error("Error while retrieving cached listing for ID {}", listingVersionId);
return Response.serverError().build();
}
// return the results as a response
return Response.ok(cachedResults.get()).build();
}
/**
* Endpoint for /listingVersions/\<listingVersionId\> to retrieve a specific ListingVersion from the
* database.
*
* @param listingVersionId the listingVersion ID
* @return response for the browser
*/
@DELETE
@Path("/{listingVersionId}")
public Response delete(@PathParam("listingVersionId") String listingVersionId) {
params.addParam(UrlParameterNames.ID, listingVersionId);
MongoQuery<ListingVersion> q = new MongoQuery<>(params, dtoFilter, cachingService);
// delete the currently selected asset
DeleteResult result = StreamHelper.awaitCompletionStage(dao.delete(q));
if (result.getDeletedCount() == 0 || !result.wasAcknowledged()) {
return new Error(Status.NOT_FOUND, "Did not find an asset to delete for current call").asResponse();
}
// return the results as a response
return Response.ok().build();
}
}
...@@ -29,7 +29,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper; ...@@ -29,7 +29,6 @@ import org.eclipsefoundation.marketplace.helper.StreamHelper;
import org.eclipsefoundation.marketplace.model.Error; import org.eclipsefoundation.marketplace.model.Error;
import org.eclipsefoundation.marketplace.model.MongoQuery; import org.eclipsefoundation.marketplace.model.MongoQuery;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
import org.eclipsefoundation.marketplace.model.ResourceDataType;
import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; import org.eclipsefoundation.marketplace.namespace.UrlParameterNames;
import org.eclipsefoundation.marketplace.service.CachingService; import org.eclipsefoundation.marketplace.service.CachingService;
import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.jboss.resteasy.annotations.jaxrs.PathParam;
...@@ -42,7 +41,6 @@ import com.mongodb.client.result.DeleteResult; ...@@ -42,7 +41,6 @@ import com.mongodb.client.result.DeleteResult;
* @author martin * @author martin
* *
*/ */
@ResourceDataType(Market.class)
@Path("/markets") @Path("/markets")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
......
const axios = require('axios'); const axios = require('axios');
const instance = axios.create({ const instance = axios.create({
timeout: 1000, timeout: 2500,
headers: {'User-Agent': 'mpc/0.0.0'} headers: {'User-Agent': 'mpc/0.0.0'}
}); });
const randomWords = require('random-words'); const randomWords = require('random-words');
...@@ -65,7 +65,7 @@ function splice(arr) { ...@@ -65,7 +65,7 @@ function splice(arr) {
return out; return out;
} }
function createListing(count) { async function createListing(count) {
if (count >= max) { if (count >= max) {
return; return;
} }
...@@ -73,14 +73,25 @@ function createListing(count) { ...@@ -73,14 +73,25 @@ function createListing(count) {
console.log(`Generating listing ${count} of ${max}`); console.log(`Generating listing ${count} of ${max}`);
var json = generateJSON(uuid.v4()); var json = generateJSON(uuid.v4());
instance.put(argv.s+"/listings/", json) instance.put(argv.s+"/listings/", json)
.then(() => { .then(listingCallback(json, count))
var installs = Math.floor(Math.random()*argv.i);
console.log(`Generating ${installs} install records for listing '${json.id}'`);
createInstall(0, installs, json, () => createListing(count+1));
})
.catch(err => console.log(err)); .catch(err => console.log(err));
} }
async function listingCallback(json, count) {
var installs = Math.floor(Math.random()*argv.i);
var solsCount = Math.floor(Math.random()*5) + 1;
var versions = [];
for (var j=0;j<solsCount;j++) {
var v = await createVersion(j, solsCount, json.id);
if (v != null) {
versions.push(v);
}
}
console.log(`Generating ${installs} install records for listing '${json.id}'`);
createInstall(0, installs, json, versions, () => createListing(count+1));
}
function createCategory(count) { function createCategory(count) {
if (count >= categoryIds.length) { if (count >= categoryIds.length) {
return; return;
...@@ -101,28 +112,27 @@ function createMarket(count) { ...@@ -101,28 +112,27 @@ function createMarket(count) {
.catch(err => console.log(err)); .catch(err => console.log(err));
} }
function createInstall(curr, max, listing, callback) { function createInstall(curr, max, listing, versions, callback) {
if (curr >= max) { if (curr >= max) {
return callback(); return callback();
} }
var json = generateInstallJSON(listing); var json = generateInstallJSON(listing, versions);
instance.post(`${argv.s}/installs/${json['listing_id']}/${json.version}`, json) instance.post(`${argv.s}/installs/${json['listing_id']}/${json.version}`, json)
.then(createInstall(curr+1,max,listing,callback)) .then(createInstall(curr+1,max,listing,versions,callback))
.catch(err => console.log(err)); .catch(err => console.log(err));
} }
function generateJSON(id) { async function createVersion(curr, max, id) {
var solutions = []; if (curr >= max) {
var solsCount = Math.floor(Math.random()*5) + 1; return;
for (var i=0; i < solsCount; i++) {
solutions.push({
"version": i,
"eclipse_versions": splice(eclipseVs),
"min_java_version": javaVs[Math.floor(Math.random()*javaVs.length)],
"platforms": splice(platforms)
});
} }
var json = generateVersionJSON(curr, id);
return instance.put(`${argv.s}/listing_versions`, json)
.then(() => {return json})
.catch(err => console.log(err));
}
function generateJSON(id) {
return { return {
"id": id, "id": id,
"title": "Sample", "title": "Sample",
...@@ -150,7 +160,6 @@ function generateJSON(id) { ...@@ -150,7 +160,6 @@ function generateJSON(id) {
"url": "" "url": ""
} }
], ],
"versions": solutions,
"market_ids": splice(marketIds).splice(0,Math.ceil(Math.random()*2)), "market_ids": splice(marketIds).splice(0,Math.ceil(Math.random()*2)),
"category_ids": splice(categoryIds).splice(0,Math.ceil(Math.random()*5)+1), "category_ids": splice(categoryIds).splice(0,Math.ceil(Math.random()*5)+1),
"screenshots": ["http://www.example.com/img/sample.png"] "screenshots": ["http://www.example.com/img/sample.png"]
...@@ -160,7 +169,7 @@ function generateJSON(id) { ...@@ -160,7 +169,7 @@ function generateJSON(id) {
function generateCategoryJSON(id) { function generateCategoryJSON(id) {
return { return {
"id": id, "id": id,
"name": randomWords({exactly:1, wordsPerString:Math.ceil(Math.random()*4)})[0], "title": randomWords({exactly:1, wordsPerString:Math.ceil(Math.random()*4)})[0],
"url": "https://www.eclipse.org" "url": "https://www.eclipse.org"
}; };
} }
...@@ -168,13 +177,13 @@ function generateCategoryJSON(id) { ...@@ -168,13 +177,13 @@ function generateCategoryJSON(id) {
function generateMarketJSON(id) { function generateMarketJSON(id) {
return { return {
"id": id, "id": id,
"name": randomWords({exactly:1, wordsPerString:Math.ceil(Math.random()*4)})[0], "title": randomWords({exactly:1, wordsPerString:Math.ceil(Math.random()*4)})[0],
"url": "https://www.eclipse.org" "url": "https://www.eclipse.org"
}; };
} }
function generateInstallJSON(listing) { function generateInstallJSON(listing,versions) {
var version = listing.versions[Math.floor(Math.random()*listing.versions.length)]; var version = versions[Math.floor(Math.random()*versions.length)];
var javaVersions = Array.from(javaVs).splice(javaVs.indexOf(version["min_java_version"])); var javaVersions = Array.from(javaVs).splice(javaVs.indexOf(version["min_java_version"]));
var eclipseVersions = Array.from(eclipseVs).splice(eclipseVs.indexOf(version["eclipse_version"])); var eclipseVersions = Array.from(eclipseVs).splice(eclipseVs.indexOf(version["eclipse_version"]));
...@@ -186,3 +195,13 @@ function generateInstallJSON(listing) { ...@@ -186,3 +195,13 @@ function generateInstallJSON(listing) {
"eclipse_version": shuff(eclipseVersions)[0] "eclipse_version": shuff(eclipseVersions)[0]
}; };
} }
function generateVersionJSON(name, listingId) {
return {
"version": name,
"listing_id": listingId,
"eclipse_versions": splice(eclipseVs),
"min_java_version": javaVs[Math.floor(Math.random()*javaVs.length)],
"platforms": splice(platforms)
};
}
...@@ -7,7 +7,7 @@ quarkus.log.file.path=/tmp/logs/quarkus.log ...@@ -7,7 +7,7 @@ quarkus.log.file.path=/tmp/logs/quarkus.log
quarkus.mongodb.connection-string = mongodb://localhost:27017 quarkus.mongodb.connection-string = mongodb://localhost:27017
quarkus.mongodb.credentials.username=root quarkus.mongodb.credentials.username=root
quarkus.mongodb.write-concern.safe=true quarkus.mongodb.write-concern.safe=true
quarkus.mongodb.min-pool-size=10 quarkus.mongodb.min-pool-size=100
quarkus.mongodb.max-pool-size=1000 quarkus.mongodb.max-pool-size=1000
quarkus.mongodb.write-concern.retry-writes=true quarkus.mongodb.write-concern.retry-writes=true
mongodb.database=mpc mongodb.database=mpc
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment