package org.gcube.data_catalogue.grsf_publish_ws.services; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; 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.FisheryRecord; import org.gcube.data_catalogue.grsf_publish_ws.json.input.Resource; import org.gcube.data_catalogue.grsf_publish_ws.json.output.ResponseCreationBean; import org.gcube.data_catalogue.grsf_publish_ws.utils.AssociationToGroupThread; import org.gcube.data_catalogue.grsf_publish_ws.utils.HelperMethods; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; import org.slf4j.LoggerFactory; /** * Fishery web service methods * @author Costantino Perciante at ISTI-CNR */ @Path("fishery/") public class GrsfPublisherFisheryService { // the context @Context ServletContext contextServlet; // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GrsfPublisherFisheryService.class); @GET @Path("hello") @Produces(MediaType.TEXT_PLAIN) public Response hello(){ return Response.ok("Hello.. Fishery service is here").build(); } @POST @Path("publish-product") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response publishFishery(FisheryRecord record){ // retrieve context and username Caller caller = AuthorizationProvider.instance.get(); String username = caller.getClient().getId(); String context = ScopeProvider.instance.get(); logger.info("Incoming request for creating a fishery record = " + record); logger.info("Request coming from user " + username + " in context " + context); ResponseCreationBean responseBean = new ResponseCreationBean(); Status status = Status.INTERNAL_SERVER_ERROR; String id = ""; try{ // determine the organization in which this product should be put String contextInWhichPublish = HelperMethods.getContextFromStatus(record.getStatus(), contextServlet); if(contextInWhichPublish == null || !contextInWhichPublish.equals(context)){ // stop, this value must be defined status = Status.BAD_REQUEST; responseBean.setId(id); throw new IllegalArgumentException("Status attribute is not defined or the Token you are using is not correct to perform such request!"); }else{ 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"); }else{ // check the user has editor/admin role into the org String organization = HelperMethods.retrieveOrgNameFromScope(contextInWhichPublish); if(catalogue.getRoleOfUserInOrganization(username, organization, catalogue.getApiKeyFromUsername(username)).equals(RolesCkanGroupOrOrg.MEMBER)){ status = Status.FORBIDDEN; responseBean.setId(null); throw new Exception("You are not authorized to create a product. Please check you have at least the editor role!"); } // check the record has a name, at least String futureTitle = record.getFisheryName(); if(!HelperMethods.isValid(futureTitle)){ status = Status.BAD_REQUEST; responseBean.setId(null); throw new Exception("The name requested for the product is not correct! It should contain only alphanumeric characters, and symbols like '.' or '_', '-'"); }else{ logger.debug("Checking if such name [" + futureTitle + "]doesn't exist yet..."); String futureName = UtilMethods.fromProductTitleToName(futureTitle); logger.info("Transformed name is " + futureName); boolean alreadyExist = catalogue.existProductWithNameOrId(futureName); if(alreadyExist){ logger.debug("A product with name " + futureName + " already exists"); responseBean.setId(null); status = Status.BAD_REQUEST; throw new Exception("Sorry but a product with such name already exists!"); }else{ // evaluate the tags of the product List tags = new ArrayList(); HelperMethods.getTags(tags, record); // evaluate the groups List groups = new ArrayList(); HelperMethods.getGroups(groups, record); // evaluate the custom fields Map customFields = new HashMap(); if(record.getExtras() != null) customFields = record.getExtras(); // automatically retrieve the other ones HelperMethods.getExtras(customFields, record); // retrieve the user's email and fullname String authorMail = HelperMethods.getUserEmail(context, SecurityTokenProvider.instance.get()); String authorFullname = HelperMethods.getUserFullname(context, SecurityTokenProvider.instance.get()); if(authorMail == null || authorFullname == null){ logger.debug("Author fullname or mail missing, cannot continue"); responseBean.setId(null); status = Status.INTERNAL_SERVER_ERROR; throw new Exception("Sorry but there was not possible to retrieve your fullname/email!"); }else{ // evaluate the resources TODO List resourcesRecord = record.getResources(); List resources = null; if(resourcesRecord != null && !resourcesRecord.isEmpty()){ resources = new ArrayList(); for (Resource res : resourcesRecord) { logger.debug("Trying to add resource " + res); if(res.getName() != null && res.getUrl() != null) resources.add(new ResourceBean(res.getUrl(), res.getName(), res.getDescription(), null, username, null, null)); else logger.warn("Unable to add resource because url or name is null"); } } // if confirmed, set to visible TODO anyway if it is confirmed we should another method boolean setPublic = record.getStatus() == org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status.Confirmed; // create the product id = catalogue.createCKanDataset( catalogue.getApiKeyFromUsername(username), futureTitle, organization, authorFullname, authorMail, record.getMaintainer(), record.getMaintainerContact(), record.getVersion(), record.getDescription(), record.getLicense(), tags, customFields, resources, setPublic); // TODO if(id != null){ logger.info("Product created! Id is " + id); responseBean.setId(id); status = Status.CREATED; responseBean.setError(null); if(!groups.isEmpty()){ logger.info("Launching thread for association to the list of groups " + groups); new AssociationToGroupThread(groups, id, organization, username, catalogue).start(); } } } } } } } }catch(Exception e){ logger.error("Failed to create fishery record", e); responseBean.setError(e.getMessage()); } return Response.status(status).entity(responseBean).build(); } }