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