diff --git a/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java b/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java index 892660e0314498ac6cf2869a06a491ea3ed51468..460817d00fa210460fdb21ceb6ce33fb210dd674 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java @@ -6,12 +6,18 @@ */ package org.eclipsefoundation.marketplace.dao.impl; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; import javax.inject.Inject; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.conversions.Bson; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.HealthCheckResponseBuilder; @@ -23,6 +29,7 @@ import org.eclipsefoundation.marketplace.namespace.DtoTableNames; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.mongodb.client.model.ReplaceOptions; import com.mongodb.client.result.DeleteResult; import io.quarkus.mongodb.ReactiveMongoClient; @@ -49,6 +56,9 @@ public class DefaultMongoDao implements MongoDao { @ConfigProperty(name = "mongodb.maintenance", defaultValue = "false") boolean maintenanceFlag; + @Inject + Instance<CodecProvider> providers; + @Inject ReactiveMongoClient mongoClient; @@ -63,7 +73,8 @@ public class DefaultMongoDao implements MongoDao { LOGGER.debug("Getting aggregate results"); // build base query - PublisherBuilder<T> builder = getCollection(q.getDocType()).aggregate(q.getPipeline(getLimit(q)), q.getDocType()); + PublisherBuilder<T> builder = getCollection(q.getDocType()).aggregate(q.getPipeline(getLimit(q)), + q.getDocType()); // check if result set should be limited if (q.getDTOFilter().useLimit()) { builder = builder.limit(getLimit(q)); @@ -80,7 +91,25 @@ public class DefaultMongoDao implements MongoDao { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Adding {} documents to MongoDB of type {}", documents.size(), q.getDocType().getSimpleName()); } - return getCollection(q.getDocType()).insertMany(documents); + + // set up upserting to not fail on updates + ReplaceOptions ro = new ReplaceOptions().upsert(true).bypassDocumentValidation(true); + + // maintain a list of updates + List<CompletionStage<?>> stages = new ArrayList<>(documents.size()); + Bson filter = q.getFilter(); + for (T doc : documents) { + if (filter == null) { + stages.add(getCollection(q.getDocType()).insertOne(doc)); + } else { + stages.add(getCollection(q.getDocType()).replaceOne(filter, doc, ro)); + } + } + + // convert the stages to futures, and wrap them in a completable future + List<CompletableFuture<?>> all = stages.stream().map(CompletionStage::toCompletableFuture) + .collect(Collectors.toList()); + return CompletableFuture.allOf(all.toArray(new CompletableFuture[all.size()])); } @Override diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java index 0aa35a0823ad6d47f990754710457918400dbf63..03454b235b75625765b18510c3eeedfdc396cd36 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java @@ -87,6 +87,9 @@ public class CatalogResource { @PUT @RolesAllowed({ "marketplace_catalog_put", "marketplace_admin_access" }) public Response putCatalog(Catalog catalog) { + if (catalog.getId() != null) { + params.addParam(UrlParameterNames.ID, catalog.getId()); + } MongoQuery<Catalog> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result StreamHelper.awaitCompletionStage(dao.add(q, Arrays.asList(catalog))); diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java index b343c314fe57312992e7b575cc7822a3bf5f9c4f..416acc1e38b4f066295e0a70e3b6607f0aa550e8 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java @@ -87,6 +87,9 @@ public class CategoryResource { @PUT @RolesAllowed({"marketplace_category_put", "marketplace_admin_access"}) public Response putCategory(Category category) { + if (category.getId() != null) { + params.addParam(UrlParameterNames.ID, category.getId()); + } MongoQuery<Category> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result StreamHelper.awaitCompletionStage(dao.add(q, Arrays.asList(category))); diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/ErrorReportResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/ErrorReportResource.java index 5c8b1adc9d6c4417b5ead3ff67be41f4678fd879..7d4c2f0ba330b387a0fd27118497357ef4cb949a 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/ErrorReportResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/ErrorReportResource.java @@ -11,12 +11,11 @@ import java.util.List; import java.util.Optional; import javax.annotation.security.PermitAll; -import javax.annotation.security.RolesAllowed; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; -import javax.ws.rs.PUT; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @@ -41,7 +40,7 @@ import org.slf4j.LoggerFactory; * @author Martin Lowe */ @RequestScoped -@Path("/error") +@Path("/error_reports") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class ErrorReportResource { @@ -87,9 +86,13 @@ public class ErrorReportResource { * @param errorReport the ErrorReport object to insert into the database. * @return response for the browser */ - @PUT - @RolesAllowed("error_put") + @POST + @PermitAll public Response putErrorReport(ErrorReport errorReport) { + // attach ID if present for update + if (errorReport.getId() != null) { + params.addParam(UrlParameterNames.ID, errorReport.getId()); + } MongoQuery<ErrorReport> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/InstallResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/InstallResource.java index 9519ff493f5807e40fff9e1d296ee928ac4b8b9a..c49d8023e4d807e7c499497fff24c77fba16d75a 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/InstallResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/InstallResource.java @@ -165,7 +165,7 @@ public class InstallResource { * @return response for the browser */ @POST - @RolesAllowed({ "marketplace_install_put", "marketplace_admin_access" }) + @PermitAll @Path("/{listingId}/{version}") public Response postInstallMetrics(@PathParam("listingId") String listingId, @PathParam("version") String version, Install installDetails) { diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java index d31a6153f8d4c65988e235df26f35fcf7e53d665..fa5cd87ec89574c8113487214cd867c19348c3a8 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java @@ -98,6 +98,9 @@ public class ListingResource { @PUT @RolesAllowed({ "marketplace_listing_put", "marketplace_admin_access" }) public Response putListing(Listing listing) { + if (listing.getId() != null) { + params.addParam(UrlParameterNames.ID, listing.getId()); + } MongoQuery<Listing> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result @@ -154,4 +157,4 @@ public class ListingResource { // return the results as a response return Response.ok().build(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingVersionResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingVersionResource.java index 9b074b875081187bd65edf3c5ccc7d840e3811f3..66f318ad967d8e13517d70f30c0d315a987997c2 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingVersionResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingVersionResource.java @@ -10,6 +10,7 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import javax.annotation.security.RolesAllowed; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.ws.rs.Consumes; @@ -85,6 +86,9 @@ public class ListingVersionResource { */ @PUT public Response putListingVersion(ListingVersion listingVersion) { + if (listingVersion.getId() != null) { + params.addParam(UrlParameterNames.ID, listingVersion.getId()); + } MongoQuery<ListingVersion> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result StreamHelper.awaitCompletionStage(dao.add(q, Arrays.asList(listingVersion))); @@ -126,6 +130,7 @@ public class ListingVersionResource { * @return response for the browser */ @DELETE + @RolesAllowed({ "marketplace_version_delete", "marketplace_admin_access" }) @Path("/{listingVersionId}") public Response delete(@PathParam("listingVersionId") String listingVersionId) { params.addParam(UrlParameterNames.ID, listingVersionId); diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java index 44c710117eea26ae9eefe267d001b85a6ba82f95..aa0fd9593b5f838c366dc087bcaceb4e5f676b34 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java @@ -61,7 +61,7 @@ public class MarketResource { DtoFilter<Market> dtoFilter; @Inject ResponseHelper responseBuider; - + @GET @PermitAll public Response select() { @@ -85,8 +85,11 @@ public class MarketResource { * @return response for the browser */ @PUT - @RolesAllowed("market_put") + @RolesAllowed({ "marketplace_market_put", "marketplace_admin_access" }) public Response putMarket(Market market) { + if (market.getId() != null) { + params.addParam(UrlParameterNames.ID, market.getId()); + } MongoQuery<Market> q = new MongoQuery<>(params, dtoFilter); // add the object, and await the result