]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-3635: Modified Media resource to create a blob record from a URI at the same...
authorRichard Millet <remillet@berkeley.edu>
Tue, 14 Aug 2012 09:19:20 +0000 (02:19 -0700)
committerRichard Millet <remillet@berkeley.edu>
Tue, 14 Aug 2012 09:19:20 +0000 (02:19 -0700)
services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java
services/blob/client/src/test/java/org/collectionspace/services/client/test/BlobServiceTest.java
services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java
services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java
services/media/client/src/main/java/org/collectionspace/services/client/MediaClient.java
services/media/client/src/main/java/org/collectionspace/services/client/MediaProxy.java
services/media/client/src/test/java/org/collectionspace/services/client/test/MediaServiceTest.java
services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java
services/media/service/src/main/java/org/collectionspace/services/media/nuxeo/MediaDocumentModelHandler.java

index 5ae0e2662d78613c88458f05bd893f4138ac95e8..4033f33de9cbf00721ccd0bdcbb3b58a980702cc 100644 (file)
@@ -37,6 +37,7 @@ public class BlobClient extends AbstractCommonListPoxServiceClientImpl<BlobProxy
 
        //HTTP query param string for specifying a URI source to blob bits.
        public static final String BLOB_URI_PARAM = "blobUri";
+       public static final String BLOB_CSID_PARAM = "blobCsid";
        
        //Image blob metadata labels
        public static final String IMAGE_MEASURED_PART_LABEL = "digitalImage";
index 3bc6e801d997e61e045d3d77c19f6b84d478ca18..48b4da88e121b35e6939540296a81c209582ec7a 100644 (file)
@@ -67,6 +67,9 @@ public class BlobServiceTest extends AbstractPoxServiceTestImpl<AbstractCommonLi
     private final static BigDecimal KNOWN_IMAGE_WIDTH = new BigDecimal(640.0);
     private final static BigDecimal KNOWN_IMAGE_HEIGHT = new BigDecimal(480.0);
     
+    private final static String PUBLIC_URL_BIRD = "http://farm6.static.flickr.com/5289/5688023100_15e00cde47_o.jpg";
+    private final static String PUBLIC_URL_DECK = "http://farm8.staticflickr.com/7231/6962564226_4bdfc17599_k_d.jpg";
+    
     
     private boolean blobCleanup = true;
 
@@ -237,8 +240,14 @@ public class BlobServiceTest extends AbstractPoxServiceTestImpl<AbstractCommonLi
     
     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
                dependsOnMethods = {"CRUDTests"})
-    public void createBlobWithURL(String testName) throws Exception {
-       createBlob(testName, true /*with URI*/, "http://farm6.static.flickr.com/5289/5688023100_15e00cde47_o.jpg");
+    public void createBlobWithURL1(String testName) throws Exception {
+       createBlob(testName, true /*with URI*/, PUBLIC_URL_BIRD);
+    }    
+    
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+               dependsOnMethods = {"CRUDTests"})
+    public void createBlobWithURL2(String testName) throws Exception {
+       createBlob(testName, true /*with URI*/, PUBLIC_URL_DECK);
     }    
     
     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
index 7c50cf5247ad09d1cbbe5c738cf4ae5cad6a888c..ec66b28a20be926dde0ce0803c1bac641f4afdc2 100644 (file)
@@ -279,6 +279,15 @@ public abstract class AbstractCollectionSpaceResourceImpl<IT, OT>
         return ctx;\r
     }\r
     \r
