2018-10-12 16:20:46 +02:00
package org.gcube.datatransfer.resolver.services ;
import java.net.URL ;
2018-11-09 12:05:53 +01:00
import java.util.concurrent.ExecutionException ;
2018-10-12 16:20:46 +02:00
import javax.servlet.http.HttpServletRequest ;
import javax.ws.rs.Consumes ;
import javax.ws.rs.GET ;
import javax.ws.rs.POST ;
import javax.ws.rs.Path ;
import javax.ws.rs.PathParam ;
import javax.ws.rs.Produces ;
2018-12-14 12:28:59 +01:00
import javax.ws.rs.WebApplicationException ;
2018-10-12 16:20:46 +02:00
import javax.ws.rs.core.Context ;
import javax.ws.rs.core.MediaType ;
import javax.ws.rs.core.Response ;
import org.gcube.common.scope.api.ScopeProvider ;
2019-05-16 12:54:20 +02:00
import org.gcube.common.scope.impl.ScopeBean ;
import org.gcube.common.scope.impl.ScopeBean.Type ;
import org.gcube.datatransfer.resolver.caches.LoadingMapOfScopeCache ;
2018-10-12 16:20:46 +02:00
import org.gcube.datatransfer.resolver.catalogue.CatalogueRequest ;
2018-11-26 12:56:51 +01:00
import org.gcube.datatransfer.resolver.catalogue.ItemCatalogueURLs ;
2018-11-15 12:18:03 +01:00
import org.gcube.datatransfer.resolver.catalogue.ResourceCatalogueCodes ;
2018-10-12 16:20:46 +02:00
import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader ;
import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference ;
2019-05-16 12:54:20 +02:00
import org.gcube.datatransfer.resolver.catalogue.resource.GetAllInfrastructureScopes ;
2018-11-09 12:05:53 +01:00
import org.gcube.datatransfer.resolver.services.error.ExceptionManager ;
2018-11-30 12:51:17 +01:00
import org.gcube.datatransfer.resolver.util.Util ;
2018-10-24 10:09:09 +02:00
import org.gcube.smartgears.utils.InnerMethodName ;
2018-10-12 16:20:46 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2018-12-17 15:52:31 +01:00
import com.google.common.cache.CacheLoader.InvalidCacheLoadException ;
2018-10-12 16:20:46 +02:00
import eu.trentorise.opendata.jackan.model.CkanDataset ;
2018-11-23 15:45:33 +01:00
/ * *
* The Class CatalogueResolver .
*
* @author Francesco Mangiacrapa at ISTI - CNR ( francesco . mangiacrapa @isti.cnr.it )
* Nov 16 , 2018
* /
2019-02-19 15:18:19 +01:00
@Path ( " {entityContext:ctlg(-(o|g|p|d))?} " )
2018-10-23 14:58:46 +02:00
public class CatalogueResolver {
2018-10-12 16:20:46 +02:00
2018-10-23 14:58:46 +02:00
private static Logger logger = LoggerFactory . getLogger ( CatalogueResolver . class ) ;
2018-11-09 12:05:53 +01:00
private static String helpURI = " https://wiki.gcube-system.org/gcube/URI_Resolver#CATALOGUE_Resolver " ;
2018-10-12 16:20:46 +02:00
2018-11-23 15:45:33 +01:00
/ * *
* Resolve catalogue .
*
* @param req the req
* @param entityName the entity name
* @param vreName the vre name
* @param entityContext the entity context
* @return the response
* /
2018-10-12 16:20:46 +02:00
@GET
2019-02-19 15:18:19 +01:00
@Path ( " /{vreName}/{entityName} " )
2018-12-14 12:28:59 +01:00
public Response resolveCatalogue ( @Context HttpServletRequest req ,
@PathParam ( " entityName " ) String entityName ,
@PathParam ( " vreName " ) String vreName ,
@PathParam ( " entityContext " ) String entityContext ) throws WebApplicationException {
logger . info ( this . getClass ( ) . getSimpleName ( ) + " GET starts... " ) ;
2018-10-12 16:20:46 +02:00
try {
2018-12-14 12:28:59 +01:00
InnerMethodName . instance . set ( " resolveCataloguePublicLink " ) ;
2018-12-17 11:48:18 +01:00
ItemCatalogueURLs itemCatalogueURLs = getItemCatalogueURLs ( req , vreName , entityContext , entityName ) ;
2018-11-26 12:56:51 +01:00
String itemCatalogueURL ;
if ( itemCatalogueURLs . isPublicItem ( ) ) {
itemCatalogueURL = itemCatalogueURLs . getPublicCataloguePortletURL ( ) ;
logger . info ( " The dataset " + itemCatalogueURLs . getItemName ( ) + " is a public item so using public access to CKAN portlet: " + itemCatalogueURL ) ;
} else {
itemCatalogueURL = itemCatalogueURLs . getPrivateCataloguePortletURL ( ) ;
logger . info ( " The dataset " + itemCatalogueURLs . getItemName ( ) + " is a private item so using protected access to CKAN portlet: " + itemCatalogueURL ) ;
}
2018-11-23 15:45:33 +01:00
return Response . seeOther ( new URL ( itemCatalogueURL ) . toURI ( ) ) . build ( ) ;
2018-10-12 16:20:46 +02:00
} catch ( Exception e ) {
2018-12-14 12:28:59 +01:00
if ( ! ( e instanceof WebApplicationException ) ) {
//UNEXPECTED EXCEPTION managing it as WebApplicationException
2018-12-14 14:26:37 +01:00
String error = " Error occurred on resolving the Catalgoue URL. Please, contact the support! " ;
if ( e . getCause ( ) ! = null )
error + = " \ n \ nCaused: " + e . getCause ( ) . getMessage ( ) ;
2018-12-14 12:28:59 +01:00
throw ExceptionManager . internalErrorException ( req , error , this . getClass ( ) , helpURI ) ;
}
//ALREADY MANAGED AS WebApplicationException
logger . error ( " Exception: " , e ) ;
throw ( WebApplicationException ) e ;
2018-10-12 16:20:46 +02:00
}
}
2018-11-23 15:45:33 +01:00
/ * *
* Post catalogue .
*
* @param req the req
* @param jsonRequest the json request
* @return the response
* /
2018-10-12 16:20:46 +02:00
@POST
2019-02-19 15:18:19 +01:00
@Path ( " " )
2018-10-12 16:20:46 +02:00
@Consumes ( MediaType . APPLICATION_JSON )
@Produces ( MediaType . TEXT_PLAIN )
2018-12-14 12:28:59 +01:00
public Response postCatalogue ( @Context HttpServletRequest req , CatalogueRequest jsonRequest ) throws WebApplicationException {
logger . info ( this . getClass ( ) . getSimpleName ( ) + " POST starts... " ) ;
2018-10-12 16:20:46 +02:00
2018-12-14 12:28:59 +01:00
try {
2018-10-12 16:20:46 +02:00
2018-12-14 12:28:59 +01:00
InnerMethodName . instance . set ( " postCataloguePublicLink " ) ;
logger . info ( " The body contains the request: " + jsonRequest . toString ( ) ) ;
2018-11-09 12:05:53 +01:00
2018-12-14 12:28:59 +01:00
//CHECK IF INPUT SCOPE IS VALID
String scope = jsonRequest . getGcube_scope ( ) ;
if ( ! scope . startsWith ( " / " ) ) {
logger . info ( " Scope not start with char '/' adding it " ) ;
scope + = " / " + scope ;
}
2018-10-12 16:20:46 +02:00
2018-12-14 12:28:59 +01:00
String serverUrl = Util . getServerURL ( req ) ;
2018-10-12 16:20:46 +02:00
2018-12-14 12:28:59 +01:00
final String vreName = scope . substring ( scope . lastIndexOf ( " / " ) + 1 , scope . length ( ) ) ;
2019-05-16 12:54:20 +02:00
ScopeBean fullScope = null ;
2018-12-17 11:48:18 +01:00
2018-12-14 12:28:59 +01:00
//CHECK IF THE vreName has a valid scope, so it is a valid VRE
try {
2019-05-16 12:54:20 +02:00
fullScope = LoadingMapOfScopeCache . get ( vreName ) ;
2018-12-17 11:48:18 +01:00
} catch ( ExecutionException e ) {
logger . error ( " Error on getting the fullscope from cache for vreName " + vreName , e ) ;
throw ExceptionManager . wrongParameterException ( req , " Error on getting full scope for the VRE name " + vreName + " . Is it registered as VRE in the D4Science Infrastructure System? " , this . getClass ( ) , helpURI ) ;
2018-12-14 12:28:59 +01:00
}
if ( fullScope = = null )
throw ExceptionManager . notFoundException ( req , " The scope ' " + scope + " ' does not matching any scope in the infrastructure. Is it valid? " , this . getClass ( ) , helpURI ) ;
ResourceCatalogueCodes rc = ResourceCatalogueCodes . valueOfCodeValue ( jsonRequest . getEntity_context ( ) ) ;
if ( rc = = null ) {
logger . error ( " Entity context is null/malformed " ) ;
throw ExceptionManager . badRequestException ( req , " Entity context is null/malformed " , this . getClass ( ) , helpURI ) ;
}
String linkURL = String . format ( " %s/%s/%s/%s " , serverUrl , rc . getId ( ) , vreName , jsonRequest . getEntity_name ( ) ) ;
logger . info ( " Returining Catalogue URL: " + linkURL ) ;
return Response . ok ( linkURL ) . header ( " Location " , linkURL ) . build ( ) ;
} catch ( Exception e ) {
if ( ! ( e instanceof WebApplicationException ) ) {
//UNEXPECTED EXCEPTION managing it as WebApplicationException
String error = " Error occurred on resolving the Analytics URL. Please, contact the support! " ;
throw ExceptionManager . internalErrorException ( req , error , this . getClass ( ) , helpURI ) ;
}
//ALREADY MANAGED AS WebApplicationException
logger . error ( " Exception: " , e ) ;
throw ( WebApplicationException ) e ;
}
2018-11-23 15:45:33 +01:00
}
2018-10-12 16:20:46 +02:00
2018-11-23 15:45:33 +01:00
/ * *
2019-05-16 12:54:20 +02:00
* Gets the item catalogue UR ls .
2018-11-23 15:45:33 +01:00
*
2018-12-17 11:48:18 +01:00
* @param req the req
2019-05-16 12:54:20 +02:00
* @param scopeName the scope name
2018-11-23 15:45:33 +01:00
* @param entityContext the entity context
* @param entityName the entity name
2019-05-16 12:54:20 +02:00
* @return the item catalogue UR ls
2018-11-23 15:45:33 +01:00
* @throws Exception the exception
* /
2019-05-16 12:54:20 +02:00
protected static ItemCatalogueURLs getItemCatalogueURLs ( HttpServletRequest req , String scopeName , String entityContext , String entityName ) throws Exception {
2018-11-23 15:45:33 +01:00
try {
String entityContextValue = ResourceCatalogueCodes . valueOfCodeId ( entityContext ) . getValue ( ) ;
2019-05-16 12:54:20 +02:00
ScopeBean scopeBean = null ;
2018-12-17 11:48:18 +01:00
try {
2019-05-16 12:54:20 +02:00
scopeBean = LoadingMapOfScopeCache . get ( scopeName ) ;
2018-12-17 15:52:31 +01:00
} catch ( ExecutionException | InvalidCacheLoadException e ) {
2019-05-16 12:54:20 +02:00
logger . error ( " Error on getting the fullscope from cache for scopeName " + scopeName , e ) ;
throw ExceptionManager . wrongParameterException ( req , " Error on getting full scope for the scope name ' " + scopeName + " '. Is it registered as a valid Scope in the D4Science Infrastructure System? " , CatalogueResolver . class , helpURI ) ;
}
String fullScope = scopeBean . toString ( ) ;
logger . info ( " Read fullScope: " + fullScope + " for SCOPE name: " + scopeName + " from cache created by: " + GetAllInfrastructureScopes . class . getSimpleName ( ) ) ;
if ( scopeBean . is ( Type . VO ) ) {
logger . info ( " It is a {} scope " , Type . VO ) ;
logger . warn ( " The Catalogue can't work at {} level, I'm overriding the scope to {} level " , Type . VO , Type . INFRASTRUCTURE ) ;
2019-05-16 14:44:02 +02:00
fullScope = fullScope . substring ( 1 , fullScope . indexOf ( " / " ) ) ; //skypping the first slash
2019-05-16 14:45:09 +02:00
logger . info ( " Overriden the input scope {} with {} as type: {} " , fullScope , Type . INFRASTRUCTURE , fullScope ) ;
2018-12-17 11:48:18 +01:00
}
2018-11-23 15:45:33 +01:00
ScopeProvider . instance . set ( fullScope ) ;
GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader . loadCatalogueEndPoints ( ) ;
logger . info ( " For scope " + fullScope + " loaded end points: " + ckanCatalogueReference ) ;
//IS THE PRODUCT PLUBLIC OR PRIVATE?
String datasetName = entityName ;
2018-11-26 12:56:51 +01:00
boolean isPublicItem = false ;
2018-11-23 15:45:33 +01:00
if ( ckanCatalogueReference . getCkanURL ( ) ! = null ) {
try {
CkanDataset dataset = CkanCatalogueConfigurationsReader . getDataset ( datasetName , ckanCatalogueReference . getCkanURL ( ) ) ;
if ( dataset ! = null ) {
2018-11-26 12:56:51 +01:00
isPublicItem = true ;
//ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL();
logger . info ( " The dataset " + datasetName + " is a public item " ) ;
2018-11-23 15:45:33 +01:00
}
} catch ( Exception e ) {
logger . warn ( " Error on checking if dataset: " + datasetName + " is private or not " , e ) ;
2018-11-26 12:56:51 +01:00
isPublicItem = true ;
2018-10-12 16:20:46 +02:00
}
2018-11-23 15:45:33 +01:00
}
2018-10-12 16:20:46 +02:00
2018-11-26 12:56:51 +01:00
String publicPorltetURL = String . format ( " %s?path=/%s/%s " , ckanCatalogueReference . getPublicPortletURL ( ) , entityContextValue , entityName ) ;
String privatePortletURL = String . format ( " %s?path=/%s/%s " , ckanCatalogueReference . getPrivatePortletURL ( ) , entityContextValue , entityName ) ;
return new ItemCatalogueURLs ( entityName , isPublicItem , privatePortletURL , publicPorltetURL ) ;
2018-11-23 15:45:33 +01:00
} catch ( Exception e ) {
2018-12-14 12:28:59 +01:00
logger . error ( " Error when resolving CatalogueURL: " , e ) ;
2018-11-23 15:45:33 +01:00
throw e ;
}
2018-10-12 16:20:46 +02:00
}
}