diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DeleteProductBean.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DeleteProductBean.java new file mode 100644 index 0000000..158bafd --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DeleteProductBean.java @@ -0,0 +1,44 @@ +package org.gcube.data_catalogue.grsf_publish_ws.json.input; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Bean to be used for input of delete-product methods + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization +public class DeleteProductBean { + + @JsonProperty("id") + @NotNull(message="id cannot be null") + @Size(min=1, message="id cannot be empty") + private String id; + + public DeleteProductBean() { + super(); + } + + /** + * @param id + */ + public DeleteProductBean(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return "DeleteProductBean [id=" + id + "]"; + } +} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java index c01b693..dd83944 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java @@ -20,6 +20,7 @@ public class FisheryRecord extends Common{ @JsonProperty("fishery_name") @NotNull(message="fishery_name cannot be null") @Size(min=1, message="fishery_name cannot be empty") + @CustomField(key="Fishery Name") private String fisheryName; @JsonProperty("fishery_id") diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java index 2fdd983..0a48273 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java @@ -21,6 +21,7 @@ public class StockRecord extends Common{ @JsonProperty("stock_name") @NotNull(message="stock_name cannot be null") @Size(min=2, message="stock_name cannot be empty") + @CustomField(key="Stock Name") private String stockName; @JsonProperty("stock_id") diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java index 1188054..dd5c261 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java @@ -6,7 +6,9 @@ import java.util.List; import java.util.Map; import javax.servlet.ServletContext; +import javax.validation.Valid; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -20,6 +22,7 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.data_catalogue.grsf_publish_ws.json.input.DeleteProductBean; import org.gcube.data_catalogue.grsf_publish_ws.json.input.FisheryRecord; import org.gcube.data_catalogue.grsf_publish_ws.json.output.ResponseCreationBean; import org.gcube.data_catalogue.grsf_publish_ws.utils.AssociationToGroupThread; @@ -30,6 +33,8 @@ import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; import org.slf4j.LoggerFactory; +import eu.trentorise.opendata.jackan.model.CkanDataset; + /** * Fishery web service methods * @author Costantino Perciante at ISTI-CNR @@ -258,5 +263,72 @@ public class GrsfPublisherFisheryService { return Response.status(status).entity(responseBean).build(); } + + @DELETE + @Path("delete-product") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteFishery(@Valid DeleteProductBean recordToDelete){ + + // retrieve context and username + Caller caller = AuthorizationProvider.instance.get(); + String username = caller.getClient().getId(); + String context = ScopeProvider.instance.get(); + + ResponseCreationBean responseBean = new ResponseCreationBean(); + Status status = Status.INTERNAL_SERVER_ERROR; + + // check it is a stock ... + logger.info("Received call to delete product with id " + recordToDelete.getId() + ", checking if it is a fishery"); + try{ + + DataCatalogue catalogue = HelperMethods.getDataCatalogueRunningInstance(context); + if(catalogue == null){ + + status = Status.INTERNAL_SERVER_ERROR; + responseBean.setId(null); + throw new Exception("There was a problem while serving your request"); + + } + + // retrieve the catalogue instance + CkanDataset fisheryInCkan = catalogue.getDataset(recordToDelete.getId(), catalogue.getApiKeyFromUsername(username)); + + if(fisheryInCkan == null){ + + status = Status.NOT_FOUND; + responseBean.setId(null); + throw new Exception("There was a problem while serving your request. This product was not found"); + + } + + // get extras and check there is the field Assessment distribution area that is mandatory for stock + if(fisheryInCkan.getExtrasAsHashMap().containsKey("Fishery Name")){ + + logger.warn("Ok, this is a fishery, removing it"); + boolean deleted = catalogue.deleteProduct(fisheryInCkan.getId(), catalogue.getApiKeyFromUsername(username), true); + if(deleted){ + logger.info("Stock DELETED AND PURGED!"); + status = Status.OK; + responseBean.setId(fisheryInCkan.getId()); + } + else{ + status = Status.INTERNAL_SERVER_ERROR; + throw new Exception("Request failed, sorry"); + } + + }else{ + status = Status.BAD_REQUEST; + throw new Exception("The id you are using doesn't belong to a Fishery product!"); + } + + }catch(Exception e){ + logger.error("Failed to delete this "); + status = Status.INTERNAL_SERVER_ERROR; + responseBean.setError(e.getMessage()); + } + + return Response.status(status).entity(responseBean).build(); + } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java index 22603ac..bfae7e5 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java @@ -6,7 +6,9 @@ import java.util.List; import java.util.Map; import javax.servlet.ServletContext; +import javax.validation.Valid; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -20,6 +22,7 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.data_catalogue.grsf_publish_ws.json.input.DeleteProductBean; import org.gcube.data_catalogue.grsf_publish_ws.json.input.StockRecord; import org.gcube.data_catalogue.grsf_publish_ws.json.output.ResponseCreationBean; import org.gcube.data_catalogue.grsf_publish_ws.utils.AssociationToGroupThread; @@ -30,6 +33,8 @@ import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; import org.slf4j.LoggerFactory; +import eu.trentorise.opendata.jackan.model.CkanDataset; + /** * Stock web service methods * @author Costantino Perciante at ISTI-CNR @@ -203,7 +208,7 @@ public class GrsfPublisherStockService { if(HelperMethods.existsLicenseId(record.getLicense())) license = record.getLicense(); else throw new Exception("Please check the license id!"); - + long version = record.getVersion() == null ? 1 : record.getVersion(); // create the product @@ -250,4 +255,71 @@ public class GrsfPublisherStockService { } + @DELETE + @Path("delete-product") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteStock(@Valid DeleteProductBean recordToDelete){ + + // retrieve context and username + Caller caller = AuthorizationProvider.instance.get(); + String username = caller.getClient().getId(); + String context = ScopeProvider.instance.get(); + + ResponseCreationBean responseBean = new ResponseCreationBean(); + Status status = Status.INTERNAL_SERVER_ERROR; + + // check it is a stock ... + logger.info("Received call to delete product with id " + recordToDelete.getId() + ", checking if it is a stock"); + try{ + + DataCatalogue catalogue = HelperMethods.getDataCatalogueRunningInstance(context); + if(catalogue == null){ + + status = Status.INTERNAL_SERVER_ERROR; + responseBean.setId(null); + throw new Exception("There was a problem while serving your request"); + + } + + // retrieve the catalogue instance + CkanDataset stockInCkan = catalogue.getDataset(recordToDelete.getId(), catalogue.getApiKeyFromUsername(username)); + + if(stockInCkan == null){ + + status = Status.NOT_FOUND; + responseBean.setId(null); + throw new Exception("There was a problem while serving your request. This product was not found"); + + } + + // get extras and check there is the field Assessment distribution area that is mandatory for stock + if(stockInCkan.getExtrasAsHashMap().containsKey("Stock Name")){ + + logger.warn("Ok, this is a stock, removing it"); + boolean deleted = catalogue.deleteProduct(stockInCkan.getId(), catalogue.getApiKeyFromUsername(username), true); + if(deleted){ + logger.info("Stock DELETED AND PURGED!"); + status = Status.OK; + responseBean.setId(stockInCkan.getId()); + } + else{ + status = Status.INTERNAL_SERVER_ERROR; + throw new Exception("Request failed, sorry"); + } + + }else{ + status = Status.BAD_REQUEST; + throw new Exception("The id you are using doesn't belong to a Stock product!"); + } + + }catch(Exception e){ + logger.error("Failed to delete this ", e); + status = Status.INTERNAL_SERVER_ERROR; + responseBean.setError(e.getMessage()); + } + + return Response.status(status).entity(responseBean).build(); + } + } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/AssociationToGroupThread.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/AssociationToGroupThread.java index 24ab651..a02ae10 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/AssociationToGroupThread.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/AssociationToGroupThread.java @@ -47,6 +47,9 @@ public class AssociationToGroupThread extends Thread { // retrieve the role to be assigned according the one the user has into the organization of the dataset RolesCkanGroupOrOrg role = RolesCkanGroupOrOrg.valueOf(catalogue.getRoleOfUserInOrganization(username, organizationId, catalogue.getApiKeyFromUsername(username)).toUpperCase()); + if(!role.equals(RolesCkanGroupOrOrg.ADMIN)) + role = RolesCkanGroupOrOrg.MEMBER; // decrease the role to member if it is not an admin + for (String groupTitle : groupsTitles) { logger.debug("Setting role " + role + " into group " + groupTitle + " to user " + username);