]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-6110: Converting FileInputStream instances to ByteArrayInputStream instances...
authorRichard Millet <remillet@berkeley.edu>
Sat, 7 Dec 2013 06:11:01 +0000 (22:11 -0800)
committerRichard Millet <remillet@berkeley.edu>
Sat, 7 Dec 2013 06:11:01 +0000 (22:11 -0800)
services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java
services/blob/client/src/main/java/org/collectionspace/services/client/BlobProxy.java
services/blob/client/src/test/java/org/collectionspace/services/client/test/BlobScaleTest.java
services/client/src/main/resources/collectionspace-client.properties
services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java

index 5788d17cf5d1c47de69e915322d164b0c30d45ea..392fdd371df47f262000d3d76ecb65f940e5b633 100644 (file)
@@ -16,6 +16,7 @@
  */
 package org.collectionspace.services.client;
 
+import javax.ws.rs.PathParam;
 import javax.ws.rs.core.Response;
 
 import org.jboss.resteasy.client.ClientResponse;
@@ -71,4 +72,14 @@ public class BlobClient extends AbstractCommonListPoxServiceClientImpl<BlobProxy
     public ClientResponse<Response> createBlobFromURI(String blobUri) {
         return getProxy().createBlobFromURI("".getBytes(), blobUri);
     }
+    
+    public ClientResponse<Response> getBlobContent(String csid) {
+       return getProxy().getBlobContent(csid);
+    }
+    
+    public ClientResponse<Response> getDerivativeContent(
+               @PathParam("csid") String csid,
+               @PathParam("derivativeTerm") String derivativeTerm) {
+       return getProxy().getDerivativeContent(csid, derivativeTerm);
+    }
 }
index 7c3e38c55e8d31b25054a548e242815141ec0fb1..b1c85d54f2f268e86b17561caeb0fd4233c4085d 100644 (file)
@@ -1,8 +1,10 @@
 package org.collectionspace.services.client;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