+    protected ServiceContext<IT, OT> createServiceContext(\r
+               IT input,\r
+               MultivaluedMap<String, String> queryParams) throws Exception {\r
+       return createServiceContext(this.getServiceName(),\r
+                       input,\r
+                       queryParams,\r
+                       null /* the class of the input type */);\r
+    }\r
+    \r
     /**\r
      * Creates the service context.\r
      * \r
index 7d8a55683244468cc2bbae3b31d7f6131d1a1ee2..8c21ffb1a424b66b4b9de5ff95ac2d4903d538a4 100644 (file)
@@ -88,10 +88,10 @@ public abstract class ResourceBase
     public Response create(@Context ResourceMap resourceMap,\r
                @Context UriInfo ui,\r
             String xmlPayload) {\r
-        return this.create(null, resourceMap, ui, xmlPayload);\r
+        return this.create(null, resourceMap, ui, xmlPayload); \r
     }\r
     \r
-    public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx,\r
+    public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx, // REM: 8/13/2012 - Some sub-classes will override this method -e.g., MediaResource does.\r
                @Context ResourceMap resourceMap,\r
                @Context UriInfo ui,\r
             String xmlPayload) {\r
@@ -99,7 +99,7 @@ public abstract class ResourceBase
        \r
         try {\r
             PoxPayloadIn input = new PoxPayloadIn(xmlPayload);\r
-            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);\r
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input, ui.getQueryParameters());\r
             ctx.setResourceMap(resourceMap);\r
             if (parentCtx != null && parentCtx.getCurrentRepositorySession() != null) {\r
                ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists\r
index 67ac258d34e809fea4b2f56509df9dd4c8fb5e68..7943c13dff8705105ad569a5c0cd5b773652ed21 100644 (file)
@@ -55,9 +55,11 @@ public class MediaClient extends AbstractCommonListPoxServiceClientImpl<MediaPro
     /**
      * @param media
      * @return
+     * 
+     * Creates a new blob resource from the form data and associates it with an existing media resource
      *
      */
-    public ClientResponse<Response> createBlobFromFormData(String csid,
+    public ClientResponse<Response> createBlobFromFormData(String csid, // this is the Media resource CSID
                MultipartFormDataOutput formDataOutput) {
         return getProxy().createBlobFromFormData(csid, formDataOutput);
     }    
@@ -65,11 +67,20 @@ public class MediaClient extends AbstractCommonListPoxServiceClientImpl<MediaPro
     /**
      * @param media
      * @return
+     * 
+     * Creates a new blob
      *
      */
     public ClientResponse<Response> createBlobFromUri(String csid, String blobUri) {
         return getProxy().createBlobFromUri(csid, blobUri, blobUri); //send the URI as both a query param and as content
-    }    
+    }
+    
+    /*
+     * Create both a new media record
+     */
+    public ClientResponse<Response> createMediaAndBlobWithUri(PoxPayloadOut xmlPayload, String blobUri) {
+       return getProxy().createMediaAndBlobWithUri(xmlPayload.getBytes(), blobUri);
+    }
         
     /**
      * @param csid
index 841cc57aba90ba192a8e63b36362f9ed6ca78efb..d91b08ecb13dc33befdcb287b5612cf2964785bd 100644 (file)
@@ -34,4 +34,10 @@ public interface MediaProxy extends CollectionSpaceCommonListPoxProxy {
     ClientResponse<Response>createBlobFromUri(@PathParam("csid") String csid,
                @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri,
                String emptyXML); //this "emptyXML" param is needed to force RESTEasy to produce a Content-Type header for this POST    
+
+    @POST
+       @Produces("application/xml")
+       @Consumes("application/xml")
+    ClientResponse<Response>createMediaAndBlobWithUri(byte[] xmlPayload,
+               @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri);    
 }
index 3d8a2cf5c3f62480a530f77d8160b454e4443bd5..b6c3318d2f8919f4d2b9e0302e93074135f5cea4 100644 (file)
@@ -56,6 +56,7 @@ public class MediaServiceTest extends AbstractPoxServiceTestImpl<AbstractCommonL
 
     private final String CLASS_NAME = MediaServiceTest.class.getName();
     private final Logger logger = LoggerFactory.getLogger(MediaServiceTest.class);
+    private final static String PUBLIC_URL_DECK = "http://farm8.staticflickr.com/7231/6962564226_4bdfc17599_k_d.jpg";
 
     private boolean mediaCleanup = true;
     
@@ -200,6 +201,24 @@ public class MediaServiceTest extends AbstractPoxServiceTestImpl<AbstractCommonL
         createBlob(testName, true /*with URI*/);
     }
     
