2018-12-05 16:58:44 +01:00
/ * *
*
* /
package org.gcube.datatransfer.resolver.services ;
import java.io.ByteArrayOutputStream ;
import java.io.File ;
2018-12-12 15:38:44 +01:00
import java.io.FileInputStream ;
2018-12-05 16:58:44 +01:00
import java.io.IOException ;
2018-12-12 15:38:44 +01:00
import java.net.URL ;
2018-12-05 16:58:44 +01:00
import java.nio.file.Files ;
import javax.servlet.http.HttpServletRequest ;
import javax.ws.rs.Consumes ;
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.xml.bind.JAXBException ;
2018-12-12 15:38:44 +01:00
import org.apache.commons.io.IOUtils ;
2018-12-07 10:41:18 +01:00
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
2018-12-05 16:58:44 +01:00
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.common.scope.impl.ScopeBean ;
import org.gcube.common.scope.impl.ScopeBean.Type ;
2018-12-12 15:38:44 +01:00
import org.gcube.common.storagehub.client.dsl.FileContainer ;
import org.gcube.common.storagehub.client.dsl.StorageHubClient ;
2018-12-05 16:58:44 +01:00
import org.gcube.data.analysis.dminvocation.ActionType ;
import org.gcube.data.analysis.dminvocation.DataMinerInvocationManager ;
import org.gcube.data.analysis.dminvocation.model.DataMinerInvocation ;
2018-12-07 10:41:18 +01:00
import org.gcube.datatransfer.resolver.requesthandler.TokenSetter ;
2018-12-05 16:58:44 +01:00
import org.gcube.datatransfer.resolver.services.error.ExceptionManager ;
import org.gcube.datatransfer.resolver.util.Util ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2018-12-12 15:38:44 +01:00
import org.xml.sax.SAXException ;
2018-12-05 16:58:44 +01:00
/ * *
2018-12-12 15:38:44 +01:00
* The Class AnalyticsCreateResolver .
2018-12-05 16:58:44 +01:00
*
2018-12-12 15:38:44 +01:00
* @author Francesco Mangiacrapa at ISTI - CNR ( francesco . mangiacrapa @isti.cnr.it )
* Dec 12 , 2018
2018-12-05 16:58:44 +01:00
* /
@Path ( " /analytics " )
public class AnalyticsCreateResolver {
2018-12-07 10:41:18 +01:00
private static final String DATAMINER_INVOCATION_MODEL = " dim " ;
2018-12-05 16:58:44 +01:00
private static Logger logger = LoggerFactory . getLogger ( AnalyticsCreateResolver . class ) ;
2018-12-13 12:39:55 +01:00
private static String helpURI = " https://gcube.wiki.gcube-system.org/gcube/URI_Resolver#Analytics_Resolver " ;
2018-12-05 16:58:44 +01:00
2018-12-13 11:09:08 +01:00
2018-12-05 16:58:44 +01:00
/ * *
2018-12-13 11:09:08 +01:00
* Creates the analytics url .
2018-12-05 16:58:44 +01:00
*
* @param req the req
2018-12-12 15:38:44 +01:00
* @param body the body
2018-12-05 16:58:44 +01:00
* @return the response
* /
@POST
@Path ( " /create " )
2018-12-12 15:38:44 +01:00
@Consumes ( MediaType . TEXT_PLAIN )
2018-12-05 16:58:44 +01:00
@Produces ( MediaType . TEXT_PLAIN )
2018-12-13 11:09:08 +01:00
public Response createAnalyticsURL ( @Context HttpServletRequest req , String body ) {
2018-12-05 16:58:44 +01:00
logger . info ( this . getClass ( ) . getSimpleName ( ) + " POST starts... " ) ;
2018-12-12 15:38:44 +01:00
logger . info ( " body is: " + body ) ;
2018-12-05 16:58:44 +01:00
2018-12-12 15:38:44 +01:00
DataMinerInvocation jsonRequest = null ;
2018-12-07 10:41:18 +01:00
try {
2018-12-12 15:38:44 +01:00
jsonRequest = DataMinerInvocationManager . getInstance ( ) . unmarshaling ( IOUtils . toInputStream ( body ) , org . gcube . data . analysis . dminvocation . MediaType . ApplicationJSON , true ) ;
}
catch ( IOException | JAXBException | SAXException e1 ) {
logger . error ( " The body is not a valid DataMinerInvocation JSON request " , e1 ) ;
ExceptionManager . throwBadRequestException ( req , " Bad 'dataminer-invocation' JSON request: \ n " + e1 . getCause ( ) . getMessage ( ) , this . getClass ( ) , helpURI ) ;
2018-12-07 10:41:18 +01:00
}
2018-12-12 15:38:44 +01:00
logger . debug ( " The body contains the request: " + jsonRequest . toString ( ) ) ;
2018-12-07 10:41:18 +01:00
String contextToken = SecurityTokenProvider . instance . get ( ) ;
2018-12-05 16:58:44 +01:00
String scope = ScopeProvider . instance . get ( ) ;
2018-12-12 15:38:44 +01:00
// logger.info("SecurityTokenProvider contextToken: "+contextToken);
logger . info ( " ScopeProvider has scope: " + scope ) ;
2018-12-07 10:41:18 +01:00
String appToken = req . getServletContext ( ) . getInitParameter ( TokenSetter . ROOT_APP_TOKEN ) ;
if ( contextToken . compareTo ( appToken ) = = 0 ) {
logger . error ( " Token not passed, SecurityTokenProvider contains the root app token: " + appToken . substring ( 0 , 10 ) + " ... " ) ;
ExceptionManager . throwUnauthorizedException ( req , " You are not authorized. You must pass a token of VRE " , this . getClass ( ) , helpURI ) ;
}
2018-12-05 16:58:44 +01:00
String operatorID = jsonRequest . getOperatorId ( ) ;
if ( scope = = null | | scope . isEmpty ( ) ) {
logger . error ( " The parameter 'scope' not found or empty in the JSON object " ) ;
ExceptionManager . throwBadRequestException ( req , " Mandatory body parameter 'scope' not found or empty in the JSON object " , this . getClass ( ) , helpURI ) ;
}
if ( operatorID = = null | | operatorID . isEmpty ( ) ) {
logger . error ( " The parameter 'operatorId' not found or empty in the JSON object " ) ;
ExceptionManager . throwBadRequestException ( req , " Mandatory body parameter 'operatorId' not found or empty in the JSON object " , this . getClass ( ) , helpURI ) ;
}
ScopeBean scopeBean = new ScopeBean ( scope ) ;
String publicLinkToDMInvFile = " " ;
if ( scopeBean . is ( Type . VRE ) ) {
String vreName = scopeBean . name ( ) ;
2018-12-13 11:09:08 +01:00
String analyticsGetResolverURL = String . format ( " %s/%s " , Util . getServerURL ( req ) , " analytics/get " ) ;
//Creating DM invocation file
if ( jsonRequest . getActionType ( ) = = null )
jsonRequest . setActionType ( ActionType . RUN ) ;
File tempInvocationFile = null ;
try {
ByteArrayOutputStream xmlByteArray = DataMinerInvocationManager . getInstance ( ) . marshaling ( jsonRequest , org . gcube . data . analysis . dminvocation . MediaType . ApplicationXML , true ) ;
String uniqueName = createDMInvocationFileName ( jsonRequest . getOperatorId ( ) ) ;
tempInvocationFile = createTempFile ( uniqueName , " .xml " , xmlByteArray . toByteArray ( ) ) ;
//CREATE THE FILE ON STORAGE HUB
StorageHubClient shc = new StorageHubClient ( ) ;
logger . info ( " Created StorageHubClient Instance, uploading file: " + tempInvocationFile . getName ( ) ) ;
FileContainer fileContainer = shc . getWSRoot ( ) . uploadFile ( new FileInputStream ( tempInvocationFile ) , tempInvocationFile . getName ( ) , " DataMinerInvocation Request created by " + this . getClass ( ) . getSimpleName ( ) ) ;
logger . info ( " UPLOADED FILE at: " + fileContainer . getPublicLink ( ) ) ;
URL thePublicLink = fileContainer . getPublicLink ( ) ;
publicLinkToDMInvFile = thePublicLink ! = null ? thePublicLink . toString ( ) : null ;
}
catch ( Exception e ) {
logger . error ( " Error on creating 'dataminer-invocation: " , e ) ;
ExceptionManager . throwBadRequestException ( req , " Error on creating your 'dataminer-invocation' request with " + jsonRequest + " . \ nPlease contact the support " , this . getClass ( ) , helpURI ) ;
} finally {
try {
//DELETING THE TEMP FILE
if ( tempInvocationFile ! = null & & tempInvocationFile . exists ( ) )
tempInvocationFile . delete ( ) ;
} catch ( Exception e ) {
//silent
2018-12-12 15:38:44 +01:00
}
2018-12-13 11:09:08 +01:00
}
2018-12-05 16:58:44 +01:00
2018-12-13 11:09:08 +01:00
if ( publicLinkToDMInvFile = = null ) {
logger . error ( " Error on creating the public link to file " ) ;
ExceptionManager . throwBadRequestException ( req , " Error on getting link to your 'dataminer-invocation' request. Plese contact the support " + jsonRequest , this . getClass ( ) , helpURI ) ;
}
2018-12-05 16:58:44 +01:00
2018-12-13 11:09:08 +01:00
String dataMinerURL = String . format ( " %s/%s?%s=%s " , analyticsGetResolverURL , vreName , DATAMINER_INVOCATION_MODEL , publicLinkToDMInvFile ) ;
logger . info ( " Returning Analytics URL: " + dataMinerURL ) ;
return Response . ok ( dataMinerURL ) . header ( " Location " , dataMinerURL ) . build ( ) ;
2018-12-05 16:58:44 +01:00
} else {
logger . error ( " The input scope " + scope + " is not a VRE " ) ;
ExceptionManager . throwBadRequestException ( req , " Working in the " + scope + " scope that is not a VRE. Use a token of VRE " , this . getClass ( ) , helpURI ) ;
}
return null ;
}
2018-12-07 11:28:37 +01:00
2018-12-05 16:58:44 +01:00
/ * *
* Creates the temp file .
*
* @param fileName the file name
* @param extension the extension
* @param data the data
* @return the file
* @throws IOException Signals that an I / O exception has occurred .
* /
private static File createTempFile ( String fileName , String extension , byte [ ] data ) throws IOException {
// Since Java 1.7 Files and Path API simplify operations on files
java . nio . file . Path path = Files . createTempFile ( fileName , extension ) ;
File file = path . toFile ( ) ;
// writing sample data
Files . write ( path , data ) ;
2018-12-12 15:38:44 +01:00
logger . info ( " Created the Temp File: " + file . getAbsolutePath ( ) ) ;
2018-12-05 16:58:44 +01:00
return file ;
}
2018-12-07 11:28:37 +01:00
/ * *
* Creates the dm invocation file name .
*
* @param operatorId the operator id
* @return the string
* /
private static String createDMInvocationFileName ( String operatorId ) {
String fileName = " dim " ;
int index = operatorId . lastIndexOf ( " . " ) ;
if ( index > 0 & & index < operatorId . length ( ) ) {
fileName + = " - " + operatorId . substring ( index + 1 , operatorId . length ( ) ) ;
}
2018-12-12 15:38:44 +01:00
//String currentTimestamp = dateFormat.format(new Date());
fileName + = " - " + System . currentTimeMillis ( ) ;
2018-12-07 11:28:37 +01:00
return fileName ;
}
2018-12-05 16:58:44 +01:00
}