@@ -27,5 +29,14 @@ public interface BlobProxy extends CollectionSpaceCommonListPoxProxy {
     @POST
     @Consumes("multipart/form-data")
     ClientResponse<Response> createBlobFromFormData(MultipartFormDataOutput formDataOutput);
-        
-}
+
+    @GET
+    @Path("{csid}/content")
+    ClientResponse<Response> getBlobContent(@PathParam("csid") String csid);
+    
+    @GET
+    @Path("{csid}/derivatives/{derivativeTerm}/content")
+    public ClientResponse<Response> getDerivativeContent(
+               @PathParam("csid") String csid,
+               @PathParam("derivativeTerm") String derivativeTerm);    
+}
\ No newline at end of file
index 0007f563118c6a7ca982ffede475cd197a7da049..53bd27c0f7feddb6a603fd5d2bda8614d7dafb76 100644 (file)
@@ -32,6 +32,7 @@ public class BlobScaleTest extends BaseServiceTest<AbstractCommonList> {
        private static final int MAX_FONTSIZE = 60;\r
        private static final String IMAGES_TO_CREATE_PROP = "imagesToCreate";\r
        private static final int DEFAULT_IMAGES_TO_CREATE = 1;\r
+       private static final int DEFAULT_IMAGES_TO_GET = 1024;\r
     private static final String GENERATED_IMAGES = "target/generated_images";\r
 \r
        private static Random generator = new Random(System.currentTimeMillis());\r
@@ -70,6 +71,21 @@ public class BlobScaleTest extends BaseServiceTest<AbstractCommonList> {
         return result;\r
        }\r
        \r
+       @Test(dataProvider = "testName", dependsOnMethods = {"scaleTest"})\r
+       public void scaleGETTest(String testName) throws MalformedURLException {\r
+               this.setupRead();\r
+               String blobToGetID = getKnowResourceId();\r
+        BlobClient client = new BlobClient();\r
+        \r
+        for (int i = 0; i < DEFAULT_IMAGES_TO_GET; i++) {\r
+               ClientResponse<Response> res = client.getDerivativeContent(blobToGetID, "Thumbnail");\r
+               assertStatusCode(res, testName);\r
+        }\r
+        \r
+        logger.debug(String.format("Performed %d GET operations on blob = %s.", \r
+                       DEFAULT_IMAGES_TO_GET, blobToGetID));\r
+       }\r
+       \r
        @Test(dataProvider = "testName")\r
        public void scaleTest(String testName) throws MalformedURLException {\r
                this.createDirectory(GENERATED_IMAGES);\r
@@ -83,7 +99,7 @@ public class BlobScaleTest extends BaseServiceTest<AbstractCommonList> {
                        URL url = jpegFile.toURI().toURL();\r
                        \r
                profiler.start();\r
-                       ClientResponse<Response> res = client.createBlobFromURI(url.toString());\r
+                       ClientResponse<Response> res = client.createBlobFromURI("http://farm6.static.flickr.com/5289/5688023100_15e00cde47_o.jpg");//url.toString());\r
                        try {\r
                                profiler.stop();\r
                        assertStatusCode(res, testName);\r
@@ -96,7 +112,8 @@ public class BlobScaleTest extends BaseServiceTest<AbstractCommonList> {
                                                + jpegFile.getAbsolutePath());\r
                                \r
                        String csid = extractId(res);\r
-                       allResourceIdsCreated.add(csid);\r
+                       //allResourceIdsCreated.add(csid);\r
+                       this.knownResourceId = csid;\r
                        } finally {\r
                                if (res != null) {\r
                     res.releaseConnection();\r
index 332c6865458c7cb46b01c4320bb39a38749c9eeb..b1984bcfbb60019362144e6711946dafc62ec0dd 100644 (file)
@@ -1,6 +1,6 @@
 #url of the collectionspace server\r
-cspace.url=http://localhost:8180/cspace-services/\r
-#cspace.url=http://nightly.collectionspace.org:8180/cspace-services/\r
+#cspace.url=http://localhost:8180/cspace-services/\r
+cspace.url=http://qa.collectionspace.org:8180/cspace-services/\r
 \r
 #cspace.url=http://localhost:8200/cspace-services/\r
 #for sockspy: \r
index db7c407e8b6a427619487445ed89e5fa589b9473..d592abab168f6b9fabc3c30487bee7b9beb48fb7 100644 (file)
@@ -26,6 +26,7 @@
  */\r
 package org.collectionspace.services.common.imaging.nuxeo;\r
 \r
+import java.io.ByteArrayInputStream;\r
 import java.io.File;\r
 import java.io.ByteArrayOutputStream;\r
 import java.io.FileNotFoundException;\r
@@ -49,7 +50,6 @@ import org.nuxeo.ecm.platform.picture.api.ImageInfo;
 import org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants;\r
 import org.nuxeo.ecm.platform.picture.api.ImagingService;\r
 import org.nuxeo.ecm.platform.picture.api.PictureView;\r
-\r
 import org.nuxeo.ecm.platform.mimetype.MimetypeDetectionException;\r
 import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry;\r
 import org.nuxeo.ecm.platform.picture.api.adapters.PictureBlobHolder;\r
@@ -58,10 +58,8 @@ import org.nuxeo.ecm.platform.filemanager.service.FileManagerService;
 import org.nuxeo.ecm.platform.filemanager.service.extension.FileImporter;\r
 import org.nuxeo.ecm.platform.filemanager.utils.FileManagerUtils;\r
 import org.nuxeo.ecm.platform.types.TypeManager;\r
-\r
 import org.nuxeo.ecm.core.repository.RepositoryDescriptor;\r
 import org.nuxeo.ecm.core.repository.RepositoryManager;\r
-\r
 import org.nuxeo.ecm.core.repository.RepositoryService;\r
 import org.nuxeo.ecm.core.storage.sql.BinaryManager;\r
 import org.nuxeo.ecm.core.storage.sql.DefaultBinaryManager;\r
@@ -96,14 +94,13 @@ import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;\r
 import org.nuxeo.ecm.core.api.DocumentRef;\r
 import org.nuxeo.ecm.core.event.EventServiceAdmin;\r
-\r
 import org.nuxeo.ecm.core.schema.SchemaManager;\r
 import org.nuxeo.ecm.core.schema.types.Schema;\r
-\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 //import org.nuxeo.ecm.core.repository.jcr.testing.RepositoryOSGITestCase;\r
 \r
+import org.apache.commons.io.IOUtils;\r
 import org.collectionspace.services.client.PoxPayloadIn;\r
 import org.collectionspace.services.client.PoxPayloadOut;\r
 import org.collectionspace.services.common.FileUtils;\r
@@ -136,6 +133,12 @@ public class NuxeoBlobUtils {
        private static final Logger logger = LoggerFactory\r
                        .getLogger(NuxeoBlobUtils.class);\r
 \r
+       //\r
+       // A maximum byte size for the byte array used to hold an image.  Images larger than this will\r
+       // be returned as FileInputStreams rather than ByteArrayInputStreams\r
+       //\r
+       private static final int MAX_IMAGE_BUFFER = 256 * 1024; // REM: 11/26/2013 - This should be set in a config/property file.\r
+       \r
        //\r
        // File name constants\r
        //\r
@@ -441,6 +444,11 @@ public class NuxeoBlobUtils {
 \r
        static private BlobsCommon createBlobsCommon(DocumentModel documentModel,\r
                        Blob nuxeoBlob) {\r
+               return createBlobsCommon(documentModel, nuxeoBlob, false);\r
+       }\r
+       \r
+       static private BlobsCommon createBlobsCommon(DocumentModel documentModel,\r
+                       Blob nuxeoBlob, Boolean getContentFlag) {\r
                BlobsCommon result = new BlobsCommon();\r
 \r
                if (documentModel != null) {\r
@@ -448,14 +456,21 @@ public class NuxeoBlobUtils {
                        result.setName(nuxeoBlob.getFilename());\r
                        result.setLength(Long.toString(nuxeoBlob.getLength()));\r
                        result.setRepositoryId(documentModel.getId());\r
-                       MeasuredPartGroupList measuredPartGroupList = getDimensions(\r
-                                       documentModel, nuxeoBlob);\r
-                       if (measuredPartGroupList != null) {\r
-                               result.setMeasuredPartGroupList(measuredPartGroupList);\r
+                       \r
+                       //\r
+                       // If getContentFlag is true then we're being asked for the blob's content, so we don't\r
+                       // need the measurement info.  Getting the measurement info requires a call to Nuxeo which in turn\r
+                       // calls ImageMagick.\r
+                       //\r
+                       if (getContentFlag.booleanValue() == false) {\r
+                               MeasuredPartGroupList measuredPartGroupList = getDimensions(\r
+                                               documentModel, nuxeoBlob);\r
+                               if (measuredPartGroupList != null) {\r
+                                       result.setMeasuredPartGroupList(measuredPartGroupList);\r
+                               }\r
                        }\r
                        \r
                        // Check to see if a thumbnail preview was created by Nuxeo\r
-                       // REM: 11/26/2013 - This looks like dead code?  What are we looking for a thumbnail?\r
             if (documentModel.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) {\r
                        String errorMsg = null;\r
                String thumbnailName = null;\r
@@ -1185,6 +1200,38 @@ public class NuxeoBlobUtils {
                return result;\r
        }\r
        \r
+       //\r
+       //  If the blob is not too big, we return a ByteArrayInputStream.  Otherwise, we return Nuxeo's InputStream\r
+       //  which is usually a FileInputStream.\r
+       //\r
+       static private InputStream getInputStream(BlobsCommon blobsCommon, Blob blob) {\r
+               InputStream result = null;\r
+               \r
+               try {\r
+                       InputStream blobStream = blob.getStream(); // By default, the result will be whatever stream Nuxeo returns to us.\r
+                       int blobSize = blobsCommon.getLength() != null ? Integer.parseInt(blobsCommon.getLength()) : 0;\r
+                       if (blobSize > 0 && blobSize < MAX_IMAGE_BUFFER) {\r
+                               byte[] bytes = IOUtils.toByteArray(blobStream);\r
+                               blobStream.close(); // Close the InputStream that we got from Nuxeo since it's usually a FileInputStream -we definitely want FileInputStreams closed.\r
+                               result = new ByteArrayInputStream(bytes);\r
+                       } else {\r
+                               result = blobStream; // The blob is too large to put into a ByteArrayStream.\r
+                       }\r
+               } catch (Exception e) {\r
+                       logger.error(String.format("Error getting the InputStream content for file %s.", blobsCommon.getName()), e);\r
+                       if (result != null) {\r
+                               try {\r
+                                       result.close();\r
+                                       result = null;\r
+                               } catch (Exception x) {\r
+                                       logger.debug(String.format("Exception encountered during InputStream cleanup of file %s", blobsCommon.getName()), x);\r
+                               }\r
+                       }                       \r
+               }\r
+               \r
+               return result;\r
+       }\r
+       \r
        /**\r
         * Gets the image.\r
         * \r
@@ -1240,19 +1287,21 @@ public class NuxeoBlobUtils {
                                // and an InputStream with the bits if the 'getContentFlag' is\r
                                // set.\r
                                //\r
-                               BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob);\r
+                               BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob, getContentFlag);\r
                                result.setBlobsCommon(blobsCommon);\r
                                if (getContentFlag == true) {\r
                                        InputStream remoteStream = null;\r
                                        if (isNonImageDerivative == false) {\r
-                                               remoteStream = docBlob.getStream(); // This will fail if the blob's file has been deleted. FileNotFoundException thrown.\r
+                                               //remoteStream = docBlob.getStream();\r
+                                               remoteStream = getInputStream(blobsCommon, docBlob); // CSPACE-6110 - For small files, return a byte array instead of a file stream\r
                                        } else {\r
                                                remoteStream = getResource(DOCUMENT_PLACEHOLDER_IMAGE);\r
                                                outMimeType.append(MIME_JPEG);\r
                                        }\r
-                                       BufferedInputStream bufferedInputStream = new BufferedInputStream(\r
-                                                       remoteStream);  \r
-                                       result.setBlobInputStream(bufferedInputStream);\r
+//                                     BufferedInputStream bufferedInputStream = new BufferedInputStream(\r
+//                                                     remoteStream);  \r
+//                                     result.setBlobInputStream(bufferedInputStream);\r
+                                       result.setBlobInputStream(remoteStream);\r
                                }\r
                        } catch (Exception e) {\r
                                if (logger.isErrorEnabled() == true) {\r
index c2672e8b75cd3f74b1cf37025f30fd82262a92ec..121abc2d549226ee758f1a54b9c95fbff5b117f9 100644 (file)
@@ -420,6 +420,7 @@ public final class NuxeoClientEmbedded {
                }\r
        }\r
        \r
+       //  REM 10/29/2013 - We may want to add this clause if (!TransactionHelper.isTransactionActive()) {\r
        boolean startTransaction = TransactionHelper.startTransaction();\r
        if (startTransaction == false) {\r
                logger.warn("Could not start a Nuxeo transaction with the TransactionHelper class.");\r
@@ -469,6 +470,7 @@ public final class NuxeoClientEmbedded {
                                        + repositoryInstances.size());\r
                }\r
             }\r
+            //if (TransactionHelper.isTransactionActiveOrMarkedRollback())\r
             TransactionHelper.commitOrRollbackTransaction();\r
         }\r
     }\r
index c764a3c3387b3873ebc46335483bec73447d396b..cebbb47db2e1d1d04438bea3a49b6be6a2d67aaf 100644 (file)
@@ -1737,8 +1737,12 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             }
         }
 
-        if (logger.isTraceEnabled()) {
-            logger.trace("Testing call to getRepository() repository root: " + repoSession.getRootDocument());
+        try {
+               if (logger.isTraceEnabled()) {
+                   logger.trace("Testing call to getRepository() repository root: " + repoSession.getRootDocument());
+               }
+        } catch (Throwable e) {
+               logger.trace("Test call to Nuxeo's getRepository() repository root failed", e);
         }
 
         profiler.stop();