From a0f7aacbca34149f52c573134f39cb0fcf75bb20 Mon Sep 17 00:00:00 2001 From: Martin Lowe <martin.lowe@eclipse-foundation.org> Date: Wed, 23 Oct 2019 14:52:08 -0400 Subject: [PATCH] Add DELETE calls for appropriate resources #25 Added delete functionality for listings, categories, catalogs, and markets. Change-Id: I7b2e97a70fce3a6cafd789aa75fc5c01481fb516 Signed-off-by: Martin Lowe <martin.lowe@eclipse-foundation.org> --- .../marketplace/dao/impl/DefaultMongoDao.java | 4 +- .../marketplace/dto/filter/CatalogFilter.java | 16 +++++- .../dto/filter/CategoryFilter.java | 16 +++++- .../marketplace/dto/filter/MarketFilter.java | 11 +++- .../marketplace/resource/CatalogResource.java | 54 ++++++++++++++++++ .../resource/CategoryResource.java | 55 ++++++++++++++++++- .../marketplace/resource/ListingResource.java | 26 +++++++++ .../marketplace/resource/MarketResource.java | 27 +++++++++ 8 files changed, 199 insertions(+), 10 deletions(-) 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 56829ef..d44a93f 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dao/impl/DefaultMongoDao.java @@ -12,7 +12,6 @@ import java.util.concurrent.CompletionStage; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import org.bson.BsonDocument; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.HealthCheckResponseBuilder; @@ -85,8 +84,7 @@ public class DefaultMongoDao implements MongoDao { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Removing documents from MongoDB using the following query: {}", q); } - // TODO we need to figure out how to build this - return getCollection(q.getDocType()).deleteMany(new BsonDocument()); + return getCollection(q.getDocType()).deleteMany(q.getFilter()); } @Override diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CatalogFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CatalogFilter.java index 1d044a3..137bac5 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CatalogFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CatalogFilter.java @@ -6,14 +6,20 @@ */ package org.eclipsefoundation.marketplace.dto.filter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import org.bson.conversions.Bson; import org.eclipsefoundation.marketplace.dto.Catalog; import org.eclipsefoundation.marketplace.model.RequestWrapper; +import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; +import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; + +import com.mongodb.client.model.Filters; /** * Filter implementation for the Catalog class. @@ -24,8 +30,14 @@ import org.eclipsefoundation.marketplace.model.RequestWrapper; public class CatalogFilter implements DtoFilter<Catalog> { @Override - public List<Bson> getFilters(RequestWrapper qps) { - return Collections.emptyList(); + public List<Bson> getFilters(RequestWrapper wrap) { + List<Bson> filters = new ArrayList<>(); + // ID check + Optional<String> id = wrap.getFirstParam(UrlParameterNames.ID); + if (id.isPresent()) { + filters.add(Filters.eq(DatabaseFieldNames.DOCID, id.get())); + } + return filters; } @Override diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CategoryFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CategoryFilter.java index 71c92fe..7bdf562 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CategoryFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/CategoryFilter.java @@ -6,14 +6,20 @@ */ package org.eclipsefoundation.marketplace.dto.filter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import org.bson.conversions.Bson; import org.eclipsefoundation.marketplace.dto.Category; import org.eclipsefoundation.marketplace.model.RequestWrapper; +import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; +import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; + +import com.mongodb.client.model.Filters; /** * @author martin @@ -23,8 +29,14 @@ import org.eclipsefoundation.marketplace.model.RequestWrapper; public class CategoryFilter implements DtoFilter<Category> { @Override - public List<Bson> getFilters(RequestWrapper qps) { - return Collections.emptyList(); + public List<Bson> getFilters(RequestWrapper wrap) { + List<Bson> filters = new ArrayList<>(); + // ID check + Optional<String> id = wrap.getFirstParam(UrlParameterNames.ID); + if (id.isPresent()) { + filters.add(Filters.eq(DatabaseFieldNames.DOCID, id.get())); + } + return filters; } @Override diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java index 997a882..a73cc5f 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java @@ -12,8 +12,8 @@ import static com.mongodb.client.model.Filters.expr; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; +import java.util.Optional; import javax.enterprise.context.ApplicationScoped; @@ -23,6 +23,7 @@ import org.eclipsefoundation.marketplace.dto.Market; import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; import org.eclipsefoundation.marketplace.namespace.DtoTableNames; +import org.eclipsefoundation.marketplace.namespace.UrlParameterNames; import com.mongodb.client.model.Accumulators; import com.mongodb.client.model.Aggregates; @@ -39,7 +40,13 @@ public class MarketFilter implements DtoFilter<Market> { @Override public List<Bson> getFilters(RequestWrapper wrap) { - return Collections.emptyList(); + List<Bson> filters = new ArrayList<>(); + // ID check + Optional<String> id = wrap.getFirstParam(UrlParameterNames.ID); + if (id.isPresent()) { + filters.add(eq(DatabaseFieldNames.DOCID, id.get())); + } + return filters; } @Override diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java index ae450cc..369e3b1 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/CatalogResource.java @@ -13,24 +13,31 @@ 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.Catalog; 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.model.ResourceDataType; +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; + /** * @author martin * @@ -82,4 +89,51 @@ public class CatalogResource { // return the results as a response return Response.ok().build(); } + + /** + * Endpoint for /catalogs/\<catalogId\> to retrieve a specific Catalog from + * the database. + * + * @param catalogId the Catalog ID + * @return response for the browser + */ + @GET + @Path("/{catalogId}") + public Response select(@PathParam("catalogId") String catalogId) { + params.addParam(UrlParameterNames.ID, catalogId); + + MongoQuery<Catalog> q = new MongoQuery<>(params, dtoFilter, cachingService); + // retrieve a cached version of the value for the current listing + Optional<List<Catalog>> cachedResults = cachingService.get(catalogId, params, + () -> StreamHelper.awaitCompletionStage(dao.get(q))); + if (!cachedResults.isPresent()) { + LOGGER.error("Error while retrieving cached listing for ID {}", catalogId); + return Response.serverError().build(); + } + + // return the results as a response + return Response.ok(cachedResults.get()).build(); + } + + /** + * Endpoint for /catalogs/\<catalogId\> to retrieve a specific Catalog from + * the database. + * + * @param catalogId the catalog ID + * @return response for the browser + */ + @DELETE + @Path("/{catalogId}") + public Response delete(@PathParam("catalogId") String catalogId) { + params.addParam(UrlParameterNames.ID, catalogId); + + MongoQuery<Catalog> 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(); + } } diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java index 125e560..1879cc0 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/CategoryResource.java @@ -13,24 +13,31 @@ 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.Category; 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.model.ResourceDataType; +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; + /** * @author martin * @@ -52,7 +59,6 @@ public class CategoryResource { @Inject DtoFilter<Category> dtoFilter; - @GET public Response select() { MongoQuery<Category> q = new MongoQuery<>(params, dtoFilter, cachingService); @@ -83,4 +89,51 @@ public class CategoryResource { // return the results as a response return Response.ok().build(); } + + /** + * Endpoint for /categories/\<categoryId\> to retrieve a specific Category from + * the database. + * + * @param categoryId the Category ID + * @return response for the browser + */ + @GET + @Path("/{categoryId}") + public Response select(@PathParam("categoryId") String categoryId) { + params.addParam(UrlParameterNames.ID, categoryId); + + MongoQuery<Category> q = new MongoQuery<>(params, dtoFilter, cachingService); + // retrieve a cached version of the value for the current listing + Optional<List<Category>> cachedResults = cachingService.get(categoryId, params, + () -> StreamHelper.awaitCompletionStage(dao.get(q))); + if (!cachedResults.isPresent()) { + LOGGER.error("Error while retrieving cached listing for ID {}", categoryId); + return Response.serverError().build(); + } + + // return the results as a response + return Response.ok(cachedResults.get()).build(); + } + + /** + * Endpoint for /categories/\<categoryId\> to retrieve a specific Category from + * the database. + * + * @param categoryId the category ID + * @return response for the browser + */ + @DELETE + @Path("/{categoryId}") + public Response delete(@PathParam("categoryId") String categoryId) { + params.addParam(UrlParameterNames.ID, categoryId); + + MongoQuery<Category> 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(); + } } diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java index 3ad6184..d30a477 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/ListingResource.java @@ -16,17 +16,20 @@ 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.Listing; 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.model.ResourceDataType; @@ -36,6 +39,8 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.mongodb.client.result.DeleteResult; + /** * Resource for retrieving listings from the MongoDB instance. * @@ -121,4 +126,25 @@ public class ListingResource { // return the results as a response return Response.ok(cachedResults.get()).build(); } + + /** + * Endpoint for /listing/\<listingId\> to delete a specific listing from the + * database. + * + * @param listingId the listing ID + * @return response for the browser + */ + @DELETE + @Path("/{listingId}") + public Response delete(@PathParam("listingId") String listingId) { + params.addParam(UrlParameterNames.ID, listingId); + MongoQuery<Listing> 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(); + } } \ No newline at end of file diff --git a/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java b/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java index 5b1bbfe..7fd751e 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java +++ b/src/main/java/org/eclipsefoundation/marketplace/resource/MarketResource.java @@ -13,17 +13,20 @@ 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.Market; 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.model.ResourceDataType; @@ -33,6 +36,8 @@ import org.jboss.resteasy.annotations.jaxrs.PathParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.mongodb.client.result.DeleteResult; + /** * @author martin * @@ -110,4 +115,26 @@ public class MarketResource { // return the results as a response return Response.ok(cachedResults.get()).build(); } + + /** + * Endpoint for /markets/\<marketId\> to retrieve a specific Market from the + * database. + * + * @param marketId the market ID + * @return response for the browser + */ + @DELETE + @Path("/{marketId}") + public Response delete(@PathParam("marketId") String marketId) { + params.addParam(UrlParameterNames.ID, marketId); + + MongoQuery<Market> 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(); + } } -- GitLab