From: Richard Millet Date: Tue, 21 Aug 2012 07:33:44 +0000 (-0700) Subject: CSPACE-5466: See JIRA issue for full description. In short, media from originating... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=d59528e66b0fd36453b4c515bcb9930ca1ebe4a2;p=tmp%2Fjakarta-migration.git CSPACE-5466: See JIRA issue for full description. In short, media from originating from an external URL is deleted from the system after a set of derivatives are produced. --- diff --git a/services/blob/client/pom.xml b/services/blob/client/pom.xml index 8223e96a3..3e8888d03 100644 --- a/services/blob/client/pom.xml +++ b/services/blob/client/pom.xml @@ -14,6 +14,12 @@ services.blob.client + + org.nuxeo.ecm.core + nuxeo-core-storage-sql-management + 5.5.0-HF07 + + org.slf4j diff --git a/services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java b/services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java index 4033f33de..5788d17cf 100644 --- a/services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java +++ b/services/blob/client/src/main/java/org/collectionspace/services/client/BlobClient.java @@ -38,6 +38,7 @@ public class BlobClient extends AbstractCommonListPoxServiceClientImpl { // if (derivativeTerm != null || getContentFlag == true) { StringBuffer mimeTypeBuffer = new StringBuffer(); - BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession, //FIXME: REM - If the blob's binary has been removed from the file system, then this call will return null. We need to at least spit out a meaningful error/warning message + BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession, blobRepositoryId, derivativeTerm, getContentFlag, mimeTypeBuffer); if (getContentFlag == true) { - blobInput.setContentStream(blobOutput.getBlobInputStream()); + if (blobOutput != null) { + blobInput.setContentStream(blobOutput.getBlobInputStream()); + } else { + // If we can't find the blob's content, we'll return a "missing document" image + blobInput.setContentStream(NuxeoImageUtils.getResource(NuxeoImageUtils.DOCUMENT_MISSING_PLACEHOLDER_IMAGE)); + mimeTypeBuffer.append(NuxeoImageUtils.MIME_JPEG); + } } if (derivativeTerm != null) { @@ -179,7 +187,7 @@ extends DocHandlerBase { blobInput.setMimeType(mimeType); blobsCommon.setMimeType(mimeType); } else { - blobInput.setMimeType(blobsCommon.getMimeType()); + blobInput.setMimeType(blobsCommon.getMimeType()); // Set the MIME type to the one in blobsCommon } blobsCommon.setRepositoryId(null); //hide the repository id from the GET results payload since it is private @@ -202,12 +210,19 @@ extends DocHandlerBase { ServiceContext ctx = this.getServiceContext(); BlobInput blobInput = BlobUtil.getBlobInput(ctx); // The blobInput should have been put into the context by the Blob or Media resource if (blobInput != null && blobInput.getBlobFile() != null) { + boolean purgeOriginal = false; + MultivaluedMap queryParams = ctx.getQueryParams(); + String purgeOriginalStr = queryParams.getFirst(BlobClient.BLOB_PURGE_ORIGINAL); + if (purgeOriginalStr != null && purgeOriginalStr.isEmpty() == false) { // Find our if the caller wants us to purge/delete the original + purgeOriginal = true; + } // // If blobInput has a file then we just received a multipart/form-data file post or a URI query parameter // DocumentModel documentModel = wrapDoc.getWrappedObject(); - RepositoryInstance repoSession = this.getRepositorySession(); - BlobsCommon blobsCommon = NuxeoImageUtils.createBlobInRepository(ctx, repoSession, blobInput); + RepositoryInstance repoSession = this.getRepositorySession(); + + BlobsCommon blobsCommon = NuxeoImageUtils.createBlobInRepository(ctx, repoSession, blobInput, purgeOriginal); blobInput.setBlobCsid(documentModel.getName()); //Assumption here is that the documentModel "name" field is storing a CSID PoxPayloadIn input = ctx.getInput(); diff --git a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java index a729108fd..03e4267f4 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java +++ b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java @@ -25,7 +25,6 @@ package org.collectionspace.services.client.test; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.InputStream; import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index 3a93a231b..43bdcdad0 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -3,6 +3,10 @@ */ package org.collectionspace.services.common; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -18,6 +22,7 @@ import org.collectionspace.authentication.AuthN; import org.collectionspace.services.config.service.InitHandler; import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon; +import org.collectionspace.services.common.config.ConfigReader; import org.collectionspace.services.common.config.ServicesConfigReaderImpl; import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; import org.collectionspace.services.common.init.AddIndices; @@ -321,6 +326,15 @@ public class ServiceMain { public String getServerRootDir() { return serverRootDir; } + + public InputStream getResourceAsStream(String resourceName) throws FileNotFoundException { + InputStream result = null; + + String resourcePath = getServerRootDir() + File.separator + ConfigReader.RESOURCES_DIR_PATH + File.separator + resourceName; + result = new FileInputStream(new File(resourcePath)); + + return result; + } /* * Save a copy of the DataSource instances that exist in our initial JNDI context. For some reason, after starting up diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java index f6a4295d2..e218427dd 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java @@ -470,6 +470,6 @@ public class TenantBindingConfigReaderImpl } public String getResourcesDir(){ - return getConfigRootDir() + File.separator + "resources"; + return getConfigRootDir() + File.separator + RESOURCES_DIR_NAME; } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java index 704aefff3..67af453bc 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java @@ -30,17 +30,24 @@ import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.InputStream; import java.io.BufferedInputStream; import java.io.IOException; +import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Set; +import java.lang.reflect.Field; import javax.imageio.ImageIO; @@ -51,6 +58,7 @@ import org.nuxeo.runtime.api.Framework; //import org.nuxeo.common.utils.FileUtils; import org.nuxeo.ecm.platform.picture.api.ImageInfo; +import org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants; import org.nuxeo.ecm.platform.picture.api.ImagingService; import org.nuxeo.ecm.platform.picture.api.PictureView; @@ -69,7 +77,12 @@ import org.nuxeo.ecm.core.repository.RepositoryService; //import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean; //import org.nuxeo.ecm.core.storage.sql.RepositoryImpl; //import org.nuxeo.ecm.core.storage.sql.Repository; +import org.nuxeo.ecm.core.storage.sql.Binary; +import org.nuxeo.ecm.core.storage.sql.BinaryManager; import org.nuxeo.ecm.core.storage.sql.DefaultBinaryManager; +import org.nuxeo.ecm.core.storage.sql.RepositoryImpl; +import org.nuxeo.ecm.core.storage.sql.RepositoryResolver; +import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob; import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository; //import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor; @@ -77,6 +90,7 @@ import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository; import org.nuxeo.ecm.core.api.IdRef; import org.nuxeo.ecm.core.api.blobholder.BlobHolder; import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder; +import org.nuxeo.ecm.core.api.impl.DocumentModelImpl; import org.nuxeo.ecm.core.api.impl.blob.FileBlob; import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob; import org.nuxeo.ecm.core.api.impl.blob.ByteArrayBlob; @@ -95,6 +109,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; //import org.nuxeo.ecm.core.repository.jcr.testing.RepositoryOSGITestCase; +import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.blob.BlobInput; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils; @@ -108,22 +123,24 @@ import org.collectionspace.services.blob.MeasuredPartGroupList; import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.nuxeo.client.java.CommonList; import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants; +import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.common.blob.BlobOutput; import org.collectionspace.services.config.service.ListResultField; -//import org.collectionspace.ecm.platform.quote.api.QuoteManager; -// TODO: Auto-generated Javadoc /** * The Class NuxeoImageUtils. */ public class NuxeoImageUtils { + /** The Constant logger. */ private static final Logger logger = LoggerFactory .getLogger(NuxeoImageUtils.class); - private static final String MIME_JPEG = "image/jpeg"; + public static final String DOCUMENT_PLACEHOLDER_IMAGE = "documentImage.jpg"; + public static final String DOCUMENT_MISSING_PLACEHOLDER_IMAGE = "documentImageMissing.jpg"; + public static final String MIME_JPEG = "image/jpeg"; /* * FIXME: REM - These constants should be coming from configuration and NOT * hard coded. @@ -267,8 +284,10 @@ public class NuxeoImageUtils { // List blobListItems = result.getBlobListItem(); HashMap item = null; for (Blob blob : docBlobs) { - item = createBlobListItem(blob, uri); - commonList.addItem(item); + if (blob != null) { + item = createBlobListItem(blob, uri); + commonList.addItem(item); + } } return commonList; @@ -724,6 +743,19 @@ public class NuxeoImageUtils { } return result; } + + private static BinaryManager getBinaryManagerService() throws ClientException { + BinaryManager result = null; + try { + result = Framework.getService(BinaryManager.class); + } catch (Exception e) { + String msg = "Unable to get Nuxeo's BinaryManager service."; + logger.error(msg, e); + throw new ClientException("msg", e); + } + return result; + } + /** * Creates the picture. @@ -738,7 +770,9 @@ public class NuxeoImageUtils { * @throws Exception */ public static BlobsCommon createBlobInRepository(ServiceContext ctx, - RepositoryInstance repoSession, BlobInput blobInput) throws Exception { + RepositoryInstance repoSession, + BlobInput blobInput, + boolean purgeOriginal) throws Exception { BlobsCommon result = null; try { @@ -756,7 +790,7 @@ public class NuxeoImageUtils { } } - result = createBlobInRepository(repoSession, wspaceDoc, blobFile, null /*mime type*/); + result = createBlobInRepository(repoSession, wspaceDoc, purgeOriginal, blobFile, null /*mime type*/); } catch (Exception e) { logger.error("Could not create image blob", e); throw e; @@ -782,8 +816,9 @@ public class NuxeoImageUtils { */ static public BlobsCommon createBlobInRepository(RepositoryInstance nuxeoSession, DocumentModel blobLocation, - // InputStream file, - File file, String mimeType) { + boolean purgeOriginal, + File file, + String mimeType) { BlobsCommon result = null; try { @@ -799,8 +834,29 @@ public class NuxeoImageUtils { blobLocation.getPathAsString(), true, file.getName()); logger.debug("Stop --> Finished calling Nuxeo to create the blob document."); - + result = createBlobsCommon(documentModel, fileBlob); // Now create our metadata resource document + + // If the sender only wanted use to generate derivatives, we need to clear the original content + if (purgeOriginal == true) { + // Empty the document model's "content" property -this does not delete the actual file/blob + documentModel.setPropertyValue("file:content", (Serializable) null); + + if (documentModel.hasFacet(ImagingDocumentConstants.PICTURE_FACET)) { + // Now with no content, the derivative listener wants to update the derivatives. So to + // prevent the listener, we remove the "Picture" facet from the document + NuxeoUtils.removeFacet(documentModel, ImagingDocumentConstants.PICTURE_FACET); // Removing this facet ensures the original derivatives are unchanged. + nuxeoSession.saveDocument(documentModel); + // Now that we've emptied the document model's content field, we can add back the Picture facet + NuxeoUtils.addFacet(documentModel, ImagingDocumentConstants.PICTURE_FACET); + } + + nuxeoSession.saveDocument(documentModel); + // Next, we need to remove the actual file from Nuxeo's data directory + DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) documentModel + .getAdapter(BlobHolder.class); + boolean deleteSuccess = NuxeoUtils.deleteFileOfBlob(docBlobHolder.getBlob()); + } } catch (Exception e) { result = null; logger.error("Could not create new Nuxeo blob document.", e); //FIXME: REM - This should probably be re-throwing the exception? @@ -829,6 +885,18 @@ public class NuxeoImageUtils { // } // } // } + + public static InputStream getResource(String resourceName) { + InputStream result = null; + + try { + result = ServiceMain.getInstance().getResourceAsStream(resourceName); + } catch (FileNotFoundException e) { + logger.error("Missing Services resource: " + resourceName, e); + } + + return result; + } /** * Gets the image. @@ -869,7 +937,7 @@ public class NuxeoImageUtils { if (derivativeTerm != null) { docBlob = pictureBlobHolder.getBlob(derivativeTerm); // Nuxeo derivatives are all JPEG - outMimeType.append(docBlob.getMimeType()); + outMimeType.append(MIME_JPEG); // All Nuxeo image derivatives are JPEG images. } else { docBlob = pictureBlobHolder.getBlob(); } @@ -890,15 +958,13 @@ public class NuxeoImageUtils { if (getContentFlag == true) { InputStream remoteStream = null; if (isNonImageDerivative == false) { - remoteStream = docBlob.getStream(); + remoteStream = docBlob.getStream(); // This will fail if the blob's file has been deleted. FileNotFoundException thrown. } else { - remoteStream = NuxeoImageUtils.class.getClassLoader() // for now, non-image derivatives are just placeholder document images - .getResourceAsStream("documentImage.jpg"); + remoteStream = getResource(DOCUMENT_PLACEHOLDER_IMAGE); outMimeType.append(MIME_JPEG); } BufferedInputStream bufferedInputStream = new BufferedInputStream( - remoteStream); // FIXME: REM - To improve performance, try - // BufferedInputStream(InputStream in, int size)? + remoteStream); result.setBlobInputStream(bufferedInputStream); } } catch (Exception e) { diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java index a3ed9fb36..aa525b748 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java @@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.File; +import java.lang.reflect.Field; import java.util.GregorianCalendar; import java.util.List; @@ -49,6 +50,7 @@ import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.repository.RepositoryInstance; +import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentRef; import org.nuxeo.ecm.core.api.IdRef; @@ -64,6 +66,8 @@ import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter; import org.nuxeo.ecm.core.schema.SchemaManager; import org.nuxeo.ecm.core.search.api.client.querymodel.descriptor.QueryModelDescriptor; +import org.nuxeo.ecm.core.storage.sql.Binary; +import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob; import org.nuxeo.runtime.api.Framework; @@ -91,7 +95,94 @@ public class NuxeoUtils { //private static final String ORDER_BY_CLAUSE_REGEX = "\\w+(_\\w+)?:\\w+( ASC| DESC)?(, \\w+(_\\w+)?:\\w+( ASC| DESC)?)*"; // Allow paths so can sort on complex fields. CSPACE-4601 private static final String ORDER_BY_CLAUSE_REGEX = "\\w+(_\\w+)?:\\w+(/(\\*|\\w+))*( ASC| DESC)?(, \\w+(_\\w+)?:\\w+(/(\\*|\\w+))*( ASC| DESC)?)*"; + + /* + * Keep this method private. This method uses reflection to gain access to a protected field in Nuxeo's "Binary" class. Once we learn how + * to locate the "file" field of a Binary instance without breaking our "contract" with this class, we should minimize + * our use of this method. + */ + private static File getFileOfBlob(Blob blob) { + File result = null; + + if (blob instanceof SQLBlob) { + SQLBlob sqlBlob = (SQLBlob)blob; + Binary binary = sqlBlob.getBinary(); + try { + Field fileField = binary.getClass().getDeclaredField("file"); + boolean accessibleState = fileField.isAccessible(); + if (accessibleState == false) { + fileField.setAccessible(true); + } + result = (File)fileField.get(binary); + fileField.setAccessible(accessibleState); // set it back to its original access state + } catch (Exception e) { + logger.error("Was not able to find the 'file' field", e); + } + } + + return result; + } + + static public boolean deleteFileOfBlob(Blob blob) { + boolean result = false; + + File fileToDelete = getFileOfBlob(blob); + result = fileToDelete.delete(); + if (result == false) { + logger.warn("Could not delete the blob file at: " + fileToDelete.getAbsolutePath()); + } + + return result; + } + + /* + * This method will fail to return a facet list if non exist or if Nuxeo changes the + * DocumentModelImpl class "facets" field to be of a different type or if they remove it altogether. + */ + public static Set getFacets(DocumentModel docModel) { + Set result = null; + + try { + Field f = docModel.getClass().getDeclaredField("facets"); + f.setAccessible(true); + result = (Set) f.get(docModel); + f.setAccessible(false); + } catch (Exception e) { + logger.error("Could not remove facet from DocumentModel instance: " + docModel.getId(), e); + } + + return result; + } + + /* + * Remove a Nuxeo facet from a document model instance + */ + public static boolean removeFacet(DocumentModel docModel, String facet) { + boolean result = false; + + Set facets = getFacets(docModel); + if (facets != null && facets.contains(facet)) { + facets.remove(facet); + result = true; + } + + return result; + } + + /* + * Adds a Nuxeo facet to a document model instance + */ + public static boolean addFacet(DocumentModel docModel, String facet) { + boolean result = false; + + Set facets = getFacets(docModel); + if (facets != null && !facets.contains(facet)) { + facets.add(facet); + result = true; + } + return result; + } public static void exportDocModel(DocumentModel src) { DocumentReader reader = null; diff --git a/services/common/src/main/resources/documentImage.jpg b/services/common/src/main/resources/documentImage.jpg deleted file mode 100644 index 89d50669c..000000000 Binary files a/services/common/src/main/resources/documentImage.jpg and /dev/null differ diff --git a/services/config/src/main/java/org/collectionspace/services/common/config/AbstractConfigReaderImpl.java b/services/config/src/main/java/org/collectionspace/services/common/config/AbstractConfigReaderImpl.java index 54269fdd7..eb3439c2b 100644 --- a/services/config/src/main/java/org/collectionspace/services/common/config/AbstractConfigReaderImpl.java +++ b/services/config/src/main/java/org/collectionspace/services/common/config/AbstractConfigReaderImpl.java @@ -144,7 +144,7 @@ public abstract class AbstractConfigReaderImpl protected String getAbsoluteFileName(String configFileName) { return serverRootDir + File.separator + CSPACE_DIR_NAME - + File.separator + CONFIG_DIR_NAME + + File.separator + CONFIG_DIR_PATH + File.separator + configFileName; } @@ -155,6 +155,6 @@ public abstract class AbstractConfigReaderImpl protected String getConfigRootDir() { return serverRootDir + File.separator + CSPACE_DIR_NAME - + File.separator + CONFIG_DIR_NAME; + + File.separator + CONFIG_DIR_PATH; } } diff --git a/services/config/src/main/java/org/collectionspace/services/common/config/ConfigReader.java b/services/config/src/main/java/org/collectionspace/services/common/config/ConfigReader.java index 74bf767d2..0ba485543 100644 --- a/services/config/src/main/java/org/collectionspace/services/common/config/ConfigReader.java +++ b/services/config/src/main/java/org/collectionspace/services/common/config/ConfigReader.java @@ -31,7 +31,9 @@ import java.io.File; public interface ConfigReader { final public static String CSPACE_DIR_NAME = "cspace"; - final public static String CONFIG_DIR_NAME = "config" + File.separator + "services"; + final public static String CONFIG_DIR_PATH = "config" + File.separator + "services"; + final public static String RESOURCES_DIR_NAME = "resources"; + final public static String RESOURCES_DIR_PATH = CSPACE_DIR_NAME + File.separator + CONFIG_DIR_PATH + File.separator + RESOURCES_DIR_NAME; /** * getFileName - get configuration file name diff --git a/services/media/client/src/main/java/org/collectionspace/services/client/MediaClient.java b/services/media/client/src/main/java/org/collectionspace/services/client/MediaClient.java index 7943c13df..0a28ffc57 100644 --- a/services/media/client/src/main/java/org/collectionspace/services/client/MediaClient.java +++ b/services/media/client/src/main/java/org/collectionspace/services/client/MediaClient.java @@ -78,8 +78,8 @@ public class MediaClient extends AbstractCommonListPoxServiceClientImpl createMediaAndBlobWithUri(PoxPayloadOut xmlPayload, String blobUri) { - return getProxy().createMediaAndBlobWithUri(xmlPayload.getBytes(), blobUri); + public ClientResponse createMediaAndBlobWithUri(PoxPayloadOut xmlPayload, String blobUri, boolean purgeOriginal) { + return getProxy().createMediaAndBlobWithUri(xmlPayload.getBytes(), blobUri, purgeOriginal); } /** diff --git a/services/media/client/src/main/java/org/collectionspace/services/client/MediaProxy.java b/services/media/client/src/main/java/org/collectionspace/services/client/MediaProxy.java index d91b08ecb..9d39f503e 100644 --- a/services/media/client/src/main/java/org/collectionspace/services/client/MediaProxy.java +++ b/services/media/client/src/main/java/org/collectionspace/services/client/MediaProxy.java @@ -39,5 +39,6 @@ public interface MediaProxy extends CollectionSpaceCommonListPoxProxy { @Produces("application/xml") @Consumes("application/xml") ClientResponsecreateMediaAndBlobWithUri(byte[] xmlPayload, - @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri); + @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri, + @QueryParam(BlobClient.BLOB_PURGE_ORIGINAL) boolean purgeOriginal); } diff --git a/services/media/client/src/test/java/org/collectionspace/services/client/test/MediaServiceTest.java b/services/media/client/src/test/java/org/collectionspace/services/client/test/MediaServiceTest.java index b6c3318d2..d491d90d6 100644 --- a/services/media/client/src/test/java/org/collectionspace/services/client/test/MediaServiceTest.java +++ b/services/media/client/src/test/java/org/collectionspace/services/client/test/MediaServiceTest.java @@ -206,11 +206,12 @@ public class MediaServiceTest extends AbstractPoxServiceTestImpl mediaRes = client.createMediaAndBlobWithUri(multipart, PUBLIC_URL_DECK); + ClientResponse mediaRes = client.createMediaAndBlobWithUri(multipart, PUBLIC_URL_DECK, true); // purge the original String mediaCsid = null; try { assertStatusCode(mediaRes, testName); mediaCsid = extractId(mediaRes); +// allResourceIdsCreated.add(mediaCsid); // Re-enable this and also add code to delete the associated blob } finally { if (mediaRes != null) { mediaRes.releaseConnection(); diff --git a/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java b/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java index 0afbf1717..eaa97f7c0 100644 --- a/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java +++ b/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java @@ -124,9 +124,11 @@ public class MediaResource extends ResourceBase { Response response = null; try { - ServiceContext ctx = createServiceContext(BlobClient.SERVICE_NAME, (PoxPayloadIn)null); // The blobUri argument is our payload + MultivaluedMap queryParams = ui.getQueryParameters(); + ServiceContext ctx = createServiceContext(BlobClient.SERVICE_NAME, + queryParams); BlobInput blobInput = BlobUtil.getBlobInput(ctx); // the blob doc handler will look for this in the context - blobInput.createBlobFile(blobUri); + blobInput.createBlobFile(blobUri); // The blobUri argument is our payload 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); @@ -136,7 +138,7 @@ public class MediaResource extends ResourceBase { } /* - * 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. + * 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) */ @@ -153,7 +155,7 @@ public class MediaResource extends ResourceBase { MultivaluedMap queryParams = ui.getQueryParameters(); String blobUri = queryParams.getFirst(BlobClient.BLOB_URI_PARAM); if (blobUri != null && blobUri.isEmpty() == false) { - result = createBlobWithUri(resourceMap, ui, xmlPayload, blobUri); + result = createBlobWithUri(resourceMap, ui, xmlPayload, blobUri); // uses the blob resource and doc handler to create the blob 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 } @@ -180,7 +182,7 @@ public class MediaResource extends ResourceBase { ServiceContext ctx = createServiceContext(BlobClient.SERVICE_NAME, input); BlobInput blobInput = BlobUtil.getBlobInput(ctx); blobInput.createBlobFile(blobUri); - response = this.create(input, ctx); + response = this.create(input, ctx); // calls the blob resource/doc-handler to create the blob // // Next, update the Media record to be linked to the blob //