Loading src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java +112 −467 Original line number Diff line number Diff line /**_____________________________________________________________________________ /** * _____________________________________________________________________________ * * OATS - INAF * Osservatorio Astronomico di Tireste - Istituto Nazionale di Astrofisica Loading @@ -21,69 +22,36 @@ * 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); Loading @@ -91,459 +59,136 @@ public class VOSpaceBackendResource extends ServerResource { 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 { // POST request with unexpected type. setStatus(Status.CLIENT_ERROR_BAD_REQUEST); result = this.printMessage("POST request with unexpected type."); 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 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() { 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."); } vosuri = readParameters(); 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; } } catch (MalformedURLException e) { 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; } return this.printMessage("Malformed URL received. Unable to read parameters from URL"); 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) { 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()); } 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."); if (result != null) { setStatus(Status.SUCCESS_OK); return result; } 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); setStatus(Status.CLIENT_ERROR_NOT_FOUND); return this.printMessage("GET request: failed to download file."); } return result; } 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 { 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) { public static Representation printMessage(String error) { StringBuilder sb = new StringBuilder(""); sb.append(error); sb.append("\n"); return new StringRepresentation(sb.toString(), MediaType.TEXT_PLAIN); } } Loading
src/main/java/it/inaf/oats/vospacebackend/VOSpaceBackendResource.java +112 −467 Original line number Diff line number Diff line /**_____________________________________________________________________________ /** * _____________________________________________________________________________ * * OATS - INAF * Osservatorio Astronomico di Tireste - Istituto Nazionale di Astrofisica Loading @@ -21,69 +22,36 @@ * 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); Loading @@ -91,459 +59,136 @@ public class VOSpaceBackendResource extends ServerResource { 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 { // POST request with unexpected type. setStatus(Status.CLIENT_ERROR_BAD_REQUEST); result = this.printMessage("POST request with unexpected type."); 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 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() { 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."); } vosuri = readParameters(); 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; } } catch (MalformedURLException e) { 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; } return this.printMessage("Malformed URL received. Unable to read parameters from URL"); 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) { 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()); } 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."); if (result != null) { setStatus(Status.SUCCESS_OK); return result; } 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); setStatus(Status.CLIENT_ERROR_NOT_FOUND); return this.printMessage("GET request: failed to download file."); } return result; } 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 { 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) { public static Representation printMessage(String error) { StringBuilder sb = new StringBuilder(""); sb.append(error); sb.append("\n"); return new StringRepresentation(sb.toString(), MediaType.TEXT_PLAIN); } }