From f7c160f7553f2262205e25ce1131d5560f49edd7 Mon Sep 17 00:00:00 2001 From: Sara Bertocco <bertocco@oats.inaf.it> Date: Thu, 21 Jul 2016 14:37:44 +0200 Subject: [PATCH] New working version after Victoria trip --- .../VOSpaceBackendResource.java | 579 ++++-------------- 1 file changed, 112 insertions(+), 467 deletions(-) diff --git a/src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java b/src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java index a3c9b1f..dbd5b47 100644 --- a/src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java +++ b/src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java @@ -1,4 +1,5 @@ -/**_____________________________________________________________________________ +/** + * _____________________________________________________________________________ * * OATS - INAF * Osservatorio Astronomico di Tireste - Istituto Nazionale di Astrofisica @@ -6,7 +7,7 @@ * ____________________________________________________________________________ * * Copyright (C) 20016 Istituto Nazionale di Astrofisica - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -18,532 +19,176 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, Inc., + * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * _____________________________________________________________________________ - **/ + * + */ package it.inaf.oats.vospacebackend; -import it.inaf.oats.vospacebackend.implementation.VOSpaceBackend; -import it.inaf.oats.vospacebackend.implementation.VOSpaceBackImplFactory; -import it.inaf.oats.vospacebackend.exceptions.ExceptionMessage; -import it.inaf.oats.vospacebackend.exceptions.VOSpaceBackendException; -import it.inaf.oats.vospacebackend.utils.ConfigReader; - -import java.io.File; -import java.io.FileOutputStream; +import it.inaf.oats.vospacebackend.utils.ResourceManager; +import ca.nrc.cadc.uws.ExecutionPhase; +import ca.nrc.cadc.uws.Job; import java.io.InputStream; -import java.io.IOException; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.Map; -import java.util.List; -import java.util.Iterator; - -import javax.servlet.ServletContext; +import java.net.MalformedURLException; import org.apache.log4j.Logger; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.codec.binary.Hex; import org.restlet.resource.Get; -import org.restlet.resource.Post; import org.restlet.resource.Put; -import org.restlet.resource.Delete; import org.restlet.Request; import org.restlet.resource.ServerResource; import org.restlet.representation.Variant; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; -import org.restlet.representation.FileRepresentation; -import org.restlet.ext.fileupload.RestletFileUpload; - import org.restlet.data.MediaType; import org.restlet.data.Status; -import java.security.InvalidKeyException; -import java.io.IOException; -import java.io.ByteArrayInputStream; -import java.io.UnsupportedEncodingException; -import java.io.OutputStream; -import java.util.UUID; -import javax.xml.bind.DatatypeConverter; - -import ca.nrc.cadc.util.RsaSignatureGenerator; -import ca.nrc.cadc.util.RsaSignatureVerifier; -import java.security.MessageDigest; +import org.apache.http.HttpStatus; /** * * @author bertocco */ -public class VOSpaceBackendResource extends ServerResource { - +public class VOSpaceBackendResource extends ServerResource implements org.apache.http.HttpStatus { + protected Logger log = Logger.getLogger(VOSpaceBackendResource.class); - + @Put public Representation doPut(Representation entity, Variant variant) throws Exception { - + Representation result = null; - + int opResult = 0; + log.info("Entering in PUT operation"); - - String vosuri = null; + + String jobID = null; + String vosuri; String encodedParameters; InputStream is; if (entity != null) { log.info("Received good entity"); try { - log.debug("Trying to read attributes"); - Request request = getRequest(); - encodedParameters = (String)getRequest().getAttributes().get("parameters"); - log.debug("Received encoded parameters : " + encodedParameters); - vosuri = manageParametersDecoding(encodedParameters); - log.debug("Received parameters decoded = " + vosuri); - } catch (Exception e) { - log.debug("Exception reading string parameters"); - log.debug(e); - } - + + vosuri = readParameters(); + + jobID = (String) getRequest().getAttributes().get("jobid"); + log.debug("Received jobid = " + jobID); + + } catch (MalformedURLException e) { + + setStatus(Status.CLIENT_ERROR_BAD_REQUEST); + return this.printMessage("Malformed URL received. Unable to read parameters from URL"); + + } + try { - + is = entity.getStream(); log.debug("Input stream get"); - result = readAndSaveFile(vosuri, is); - + opResult = ResourceManager.readAndSaveFile(vosuri, is); + } catch (Exception e) { - result = this.printMessage("File NOT Uploaded! Something went wrong."); - } - + + log.debug("Exception in readAndSaveFile"); + return this.printMessage("File NOT Uploaded! Something went wrong."); + + } + } - - return result; - } - -/* - @Post - public Representation doPost(Representation entity) throws Exception { - - Representation result = null; - log.info("Entering in POST operation"); - - if (entity != null) { - - if (MediaType.MULTIPART_FORM_DATA.equals(entity.getMediaType(), true)) { - log.info("Correctly Using MULTIPART_FORM_DATA"); - - try { - result = this.uploadFile(entity); - } catch (Exception e) { - result = this.printMessage(e.getMessage()); + + if (opResult == HttpStatus.SC_OK) { + + log.debug("File upload successful!"); + log.debug("Going to set execution phase as completed ..."); + ResourceManager.setJobPhase(jobID, ExecutionPhase.EXECUTING, ExecutionPhase.COMPLETED); + log.debug("Checkp 1"); + ExecutionPhase expected = ExecutionPhase.COMPLETED; + ExecutionPhase current = ResourceManager.getJobPhase(jobID); + log.debug("Current phase = " + current.toString()); + if (current == null) { + log.debug("Unable to correctly get job phase"); + return this.printMessage("File SUCCESSFULLY Uploaded, but Unable to correctly set/get job phase"); + } else { + if (current.toString().equals(expected.toString())) { + log.debug("Job phase at the backend upload end: " + current.toString()); + setStatus(Status.SUCCESS_OK); + return this.printMessage("File SUCCESSFULLY Uploaded!"); + } else { + log.debug("Job phase at the backend upload end: " + current.toString()); + return this.printMessage("File SUCCESSFULLY Uploaded, but internal operation trace not completed"); } - - - } else { - // POST request with unexpected type. - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("POST request with unexpected type."); - } - - + } } else { - // POST request with no entity. - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("POST request with no entity."); + log.debug("Internal server error. Operation result code: " + String.valueOf(opResult)); + setStatus(Status.SERVER_ERROR_INTERNAL); + return this.printMessage("File NOT Uploaded! Something went wrong."); } - return result; - + } -*/ - + @Get - public Representation doGet(){ - + public Representation doGet() { + Representation result = null; - + String vosuri; + log.info("Entering in GET operation"); - String fileName = (String)getRequestAttributes().get("fileToManage"); - log.debug("File to download is: " + fileName); - try { - result = this.downloadFile(fileName); - } catch (Exception e) { - //setStatus(Status.CLIENT_ERROR_NOT_FOUND); - result = this.printMessage("GET request: failed to download file."); - } - - - return result; - } - - - @Delete - public Representation doDelete(){ - - Representation result; - - log.info("Entering in DELETE operation"); - - String fileName = (String)getRequestAttributes().get("fileToManage"); - log.debug("File to delete is: " + fileName); - try { - result = this.deleteFile(fileName); - } catch (Exception e) { - result = this.printMessage("DELETE request: failed to delete file " + fileName); - } - return result; - - } -/* - private Representation uploadFile(Representation entity) throws Exception { - - Representation result = null; - - - // 1/ Create a factory for disk-based file items - DiskFileItemFactory factory = new DiskFileItemFactory(); - factory.setSizeThreshold(1000240); - log.info("Factory created"); - // 2/ Create a new file upload handler based on the Restlet - // FileUpload extension that will parse Restlet requests and - // generates FileItems. - RestletFileUpload upload = new RestletFileUpload(factory); - log.info("RestletFileUpload created"); - - List<FileItem> items; - - boolean fileFound = false; - String origFileName = null; - FileItem fileItemToStore = null; - Map<String, String> parameters = new HashMap<String, String>(); - try { - // 3/ Request is parsed by the handler which generates a list of FileItems - items = upload.parseRequest(getRequest()); - - for (final Iterator<FileItem> it = items.iterator(); it.hasNext(); ) { - FileItem fi = it.next(); - String fileName = fi.getName(); - if (fileName == null) { - parameters.put(fi.getFieldName(), new String(fi.get(), "UTF-8")); - } else { - fileItemToStore = fi; - origFileName = fileName; - fileFound = true; - } - } - } catch (Exception e) { - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("Unable to correctly parse request"); - return result; - } - - if (!fileFound) { - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("Unable to find a file to download"); - return result; - } - - String unique_file_id_str; - String security_token; - - if (parameters.isEmpty()) { - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("Unable to find parameters in client request"); - return result; - } - - if (origFileName == null) { - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("Unable to find original file name in client request"); - return result; - } - - if (parameters.get("unique_file_id_string") == null) { - setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("No parameter unique_file_id_string found in request"); - return result; - } - unique_file_id_str = parameters.get("unique_file_id_string"); - - - if (parameters.get("security_token") == null) { + + vosuri = readParameters(); + + } catch (MalformedURLException e) { + setStatus(Status.CLIENT_ERROR_BAD_REQUEST); - result = this.printMessage("No parameter security_token found in request"); - return result; - } - security_token = parameters.get("security_token"); - - log.debug("unique_file_id_string = " + unique_file_id_str); - - log.debug("security_token = " + security_token); - - log.debug("fileName = " + origFileName); - - - result = readAndSaveFile(vosuri, fileItemToStore); - - return result; - - } - */ - - private Representation readAndSaveFile(String vosuri, FileItem fi) - throws IOException, VOSpaceBackendException { - - Representation result; - log.debug("Entering in readAndSaveFile"); - - InputStream is = fi.getInputStream(); - log.debug("Input stream get"); - - return readAndSaveFile(vosuri, is); - - } - - - private Representation readAndSaveFile(String vosuri, InputStream is) - throws IOException, VOSpaceBackendException { - - Representation result; - String md5sum = null; - - // Generate the unique file identifier (storageFileID) - String unique_file_id_str = UUID.randomUUID().toString(); - log.debug("Unique file identifyer " + unique_file_id_str); - - // Get temporary document root from configuration file - String tmpStorageRoot = new String(); - try { - ConfigReader myConf = new ConfigReader("VOSpace.properties"); - tmpStorageRoot = myConf.getProperty("fs.posix.tmp.storage.root"); - } catch (Exception e) { - ExceptionMessage exMsg = new ExceptionMessage(); - log.debug(MessageFormat.format( - exMsg.getMessage("UNABLE_TO_READ_PROPERTIES"), "VOSpace.properties")); - throw new VOSpaceBackendException(MessageFormat.format( - exMsg.getMessage("PROPERTY_NOT_FOUND"), "fs.posix.tmp.storage.root", "VOSpace.properties")); - } - // Create the temporary directory, if needed - File path = new File(tmpStorageRoot); - if (!path.exists()) { - boolean status = path.mkdirs(); - } - // Seve the temporary file in temporary location with the new unique name - File savedUploadedFile = new File(path + File.separator + unique_file_id_str); - FileOutputStream outStream = new FileOutputStream(savedUploadedFile); - try { - md5sum = readWriteAndGetChecksum(is, outStream); - } catch (Exception e) { - result = this.printMessage("File NOT Uploaded! Something went wrong." + e.getMessage()); + return this.printMessage("Malformed URL received. Unable to read parameters from URL"); + } - + try { - if (this.storeUploadedFile(vosuri, unique_file_id_str, md5sum)) { - setStatus(Status.SUCCESS_OK); - result = this.printMessage("File successfully uploaded"); - } else { - result = this.printMessage("File NOT Uploaded! Something went wrong."); - } + result = ResourceManager.downloadFile(vosuri); } catch (Exception e) { - result = this.printMessage("File NOT Uploaded! Something went wrong."); - } - - return result; - } - - - private boolean storeUploadedFile(String vosuri, String tmp_file_name, - String md5_sum) throws Exception { - boolean stored = false; - log.debug("Entering in storeUploadedFile"); - VOSpaceBackImplFactory myVOSpaceFactory = new VOSpaceBackImplFactory(); - log.debug("myVOSpaceFactory created"); - VOSpaceBackend myVOSpace = myVOSpaceFactory.getVOSpaceBackImpl(); - log.debug("myVOSpace get"); - stored = myVOSpace.createFile(vosuri, tmp_file_name, md5_sum); - log.debug("File stored: " + stored); - return stored; - - } - - private Representation downloadFile(String fileName) throws Exception { - - Representation result; - - log.debug("Entering in downloadFile"); - VOSpaceBackImplFactory myVOSpaceFactory = new VOSpaceBackImplFactory(); - log.debug("myVOSpaceFactory created"); - VOSpaceBackend myVOSpace = myVOSpaceFactory.getVOSpaceBackImpl(); - log.debug("myVOSpace get"); - File fileToDownload = myVOSpace.returnFile(fileName); - if (fileToDownload != null ) { - log.debug("File found, fileToDownload is not null"); - FileRepresentation fr = new FileRepresentation(fileToDownload.getAbsolutePath(), - MediaType.APPLICATION_OCTET_STREAM); - result = fr; - setStatus(Status.SUCCESS_OK); - - } else { - log.debug("File NOT found, fileToDownload is null"); - result = this.printMessage("Unable to download file. Something went wrong!"); setStatus(Status.SERVER_ERROR_INTERNAL); + result = this.printMessage("GET request: failed to download file."); } - - return result; - } - - private Representation deleteFile(String fileName) throws Exception { - - Representation result = null; - - log.debug("Entering in deleteFile"); - VOSpaceBackImplFactory myVOSpaceFactory = new VOSpaceBackImplFactory(); - log.debug("myVOSpaceFactory created"); - VOSpaceBackend myVOSpace = myVOSpaceFactory.getVOSpaceBackImpl(); - log.debug("myVOSpace delete"); - try { - if(myVOSpace.deleteFile(fileName)) { - log.debug("DELETE request: file " + fileName + " removed."); - result = this.printMessage("DELETE request: file " + fileName + " removed."); - setStatus(Status.SUCCESS_OK); - } else { - log.debug("DELETE request: failed to remove file " + fileName); - result = this.printMessage("DELETE request: failed to remove file " + fileName); - setStatus(Status.SERVER_ERROR_INTERNAL); - } - } catch (Exception e) { - log.debug("DELETE request: failed to remove file " + fileName); - result = this.printMessage("DELETE request: failed to remove file " + fileName); - setStatus(Status.SERVER_ERROR_INTERNAL); - } - - return result; + + if (result != null) { + setStatus(Status.SUCCESS_OK); + return result; + } else { + setStatus(Status.CLIENT_ERROR_NOT_FOUND); + return this.printMessage("GET request: failed to download file."); + } + } - - - - private String manageParametersDecoding(String toBeVerified) { - + private String readParameters() throws MalformedURLException { + String vosuri; - int count = 0; - - log.debug("manageParametersEncoding BEGIN"); - String urlStr = new String(DatatypeConverter.parseBase64Binary(toBeVerified)); - log.debug("urlStr = " + urlStr); - vosuri = urlStr.substring(0, urlStr.indexOf("|")); - log.debug("vosuri = " + vosuri); - String remaining = urlStr.substring(urlStr.indexOf("|")+1, urlStr.length()); - log.debug("Remaining after get vosuri = " + remaining); - String signature = remaining.substring(remaining.indexOf("|")+1, remaining.length()); - log.debug("signature = \n" + signature); - - // Validation - log.debug("I am going to create RsaSignatureVerifier"); - RsaSignatureVerifier su = new RsaSignatureVerifier(); - log.debug("Created"); - - boolean valid = false; try { - valid = su.verify(new ByteArrayInputStream(vosuri.getBytes()), - DatatypeConverter.parseBase64Binary(signature)); - } catch (IOException ioe) { - log.debug("IOException"); - log.debug(ioe.getMessage()); - } catch (InvalidKeyException ike) { - log.debug("InvalidKeyException"); - log.debug(ike.getMessage()); + log.debug("Trying to read attributes"); + Request request = getRequest(); + String encodedParameters = (String) getRequest().getAttributes().get("parameters"); + log.debug("Received encoded parameters : " + encodedParameters); + vosuri = ResourceManager.manageParametersDecoding(encodedParameters); + log.debug("Received parameters decoded = " + vosuri); + } catch (Exception e) { + log.debug("Exception reading string parameters"); + log.debug(e); + throw new MalformedURLException("Exception reading string parameters from URL"); } - + return vosuri; - + } - - public String readWriteAndGetChecksum(InputStream istream, FileOutputStream ostream) throws Exception { - - log.debug("Entering in readWriteAndGetChecksum(InputStream, FileOutputStream)"); - - int DEFAULT_BUFFER_SIZE = 1024 * 4; - String checksum = null; - byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - int bytesRead; - - MessageDigest msgDigest = MessageDigest.getInstance("MD5"); - - // do an initial read to ensure there are bytes in the stream - try { - bytesRead = istream.read(buffer, 0, DEFAULT_BUFFER_SIZE); - if (bytesRead <= 0) { - // do not allow the creation of zero-length files - log.debug("Cannot write a zero-length file."); - throw new Exception("Cannot write a zero-length file."); - } else - log.debug("First bytes read OK"); - } catch (IOException ex) { - String errorMsg = "Upstream exception while reading from " - + istream.getClass().getName() + ": " - + ex.getMessage(); - log.debug("IOException in the first byte reading of the incoming file"); - log.debug(errorMsg); - //throw new TransferAbortedException(errorMsg); - throw new Exception(errorMsg); - } - // Loop reading and writing data. - msgDigest.update(buffer, 0, bytesRead); - log.debug("First msgDigest.update OK"); - try { + public static Representation printMessage(String error) { - while (bytesRead >= 0) { - ostream.write(buffer, 0, bytesRead); - try { - bytesRead = istream.read(buffer, 0, DEFAULT_BUFFER_SIZE); - if(bytesRead > 0) { - msgDigest.update(buffer, 0, bytesRead); - } - } catch (IOException ex) { - String errorMsg = "Upstream exception while reading from " - + istream.getClass().getName() + ": " - + ex.getMessage(); - //throw new TransferAbortedException(errorMsg); - log.debug(errorMsg); - log.debug("A Exception in reading/writing file" + ex.getMessage()); - throw new Exception(errorMsg); - } - } - ostream.flush(); - ostream.close(); - - } catch (IOException ex) { - log.debug("B Exception in reading/writing file" + ex.getMessage()); - } - - //Get the hash's bytes - byte[] bytes = null; - try { - bytes = msgDigest.digest(); - } catch (Exception ex) { - log.debug("Exception doing msgDigest.digest()"); - } - String md5_checksum = new String(Hex.encodeHex(bytes)); - log.debug("************************ MD5 checksum calculated: " + md5_checksum); - - return md5_checksum; - - } - - - private Representation printMessage(String error) { - - StringBuilder sb = new StringBuilder(""); - sb.append(error); - sb.append("\n"); - return new StringRepresentation(sb.toString(), MediaType.TEXT_PLAIN); + StringBuilder sb = new StringBuilder(""); + sb.append(error); + sb.append("\n"); + return new StringRepresentation(sb.toString(), MediaType.TEXT_PLAIN); } + } -- GitLab