2016-10-08 20:46:17 +02:00
package org.gcube.data_catalogue.grsf_publish_ws.services ;
2016-10-10 18:50:11 +02:00
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
2016-10-09 16:06:45 +02:00
2016-10-10 18:50:11 +02:00
import javax.servlet.ServletContext ;
2016-10-14 18:44:34 +02:00
import javax.validation.Valid ;
2016-10-08 20:46:17 +02:00
import javax.ws.rs.Consumes ;
2016-10-14 18:44:34 +02:00
import javax.ws.rs.DELETE ;
2016-10-10 18:50:11 +02:00
import javax.ws.rs.GET ;
2016-10-08 20:46:17 +02:00
import javax.ws.rs.POST ;
import javax.ws.rs.Path ;
import javax.ws.rs.Produces ;
2016-10-10 18:50:11 +02:00
import javax.ws.rs.core.Context ;
2016-10-08 20:46:17 +02:00
import javax.ws.rs.core.MediaType ;
import javax.ws.rs.core.Response ;
2016-10-09 16:06:45 +02:00
import javax.ws.rs.core.Response.Status ;
2016-10-08 20:46:17 +02:00
2016-10-10 18:50:11 +02:00
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 ;
2016-10-14 18:44:34 +02:00
import org.gcube.data_catalogue.grsf_publish_ws.json.input.DeleteProductBean ;
2016-10-08 20:46:17 +02:00
import org.gcube.data_catalogue.grsf_publish_ws.json.input.FisheryRecord ;
2016-10-09 16:06:45 +02:00
import org.gcube.data_catalogue.grsf_publish_ws.json.output.ResponseCreationBean ;
2016-10-10 18:50:11 +02:00
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 ;
2016-10-08 20:46:17 +02:00
import org.slf4j.LoggerFactory ;
2016-10-14 18:44:34 +02:00
import eu.trentorise.opendata.jackan.model.CkanDataset ;
2016-10-08 20:46:17 +02:00
/ * *
* Fishery web service methods
* @author Costantino Perciante at ISTI - CNR
* /
@Path ( " fishery/ " )
public class GrsfPublisherFisheryService {
2016-10-11 11:39:25 +02:00
private static final String DEFAULT_FISHERY_LICENSE = " CC-BY-SA-4.0 " ;
2016-10-10 18:50:11 +02:00
// the context
@Context
ServletContext contextServlet ;
2016-10-09 16:06:45 +02:00
2016-10-08 20:46:17 +02:00
// Logger
private static final org . slf4j . Logger logger = LoggerFactory . getLogger ( GrsfPublisherFisheryService . class ) ;
2016-10-11 11:39:25 +02:00
2016-10-10 18:50:11 +02:00
@GET
@Path ( " hello " )
@Produces ( MediaType . TEXT_PLAIN )
public Response hello ( ) {
return Response . ok ( " Hello.. Fishery service is here " ) . build ( ) ;
}
2016-10-11 11:39:25 +02:00
@GET
@Path ( " get-licenses " )
@Produces ( MediaType . APPLICATION_JSON )
public Response getLicenses ( ) {
// since are equals for stock and fishery, we just retrieve them all
Map < String , String > licenses = new HashMap < String , String > ( ) ;
Status status ;
try {
licenses = HelperMethods . getLicenses ( ) ;
status = Status . OK ;
} catch ( Exception e ) {
logger . error ( " Failed to retrieve the list of licenses " ) ;
status = Status . INTERNAL_SERVER_ERROR ;
}
return Response . status ( status ) . entity ( licenses ) . build ( ) ;
}
2016-10-09 16:06:45 +02:00
2016-10-08 20:46:17 +02:00
@POST
@Path ( " publish-product " )
@Consumes ( MediaType . APPLICATION_JSON )
@Produces ( MediaType . APPLICATION_JSON )
public Response publishFishery ( FisheryRecord record ) {
2016-10-09 16:06:45 +02:00
2016-10-10 18:50:11 +02:00
// 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 = " " ;
2016-10-13 11:46:42 +02:00
// validate the bean
logger . debug ( " Start validating bean... " ) ;
Response responseAfterValidation = HelperMethods . validateBeanAndResources ( record ) ;
if ( responseAfterValidation = = null )
logger . debug ( " Bean validation successful " ) ;
else {
logger . warn ( " Bean validation failed " ) ;
return responseAfterValidation ;
}
2016-10-10 18:50:11 +02:00
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 ( ) ;
2016-10-13 11:46:42 +02:00
String fishingArea = record . getFishingArea ( ) ;
String jurisdictionArea = record . getJurisdictionArea ( ) ;
2016-10-10 18:50:11 +02:00
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 '_', '-' " ) ;
2016-10-13 11:46:42 +02:00
} else if ( ( fishingArea = = null | | fishingArea . isEmpty ( ) ) & & ( jurisdictionArea = = null | | jurisdictionArea . isEmpty ( ) ) ) {
status = Status . BAD_REQUEST ;
responseBean . setId ( null ) ;
throw new Exception ( " fishing_area and jurisdiction_area cannot be null/empty at the same time! " ) ;
2016-10-10 18:50:11 +02:00
} 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 ) ;
2016-10-14 15:20:10 +02:00
status = Status . CONFLICT ;
2016-10-10 18:50:11 +02:00
throw new Exception ( " Sorry but a product with such name already exists! " ) ;
} else {
// evaluate the tags of the product
List < String > tags = new ArrayList < String > ( ) ;
HelperMethods . getTags ( tags , record ) ;
// evaluate the groups
List < String > groups = new ArrayList < String > ( ) ;
HelperMethods . getGroups ( groups , record ) ;
// evaluate the custom fields
Map < String , String > customFields = new HashMap < String , String > ( ) ;
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 {
2016-10-13 11:46:42 +02:00
// evaluate the resources
List < ResourceBean > resources = HelperMethods . getResourcesFromBean ( record , username ) ;
2016-10-10 18:50:11 +02:00
// if confirmed, set to visible TODO anyway if it is confirmed we should another method
2016-10-13 18:51:34 +02:00
boolean setPublic = true ;
2016-10-10 18:50:11 +02:00
2016-10-11 11:39:25 +02:00
// check the license id
String license = null ;
if ( record . getLicense ( ) = = null | | record . getLicense ( ) . isEmpty ( ) )
license = DEFAULT_FISHERY_LICENSE ;
else
if ( HelperMethods . existsLicenseId ( record . getLicense ( ) ) )
license = record . getLicense ( ) ;
else throw new Exception ( " Please check the license id! " ) ;
2016-10-13 15:34:47 +02:00
long version = record . getVersion ( ) = = null ? 1 : record . getVersion ( ) ;
2016-10-11 11:39:25 +02:00
2016-10-10 18:50:11 +02:00
// create the product
id = catalogue . createCKanDataset (
catalogue . getApiKeyFromUsername ( username ) ,
futureTitle ,
organization ,
authorFullname ,
authorMail ,
record . getMaintainer ( ) ,
record . getMaintainerContact ( ) ,
2016-10-13 15:34:47 +02:00
version ,
2016-10-10 18:50:11 +02:00
record . getDescription ( ) ,
2016-10-11 11:39:25 +02:00
license ,
2016-10-10 18:50:11 +02:00
tags ,
customFields ,
resources ,
2016-10-13 11:46:42 +02:00
setPublic ) ;
2016-10-10 18:50:11 +02:00
if ( id ! = null ) {
logger . info ( " Product created! Id is " + id ) ;
responseBean . setId ( id ) ;
status = Status . CREATED ;
responseBean . setError ( null ) ;
2016-10-13 18:51:34 +02:00
responseBean . setDatasetUrl ( catalogue . getPortletUrl ( ) + " ?path=/dataset/ " + futureName ) ;
2016-10-10 18:50:11 +02:00
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 ( ) ) ;
}
2016-10-09 16:06:45 +02:00
2016-10-10 18:50:11 +02:00
return Response . status ( status ) . entity ( responseBean ) . build ( ) ;
2016-10-09 16:06:45 +02:00
2016-10-08 20:46:17 +02:00
}
2016-10-14 18:44:34 +02:00
@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 ( ) ;
}
2016-10-08 20:46:17 +02:00
}