uri-resolver/src/main/java/org/gcube/datatransfer/resolver/services/StorageManager.java

256 lines
9.1 KiB
Java
Raw Normal View History

package org.gcube.datatransfer.resolver.services;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
import org.gcube.contentmanagement.blobstorage.resource.MyFile;
import org.gcube.contentmanagement.blobstorage.service.IClient;
import org.gcube.contentmanager.storageclient.wrapper.AccessType;
import org.gcube.contentmanager.storageclient.wrapper.MemoryType;
import org.gcube.contentmanager.storageclient.wrapper.StorageClient;
import org.gcube.datatransfer.resolver.SingleFileStreamingOutput;
import org.gcube.datatransfer.resolver.services.exceptions.BadRequestException;
import org.gcube.datatransfer.resolver.services.exceptions.InternalServerException;
import org.gcube.datatransfer.resolver.services.exceptions.WrongParameterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class StorageManager.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
* @author Lucio Lelii
*
* Oct 19, 2018
*/
@Path("/")
public class StorageManager {
/**
*
*/
protected static final String STORAGEID_RESOLVER = "storageid-resolver";
private static final String STORAGE_ID = "storage-id";
private static Logger logger = LoggerFactory.getLogger(StorageManager.class);
/**
* Gets the storage id.
*
* @param httpRequest the http request
* @param storageId the storage id
* @param fileName the file name
* @param contentType the content type
* @param validation the validation
* @return the storage id
*/
@GET
@Path("{storage-id:(?!id)[^/?$]*}")
public Response getStorageId(@Context HttpServletRequest httpRequest, @PathParam(STORAGE_ID) String storageId, @QueryParam(ConstantsResolver.FILE_NAME) String fileName, @QueryParam(ConstantsResolver.CONTENT_TYPE) String contentType, @QueryParam(ConstantsResolver.VALIDATION) Boolean validation) {
logger.info("resolve Storage-Id called");
//Checking mandatory parameter storageId
if(storageId==null || storageId.isEmpty()){
logger.error(STORAGE_ID+" not found");
throw new BadRequestException(httpRequest, Status.NOT_ACCEPTABLE, "Missing mandatory path parameter "+STORAGE_ID, StorageManager.class);
}
return resolveStorageId(httpRequest, storageId, fileName, contentType, validation);
}
/**
* Resolve storage id.
*
* @param httpRequest the http request
* @param storageId the storage id
* @param fileName the file name
* @param contentType the content type
* @param validation the validation
* @return the response
*/
protected static Response resolveStorageId(HttpServletRequest httpRequest, String storageId, String fileName, String contentType, Boolean validation) {
logger.info("storage-id: "+storageId+", fileName: "+fileName+", contentType: "+contentType+", validation: "+validation);
//Checking mandatory parameter storageId
if (storageId == null || storageId.isEmpty()) {
logger.warn("storageId not found");
throw new BadRequestException(httpRequest, Status.NOT_ACCEPTABLE, "Missing mandatory path parameter "+STORAGE_ID, StorageManager.class);
}
/*
if(validation!=null && validation)
return validationPayload(storageId);
*/
StorageClient client = getStorageClientInstance(storageId);
String toSEID = null;
IClient iClient = null;
try{
iClient = client.getClient();
toSEID = iClient.getId(storageId); //to Storage Encrypted ID
logger.debug("Decoded ID"+" = "+ toSEID);
}catch(Exception e){
logger.error("Storage Client Exception when getting file from storage: ", e);
throw new InternalServerException(httpRequest, Status.INTERNAL_SERVER_ERROR, "Storage Client Exception when getting file from storage with id: "+storageId, StorageManager.class);
//throw new WebApplicationException("Storage Client Exception when getting file from storage with id: "+storageId, Status.INTERNAL_SERVER_ERROR);
}
if(toSEID==null){
logger.error("Decrypted id for storageId: "+storageId +" is null!");
throw new WrongParameterException(httpRequest, Status.BAD_REQUEST, "Error on decrypting the "+STORAGE_ID+ " '"+storageId+"'. Is it a valid id?", StorageManager.class);
}
long size = iClient.getSize().RFileById(toSEID);
try{
MyFile file = iClient.getMetaFile().RFile(toSEID);
logger.debug("MetaFile retrieved from storage? "+ (file!=null));
//Reading the fileName from Storage Metadata only if the passed fileName is null
if(fileName==null || fileName.isEmpty())
fileName= file.getName();
//Reading the contentType from Storage Metadata only if the passed contentType is null
if(contentType==null || contentType.isEmpty())
contentType = file.getMimeType();
}catch (Exception e) {
logger.warn("Error when getting file metadata from storage, printing this warning and trying to continue..", e);
}
fileName = fileName==null || fileName.isEmpty()?ConstantsResolver.DEFAULT_FILENAME_FROM_STORAGE_MANAGER:fileName;
logger.info("filename retrieved is {}",fileName);
contentType = contentType==null || contentType.isEmpty()?ConstantsResolver.DEFAULT_CONTENTTYPE_UNKNOWN_UNKNOWN:contentType;
logger.info("contentType used is {}",contentType);
//Building the response
InputStream streamToWrite=iClient.get().RFileAsInputStream(toSEID); //input stream
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
ResponseBuilder response = Response
.ok(so)
.header(ConstantsResolver.CONTENT_DISPOSITION,"attachment; filename = \""+fileName+"\"")
.header(ConstantsResolver.CONTENT_LENGTH, size);
if (contentType!= null) response.header("Content-Type",contentType);
return response.build();
}
/**
* Http do head.
*
* @param storageId the storage id
* @return the response
*/
/*@HEAD
@Path("{storage-id}")
public Response httpDoHead(@PathParam(STORAGE_ID) String storageId, @QueryParam(HPROXYCHECK) Boolean hproxycheck) throws ServletException, IOException {
logger.info("doHead working..");
//THIS IS FOR HPROXY CHECK
if(hproxycheck==null || hproxycheck){
logger.trace("returning status 200 for Hproxy check");
ResponseBuilder response = Response.status(HttpStatus.SC_OK);
return response.build();
}
return validationPayload(storageId);
}*/
/**
* Validation payload.
*
* @param storageId the storage id
* @return the response
*/
/*protected Response validationPayload(String storageId){
//Checking to STORAGE-ID Resolver
if (storageId == null || storageId.isEmpty()) {
logger.warn("storageId not found");
throw new WebApplicationException("Missing mandatory parameter "+STORAGE_ID, Status.BAD_REQUEST);
}
StorageClient client = getStorageClientInstance(storageId);
String toSEID = null;
IClient iClient = null;
try{
iClient = client.getClient();
toSEID = iClient.getId(storageId); //to Storage Encrypted ID
logger.debug("Decoded ID"+" = "+ toSEID);
}catch(Exception e){
logger.error("Storage Client Exception when getting file from storage: ", e);
throw new WebApplicationException("Storage Client Exception when getting file from storage with id: "+storageId, Status.INTERNAL_SERVER_ERROR);
}
if(toSEID==null){
String error = "Decrypted storageId is null, thrown exception!";
throw new WebApplicationException(error, Status.BAD_REQUEST);
}
//Building the response
InputStream streamToWrite=iClient.get().RFileAsInputStream(toSEID); //input stream
byte[] bytes = new byte[1]; //1B
int c;
try {
c = streamToWrite.read(bytes);
logger.info(c+" byte read from InputStream");
if(c>0){
logger.info("at least 1 byte read, returning status 200");
IOUtils.closeQuietly(streamToWrite);
ResponseBuilder response = Response.status(HttpStatus.SC_OK);
return response.build();
}else
throw new WebApplicationException("The file with id: "+storageId+" is missing in the storage", Status.NOT_FOUND);
}
catch (IOException e) {
logger.error("Error on validating the file: ",e);
throw new WebApplicationException("Error on validating the file with id: "+storageId, Status.INTERNAL_SERVER_ERROR);
}
}*/
/**
* Gets the storage client instance.
*
* @param storageId the storage id
* @return the storage client instance
*/
protected static StorageClient getStorageClientInstance(String storageId){
MemoryType memory=null;
if(storageId.endsWith(org.gcube.contentmanagement.blobstorage.transport.backend.util.Costants.VOLATILE_URL_IDENTIFICATOR)){
memory=MemoryType.VOLATILE;
storageId=storageId.replace(org.gcube.contentmanagement.blobstorage.transport.backend.util.Costants.VOLATILE_URL_IDENTIFICATOR, "");
}
StorageClient client;
if(memory==null)
client=new StorageClient(StorageManager.class.getName(), StorageManager.class.getSimpleName(), STORAGEID_RESOLVER, AccessType.PUBLIC);
else
client=new StorageClient(StorageManager.class.getName(), StorageManager.class.getSimpleName(), STORAGEID_RESOLVER, AccessType.PUBLIC, memory);
return client;
}
}