+    @Test(dataProvider = "testName", 
+               dependsOnMethods = {"createWithBlobUri"})
+    public void createMediaAndBlobWithUri(String testName) throws Exception {
+               MediaClient client = new MediaClient();
+               PoxPayloadOut multipart = createMediaInstance(createIdentifier());
+               ClientResponse<Response> mediaRes = client.createMediaAndBlobWithUri(multipart, PUBLIC_URL_DECK);
+               String mediaCsid = null;
+               try {
+                       assertStatusCode(mediaRes, testName);
+                       mediaCsid = extractId(mediaRes);
+               } finally {
+                       if (mediaRes != null) {
+                               mediaRes.releaseConnection();
+                       }
+               }
+    }
+    
+    
     @Test(dataProvider = "testName", 
                dependsOnMethods = {"createWithBlobUri"})
     public void createWithBlobPost(String testName) throws Exception {
index 9d1cd186519524d34fb6420983ef7b541f4bdd7e..0afbf1717fdbcf3b3e81d9f9caac56e6c5614bc9 100644 (file)
@@ -25,12 +25,14 @@ package org.collectionspace.services.media;
 
 import org.collectionspace.services.blob.BlobResource;
 import org.collectionspace.services.client.BlobClient;
+import org.collectionspace.services.client.CollectionSpaceClientUtils;
+import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.MediaClient;
 import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.common.ResourceBase;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.ResourceMap;
 import org.collectionspace.services.common.ServiceMessages;
 import org.collectionspace.services.common.blob.BlobInput;
 import org.collectionspace.services.common.blob.BlobUtil;
@@ -50,8 +52,9 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
-import java.io.InputStream;
+import javax.ws.rs.core.UriInfo;
 
 @Path(MediaClient.SERVICE_PATH)
 @Consumes("application/xml")
@@ -102,9 +105,6 @@ public class MediaResource extends ResourceBase {
         return result;
        }       
        
-    //FIXME retrieve client type from configuration
-//    final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
-
     @Override
     protected String getVersionString() {
        final String lastChangeRevision = "$LastChangedRevision: 2108 $";
@@ -116,11 +116,62 @@ public class MediaResource extends ResourceBase {
        return MediaCommon.class;
     }
     
+    /*
+     * Creates a new media record/resource AND creates a new blob (using a URL pointing to a media file/resource) and associates
+     * it with the new media record/resource.
+     */
+    protected Response createBlobWithUri(ResourceMap resourceMap, UriInfo ui, String xmlPayload, String blobUri) {
+       Response response = null;
+       
+       try {
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(BlobClient.SERVICE_NAME, (PoxPayloadIn)null); // The blobUri argument is our payload
+               BlobInput blobInput = BlobUtil.getBlobInput(ctx); // the blob doc handler will look for this in the context
+               blobInput.createBlobFile(blobUri);
+               response = this.create((PoxPayloadIn)null, ctx); // By now the binary bits have been created and we just need to create the metadata blob record -this info is in the blobInput var
+       } catch (Exception e) {
+               throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
+       }
+
+               return response;
+    }
+    
+    /*
+     * Looks for a blobUri query param from a POST.  If it finds one then it creates a blob and a media resource and associates them.
+     * (non-Javadoc)
+     * @see org.collectionspace.services.common.ResourceBase#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.ResourceMap, javax.ws.rs.core.UriInfo, java.lang.String)
+     */
+    @Override
+    public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx,
+               @Context ResourceMap resourceMap,
+               @Context UriInfo ui,
+            String xmlPayload) {
+       Response result = null;
+       
+       //
+       // If we find a "blobUri" query param, then we need to create a blob resource/record first and then the media resource/record
+       //
+        MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
+        String blobUri = queryParams.getFirst(BlobClient.BLOB_URI_PARAM);
+        if (blobUri != null && blobUri.isEmpty() == false) {
+               result = createBlobWithUri(resourceMap, ui, xmlPayload, blobUri);
+               String blobCsid = CollectionSpaceClientUtils.extractId(result);
+               queryParams.add(BlobClient.BLOB_CSID_PARAM, blobCsid); // Add the new blob's csid as an artificial query param -the media doc handler will look for this
+        }
+        
+               result = super.create(parentCtx, resourceMap, ui, xmlPayload); // Now call the parent to finish the media resource POST request
+        
+        return result;
+    }
+    
+    
+    /*
+     * Creates a new blob (using a URL pointing to a media file/resource) and associates it with an existing media record/resource.
+     */
     @POST
     @Path("{csid}")
     @Consumes("application/xml")
     @Produces("application/xml")    
-    public Response createBlobWithUri(@PathParam("csid") String csid,
+    public Response createBlobWithUriAndUpdateMedia(@PathParam("csid") String csid,
                @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri) {
        Response response = null;
        PoxPayloadIn input = null;
@@ -143,6 +194,10 @@ public class MediaResource extends ResourceBase {
                return response;
     }    
         
+    /*
+     * Creates a new blob (using the incoming multipart form data) and associates it with an existing media record/resource.
+     * If a URL query param is passed in as well, we use the URL to create the new blob instead of the multipart form data.
+     */
     @POST
     @Path("{csid}")
     @Consumes("multipart/form-data")
@@ -169,7 +224,7 @@ public class MediaResource extends ResourceBase {
                        this.update(csid, input, mediaContext);
                } else {
                        //A URI query param overrides the incoming multipart/form-data payload in the request
-                       response = createBlobWithUri(csid, blobUri);
+                       response = createBlobWithUriAndUpdateMedia(csid, blobUri);
                }
        } catch (Exception e) {
                throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
index c90614aabd6dad3c412435bda7df68810e0bc850..9389ba30ddcc1818b09c4fcba75864cbdbb9b3d9 100644 (file)
@@ -25,6 +25,7 @@ package org.collectionspace.services.media.nuxeo;
 
 import org.collectionspace.services.MediaJAXBSchema;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.client.BlobClient;
 import org.collectionspace.services.common.blob.BlobInput;
 import org.collectionspace.services.common.blob.BlobUtil;
 import org.collectionspace.services.common.context.ServiceContext;
@@ -36,6 +37,8 @@ import org.nuxeo.ecm.core.api.DocumentModel;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.ws.rs.core.MultivaluedMap;
+
 /**
  * The Class MediaDocumentModelHandler.
  */
@@ -73,17 +76,23 @@ public class MediaDocumentModelHandler
        @Override
        public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
                ServiceContext ctx = this.getServiceContext();
+               String blobCsid = null;
+               
                BlobInput blobInput = BlobUtil.getBlobInput(ctx);
                if (blobInput != null && blobInput.getBlobCsid() != null) {
-                       String blobCsid = blobInput.getBlobCsid();
-                       //
-                       // If getBlobCsid has a value then we just received a multipart/form-data file post
-                       //
-                       DocumentModel documentModel = wrapDoc.getWrappedObject();
-                       documentModel.setProperty(ctx.getCommonPartLabel(), MediaJAXBSchema.blobCsid, blobCsid);
+                       blobCsid = blobInput.getBlobCsid(); // If getBlobCsid has a value then we just finishing a multipart/form-data file post, created a blob, and now associating it with an existing media resource 
                } else {
+                       MultivaluedMap<String, String> queryParams = this.getServiceContext().getQueryParams();
+                       blobCsid = queryParams.getFirst(BlobClient.BLOB_CSID_PARAM); // if the blobUri query param is set, it's probably set from the MediaResource.create method -we're creating a blob from a URI and creating a new media resource as well
+                       // extract all the other fields from the input payload
                        super.fillAllParts(wrapDoc, action);
                }
+               
+               //
+               if (blobCsid != null) {
+                       DocumentModel documentModel = wrapDoc.getWrappedObject();
+                       documentModel.setProperty(ctx.getCommonPartLabel(), MediaJAXBSchema.blobCsid, blobCsid);
+               }
        }    
     
 }