@ -1,23 +1,34 @@
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.Resource ;
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 ;
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 ;
/ * *
@ -27,8 +38,19 @@ import org.slf4j.LoggerFactory;
@Path ( "stock/" )
public class GrsfPublisherStockService {
// the context
@Context
ServletContext contextServlet ;
// Logger
private static final org . slf4j . Logger logger = LoggerFactory . getLogger ( GrsfPublisherStockService . class ) ;
@GET
@Path ( "hello" )
@Produces ( MediaType . TEXT_PLAIN )
public Response hello ( ) {
return Response . ok ( "Hello.. Stock service is here" ) . build ( ) ;
}
@POST
@Path ( "publish-product" )
@ -41,40 +63,160 @@ public class GrsfPublisherStockService {
String username = caller . getClient ( ) . getId ( ) ;
String context = ScopeProvider . instance . get ( ) ;
logger . info ( "Incoming request for creating a stock record by user with id " + username ) ;
logger . info ( "Incoming request for creating a stock record = " + record ) ;
logger . info ( "Request coming from user " + username + " in context " + context ) ;
ResponseCreationBean responseBean = new ResponseCreationBean ( ) ;
Status status = Status . CREATED ;
Status status = Status . INTERNAL_SERVER_ERROR ;
String id = "" ;
try {
DataCatalogue catalogue = HelperMethods . getDataCatalogueRunningInstance ( context ) ;
// check the user has editor/admin role into the org TODO pending or accepted?
// check the record has a name, at least
// evaluate the tags of the product
// evaluate the resources
// evaluate tags and groups using reflection
List < String > tags = new ArrayList < String > ( ) ;
List < String > groups = new ArrayList < String > ( ) ;
// create the product
//catalogue.createCKanDataset(apiKey, title, organizationNameOrId, author, authorMail, maintainer, maintainerMail, version, description, licenseId, tags, customFields, resources, setPublic)
// 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 . getStockName ( ) ;
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 < 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 {
// evaluate the resources TODO
List < Resource > resourcesRecord = record . getResources ( ) ;
List < ResourceBean > resources = null ;
if ( resourcesRecord ! = null & & ! resourcesRecord . isEmpty ( ) ) {
resources = new ArrayList < ResourceBean > ( ) ;
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 stock record" , e ) ;
status = Status . INTERNAL_SERVER_ERROR ;
responseBean . setError ( e . toString ( ) ) ;
responseBean . setId ( id ) ;
responseBean . setError ( e . getMessage ( ) ) ;
}
return Response . status ( status ) . entity ( responseBean ) . build ( ) ;
}
}