From 7dde6cd7ada31f3405cc61721fc53d070928f47a Mon Sep 17 00:00:00 2001 From: remillet Date: Mon, 6 Mar 2017 15:09:19 -0800 Subject: [PATCH] CSPACE-7082: Create a general mechanism for HTTP cache-control settings in the Services. --- .../common/vocabulary/AuthorityResource.java | 20 +-- .../nuxeo/UpdateObjectLocationBatchJob.java | 20 ++- .../services/blob/BlobResource.java | 56 +++++++-- .../tenants/tenant-bindings-proto-unified.xml | 11 +- .../AbstractCollectionSpaceResourceImpl.java | 116 +++++++++++++++--- ...tMultiPartCollectionSpaceResourceImpl.java | 3 +- .../services/common/NuxeoBasedResource.java | 34 +++-- .../services/common/ServiceMessages.java | 36 +++--- .../context/AbstractServiceContextImpl.java | 13 ++ .../common/context/ServiceContext.java | 15 ++- .../config/src/main/resources/service.xsd | 25 +++- .../services/media/MediaResource.java | 13 +- 12 files changed, 280 insertions(+), 82 deletions(-) diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java index 6a71433e2..41d49dfb4 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java @@ -40,6 +40,7 @@ import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.ResponseBuilder; import org.collectionspace.services.client.IClientQueryParams; import org.collectionspace.services.client.IQueryManager; @@ -417,14 +418,16 @@ public abstract class AuthorityResource @GET @Path("{csid}") @Override - public byte[] get( + public Response get( @Context Request request, @Context UriInfo uriInfo, @PathParam("csid") String specifier) { + Response result = null; uriInfo = new UriInfoWrapper(uriInfo); - PoxPayloadOut result = null; + PoxPayloadOut payloadout = null; + try { - ServiceContext ctx = createServiceContext(uriInfo); + ServiceContext ctx = createServiceContext(request, uriInfo); DocumentHandler handler = createDocumentHandler(ctx); Specifier spec = Specifier.getSpecifier(specifier, "getAuthority", "GET"); @@ -439,20 +442,23 @@ public abstract class AuthorityResource handler.setDocumentFilter(myFilter); getRepositoryClient(ctx).get(ctx, handler); } - result = ctx.getOutput(); - + + payloadout = ctx.getOutput(); + ResponseBuilder responseBuilder = Response.ok(payloadout.getBytes()); + this.setCacheControl(ctx, responseBuilder); + result = responseBuilder.build(); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.GET_FAILED, specifier); } if (result == null) { Response response = Response.status(Response.Status.NOT_FOUND).entity( - "Get failed, the requested Authority specifier:" + specifier + ": was not found.").type( + "GET request failed. The requested Authority specifier:" + specifier + ": was not found.").type( "text/plain").build(); throw new CSWebApplicationException(response); } - return result.getBytes(); + return result; } /** diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java index 0e510335c..b4ea9c4e5 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java @@ -26,10 +26,8 @@ import org.collectionspace.services.common.NuxeoBasedResource; import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.api.RefNameUtils; import org.collectionspace.services.common.api.Tools; -import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.invocable.InvocationResults; import org.collectionspace.services.jaxb.AbstractCommonList; - import org.dom4j.DocumentException; //import org.jboss.resteasy.specimpl.UriInfoImpl; import org.jdom.Document; @@ -431,9 +429,21 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable { } protected PoxPayloadOut findByCsid(NuxeoBasedResource resource, String csid) throws URISyntaxException, DocumentException { - byte[] response = resource.get(null, createUriInfo(), csid); - PoxPayloadOut payload = new PoxPayloadOut(response); - return payload; + PoxPayloadOut result = null; + + try { + result = resource.getResourceFromCsid(null, createUriInfo(), csid); + } catch (Exception e) { + String msg = String.format("UpdateObjectLocation batch job could find/get resource CSID='%s' of type '%s'", + csid, resource.getServiceName()); + if (logger.isDebugEnabled()) { + logger.debug(msg, e); + } else { + logger.error(msg); + } + } + + return result; } protected UriInfo createUriInfo() throws URISyntaxException { diff --git a/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java b/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java index cc86d029c..25051d647 100644 --- a/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java +++ b/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java @@ -49,9 +49,11 @@ 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.CacheControl; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.UriInfo; @@ -59,6 +61,8 @@ import javax.ws.rs.core.UriInfo; import java.io.InputStream; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; //FIXME: REM - We should not have Nuxeo dependencies in our resource classes. @@ -68,7 +72,8 @@ import java.util.Map; public class BlobResource extends NuxeoBasedResource { private static final int DEFAULT_MAX_CACHE_AGE = 86400; // 1 day of seconds. - + private static final String DERIVATIVES_REGEX = "(\\w+)(/blobs/\\*/derivatives/)(\\w+)(/content)"; // matches things like 'GET/blobs/*/derivatives/Medium/content' + @Override public String getServiceName(){ return BlobClient.SERVICE_NAME; @@ -158,13 +163,14 @@ public class BlobResource extends NuxeoBasedResource { /* * This method can replace the 'createBlob' -specifically, this JAX-RS technique can replace the call to - * the BlobInput.createBlobFile() method. In theory, this should reduce by 1 the number of time we need to copy + * the BlobInput.createBlobFile() method. In theory, this should reduce by 1 the number of times we need to copy * bits around. */ @POST @Path("{csid}/prototype") @Consumes("multipart/form-data") @Produces(MediaType.TEXT_PLAIN) + @Deprecated public Response prototype(@PathParam("csid") String csid, @Context HttpServletRequest req, @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri, @@ -241,12 +247,28 @@ public class BlobResource extends NuxeoBasedResource { return response; } + /** + * If there is no explicit setting in the Blobs service binding, we'll ask the HTTP client to cache blobs for 1 full day. + * @param ctx + * @param cacheKey + * @return + */ @Override - protected int getCacheMaxAge(ServiceContext ctx) { - int result = super.getCacheMaxAge(ctx); + protected CacheControl getCacheControl(ServiceContext ctx, String cacheKey) { + CacheControl result = null; + + if (cacheKey.matches(DERIVATIVES_REGEX)) { + Pattern p = Pattern.compile(DERIVATIVES_REGEX); + Matcher m = p.matcher(cacheKey); + if (m.find()) { + cacheKey = String.format("%s%s*%s", m.group(1), m.group(2), m.group(4)); // Converts something like this "GET/blobs/*/derivatives/Medium/content" into this "GET/blobs/*/derivatives/*/content" + } + } - if (result <= 0) { - result = this.DEFAULT_MAX_CACHE_AGE; + result = super.getCacheControl(ctx, cacheKey); + if (result == null) { + result = new CacheControl(); + result.setMaxAge(DEFAULT_MAX_CACHE_AGE); } return result; @@ -254,12 +276,15 @@ public class BlobResource extends NuxeoBasedResource { @GET @Path("{csid}/content") - public Response getBlobContent( @PathParam("csid") String csid) { + public Response getBlobContent( + @PathParam("csid") String csid, + @Context Request jaxRsRequest, + @Context UriInfo uriInfo) { Response result = null; - ServiceContext ctx = null; + ServiceContext ctx = null; try { - ctx = createServiceContext(); + ctx = createServiceContext(jaxRsRequest, uriInfo); BlobsCommon blobsCommon = getBlobsCommon(csid); StringBuffer mimeType = new StringBuffer(); InputStream contentStream = getBlobContent(ctx, csid, null /*derivative term*/, mimeType /*will get set*/); @@ -276,7 +301,7 @@ public class BlobResource extends NuxeoBasedResource { return result; } - private BlobsCommon getBlobsCommon(String csid) throws Exception { + private BlobsCommon getBlobsCommon(String csid) throws Exception { BlobsCommon result = null; ServiceContext ctx = createServiceContext(); @@ -341,15 +366,20 @@ public class BlobResource extends NuxeoBasedResource { @Path("{csid}/derivatives/{derivativeTerm}/content") public Response getDerivativeContent( @PathParam("csid") String csid, - @PathParam("derivativeTerm") String derivativeTerm) { + @PathParam("derivativeTerm") String derivativeTerm, + @Context Request jaxRsRequest, + @Context UriInfo uriInfo) { Response result = null; ServiceContext ctx = null; try { - ctx = createServiceContext(); + // Setup the call to get the blob derivative + ctx = createServiceContext(jaxRsRequest, uriInfo); BlobsCommon blobsCommon = getBlobsCommon(csid); StringBuffer mimeType = new StringBuffer(); + // Get the blob derivative from Nuxeo InputStream contentStream = getBlobContent(ctx, csid, derivativeTerm, mimeType); + // Build a response Response.ResponseBuilder responseBuilder = Response.ok(contentStream, mimeType.toString()); setCacheControl(ctx, responseBuilder); responseBuilder = responseBuilder.header("Content-Disposition","inline;filename=\"" @@ -358,7 +388,7 @@ public class BlobResource extends NuxeoBasedResource { } catch (Exception e) { throw bigReThrow(e, ServiceMessages.CREATE_FAILED); } - + return result; } diff --git a/services/common/src/main/cspace/config/services/tenants/tenant-bindings-proto-unified.xml b/services/common/src/main/cspace/config/services/tenants/tenant-bindings-proto-unified.xml index d3511febc..b373c5d85 100644 --- a/services/common/src/main/cspace/config/services/tenants/tenant-bindings-proto-unified.xml +++ b/services/common/src/main/cspace/config/services/tenants/tenant-bindings-proto-unified.xml @@ -155,7 +155,16 @@ - 86400 + + + GET/blobs/*/content + 86401 + + + GET/blobs/*/derivatives/*/content + 86402 + + name diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java index 74284e5a5..1a5dde637 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java @@ -23,7 +23,6 @@ */ package org.collectionspace.services.common; -import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,10 +33,13 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.CSWebApplicationException; import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.common.config.ServiceConfigUtils; @@ -51,13 +53,15 @@ import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.TransactionException; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.common.repository.RepositoryClientFactory; +import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.security.UnauthorizedException; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; +import org.collectionspace.services.config.service.CacheControlConfig; +import org.collectionspace.services.config.service.DocHandlerParams.Params.CacheControlConfigElement; import org.collectionspace.services.config.service.ServiceBindingType; import org.collectionspace.services.config.service.DocHandlerParams.Params; import org.collectionspace.services.description.ServiceDescription; - import org.jboss.resteasy.spi.HttpRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -162,6 +166,14 @@ public abstract class AbstractCollectionSpaceResourceImpl return docHandler; } + protected ServiceContext createServiceContext(Request requestInfo, UriInfo uriInfo) throws Exception { + ServiceContext result = this.createServiceContext(uriInfo); + + result.setRequestInfo(requestInfo); + + return result; + } + /** * Creates the service context. * @@ -650,35 +662,105 @@ public abstract class AbstractCollectionSpaceResourceImpl } /** - * Get max cache age for HTTP responses from the tenant's service bindings. - * - * @param ctx + * Find a named CacheControlConfig instance. + * @param element + * @param cacheKey * @return */ - protected int getCacheMaxAge(ServiceContext ctx) { - BigInteger result = null; + private CacheControlConfig getCacheControl(CacheControlConfigElement element, String cacheKey) { + CacheControlConfig result = null; + + List list = element.getCacheControlConfigList(); + for (CacheControlConfig cacheControlConfig : list) { + if (cacheControlConfig.getKey().equalsIgnoreCase(cacheKey)) { + result = cacheControlConfig; + break; + } + } + + return result; + } + + /* + * By default, use the request's URI and HTTP method to form the cache-key to use when looking up the + * cache control configuration from the service bindings + */ + protected CacheControl getDefaultCacheControl(ServiceContext ctx) { + UriInfo uriInfo = ctx.getUriInfo(); + Request requestInfo = ctx.getRequestInfo(); + + if (uriInfo != null && requestInfo != null) try { + String resName = SecurityUtils.getResourceName(uriInfo); + String requestMethod = requestInfo.getMethod(); + return getCacheControl(ctx, String.format("%s/%s", requestMethod, resName)); // example, "GET/blobs/*/content" + } catch (Exception e) { + logger.debug(e.getMessage(), e); + } + + return getCacheControl(ctx, "default"); // Look for a default one if we couldn't find based on the resource request + } + + protected CacheControl getCacheControl(ServiceContext ctx, String cacheKey) { + CacheControl result = null; try { Params docHandlerParams = ServiceConfigUtils.getDocHandlerParams(ctx.getTenantId(), ctx.getServiceName()); - if (docHandlerParams.getCacheMaxAge() != null) { - result = docHandlerParams.getCacheMaxAge(); + CacheControlConfig cacheControlConfig = getCacheControl(docHandlerParams.getCacheControlConfigElement(), cacheKey); + if (cacheControlConfig != null) { + result = new CacheControl(); + + if (cacheControlConfig.isPrivate() != null) { + result.setPrivate(cacheControlConfig.isPrivate()); + } + + if (cacheControlConfig.isNoCache() != null) { + result.setNoCache(cacheControlConfig.isNoCache()); + } + + if (cacheControlConfig.isProxyRevalidate() != null) { + result.setProxyRevalidate(cacheControlConfig.isProxyRevalidate()); + } + + if (cacheControlConfig.isMustRevalidate() != null) { + result.setMustRevalidate(cacheControlConfig.isMustRevalidate()); + } + + if (cacheControlConfig.isNoStore() != null) { + result.setNoStore(cacheControlConfig.isNoStore()); + } + + if (cacheControlConfig.isNoTransform() != null) { + result.setNoTransform(cacheControlConfig.isNoTransform()); + } + + if (cacheControlConfig.getMaxAge() != null) { + result.setMaxAge(cacheControlConfig.getMaxAge().intValue()); + } + + if (cacheControlConfig.getSMaxAge() != null) { + result.setSMaxAge(cacheControlConfig.getSMaxAge().intValue()); + } } } catch (DocumentException e) { - logger.debug("Failed to retrieve cache-age-max from service bindings.", e); + result = null; + logger.debug(String.format("Failed to retrieve CacheControlConfig with key '%s' from service bindings '%s'.", cacheKey, ctx.getServiceName()), e); + } catch (NullPointerException npe) { + result = null; + // + // NPE might mean optional cache-control config is missing -that's usually ok. + logger.trace(npe.getLocalizedMessage(), npe); } - return result != null ? result.intValue() : 0; + return result; } protected Response.ResponseBuilder setCacheControl(ServiceContext ctx, Response.ResponseBuilder responseBuilder) { - int cacheMaxAge = getCacheMaxAge(ctx); + CacheControl cacheControl = getDefaultCacheControl(ctx); - if (cacheMaxAge > 0) { - CacheControl cacheControl = new CacheControl(); - cacheControl.setMaxAge(getCacheMaxAge(ctx)); + if (cacheControl != null) { responseBuilder.cacheControl(cacheControl); - logger.debug(String.format("Cache-max-age for service '%s' is set to '%d' in the service bindings for tenant ID='%s'.", - ctx.getServiceName(), cacheMaxAge, ctx.getTenantId())); + logger.debug(String.format("Setting default CacheControl for service '%s' responses from the service bindings for tenant ID='%s'.", + ctx.getServiceName(), ctx.getTenantId())); } return responseBuilder; diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java index 7d5d1810a..74e3bc8fb 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java @@ -34,6 +34,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.Request; import javax.ws.rs.core.UriInfo; import org.collectionspace.services.client.PayloadOutputPart; @@ -146,7 +147,7 @@ public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends Abstr */ @GET @Path(WorkflowClient.SERVICE_PATH) - public Lifecycle getWorkflow(@Context UriInfo uriInfo) { + public Lifecycle getWorkflow(@Context Request jaxRsRequest, @Context UriInfo uriInfo) { Lifecycle result; String documentType = "undefined"; diff --git a/services/common/src/main/java/org/collectionspace/services/common/NuxeoBasedResource.java b/services/common/src/main/java/org/collectionspace/services/common/NuxeoBasedResource.java index 14cc33603..37508b209 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/NuxeoBasedResource.java +++ b/services/common/src/main/java/org/collectionspace/services/common/NuxeoBasedResource.java @@ -331,28 +331,42 @@ public abstract class NuxeoBasedResource //======================= GET ==================================================== @GET @Path("{csid}") - public byte[] get( + public Response get( @Context Request request, @Context UriInfo uriInfo, @PathParam("csid") String csid) { uriInfo = new UriInfoWrapper(uriInfo); PoxPayloadOut result = null; - ensureCSID(csid, READ); + try { - RemoteServiceContext ctx = (RemoteServiceContext) createServiceContext(uriInfo); - result = get(csid, ctx);// ==> CALL implementation method, which subclasses may override. - if (result == null) { - Response response = Response.status(Response.Status.NOT_FOUND).entity( - ServiceMessages.READ_FAILED + ServiceMessages.resourceNotFoundMsg(csid)).type("text/plain").build(); - throw new CSWebApplicationException(response); - } + result = getResourceFromCsid(request, uriInfo, csid); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); } + + if (result == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + ServiceMessages.READ_FAILED + ServiceMessages.resourceNotFoundMsg(csid)).type("text/plain").build(); + throw new CSWebApplicationException(response); + } - return result.getBytes(); + return Response.ok(result.getBytes()).build(); } + public PoxPayloadOut getResourceFromCsid( + Request request, + UriInfo uriInfo, + String csid) throws Exception { + PoxPayloadOut result = null; + + ensureCSID(csid, READ); + RemoteServiceContext ctx = + (RemoteServiceContext) createServiceContext(request, uriInfo); + result = get(csid, ctx);// ==> CALL an implementation method, which subclasses may override. + + return result; + } + /** * Call this method only from other resources (like the Service Groups resource) obtained from the global resource map (ResourceMap). If the a parent * context exists and it has an open Nuxeo repository session, we will use it; otherwise, we will create a new one. diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMessages.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMessages.java index 3df268caf..630bff3c4 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMessages.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMessages.java @@ -33,28 +33,28 @@ package org.collectionspace.services.common; */ public class ServiceMessages { - private static final String FAILED = "failed: "; - private static final String UNSUPPORTED = "unsupported: "; + private static final String FAILED = " failed: "; + private static final String UNSUPPORTED = " unsupported: "; - public static final String POST_FAILED = "POST " + FAILED; - public static final String GET_FAILED = "GET " + FAILED; - public static final String PUT_FAILED = "PUT " + FAILED; + public static final String POST_FAILED = "POST request" + FAILED; + public static final String GET_FAILED = "GET request" + FAILED; + public static final String PUT_FAILED = "PUT request" + FAILED; - public static final String CREATE_FAILED = "Create request " + FAILED; - public static final String READ_FAILED = "Read request " + FAILED; - public static final String REINDEX_FAILED = "Reindex request " + FAILED; - public static final String UPDATE_FAILED = "Update request " + FAILED; + public static final String CREATE_FAILED = "Create request" + FAILED; + public static final String READ_FAILED = "Read request" + FAILED; + public static final String REINDEX_FAILED = "Reindex request" + FAILED; + public static final String UPDATE_FAILED = "Update request" + FAILED; - public static final String POST_UNSUPPORTED = "POST " + UNSUPPORTED; - public static final String GET_UNSUPPORTED = "GET " + UNSUPPORTED; - public static final String GET_LIST_UNSUPPORTED = "GET/LIST " + UNSUPPORTED; - public static final String PUT_UNSUPPORTED = "PUT " + UNSUPPORTED; - public static final String DELETE_UNSUPPORTED = "DELETE " + UNSUPPORTED; + public static final String POST_UNSUPPORTED = "POST request" + UNSUPPORTED; + public static final String GET_UNSUPPORTED = "GET request" + UNSUPPORTED; + public static final String GET_LIST_UNSUPPORTED = "GET/LIST request" + UNSUPPORTED; + public static final String PUT_UNSUPPORTED = "PUT request" + UNSUPPORTED; + public static final String DELETE_UNSUPPORTED = "DELETE request" + UNSUPPORTED; - public static final String DELETE_FAILED = "Delete request " + FAILED; - public static final String LIST_FAILED = "List request " + FAILED; - public static final String SEARCH_FAILED = "Search request " + FAILED; - public static final String AUTH_REFS_FAILED = "Authority references request " + FAILED; + public static final String DELETE_FAILED = "Delete request" + FAILED; + public static final String LIST_FAILED = "List request" + FAILED; + public static final String SEARCH_FAILED = "Search request" + FAILED; + public static final String AUTH_REFS_FAILED = "Authority references request" + FAILED; public static final String UNKNOWN_ERROR_MSG = "Unknown error "; public static final String VALIDATION_FAILURE = "Validation failure "; diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index d44059fdb..75af571d7 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Properties; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; import javax.ws.rs.core.UriInfo; import org.collectionspace.authentication.spi.AuthNContext; @@ -108,6 +109,8 @@ public abstract class AbstractServiceContextImpl private SecurityContext securityContext; /** The sessions JAX-RS URI information */ private UriInfo uriInfo; + /** The JAX-RS request information */ + private Request requestInfo; /** The current repository session */ private Object currentRepositorySession; /** A reference count for the current repository session */ @@ -843,6 +846,16 @@ public abstract class AbstractServiceContextImpl return this.uriInfo; } + @Override + public Request getRequestInfo() { + return this.requestInfo; + } + + @Override + public void setRequestInfo(Request requestInfo) { + this.requestInfo = requestInfo; + } + /* * We expect the 'currentRepositorySession' member to be set only once per instance. Also, we expect only one open repository session * per HTTP request. We'll log an error if we see more than one attempt to set a service context's current repo session. diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java index 206d7ef5a..5027ac75e 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java @@ -27,11 +27,10 @@ import java.util.List; import java.util.Map; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; import javax.ws.rs.core.UriInfo; import org.collectionspace.services.client.CollectionSpaceClient; -import org.collectionspace.services.client.PoxPayloadIn; -import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.CollectionSpaceResource; import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.document.DocumentHandler; @@ -255,6 +254,12 @@ public interface ServiceContext { * @param map the map of service names to resource instances. */ public void setResourceMap(ResourceMap map); + + /** + * + * @param jaxsRsRequest - Keep track of the JAX-RS request information + */ + public void setRequestInfo(Request jaxsRsRequest); /** * getPartsMetadata returns metadata for object parts used by the service @@ -395,6 +400,12 @@ public interface ServiceContext { * @return */ public boolean shouldForceSync(); + + /** + * + * @return The JAX-RS request information + */ + Request getRequestInfo(); } diff --git a/services/config/src/main/resources/service.xsd b/services/config/src/main/resources/service.xsd index ea6682df2..6d4659750 100644 --- a/services/config/src/main/resources/service.xsd +++ b/services/config/src/main/resources/service.xsd @@ -242,7 +242,13 @@ - + + + + + + + @@ -275,8 +281,19 @@ - - - + + + + + + + + + + + + + + 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 b82573f75..bc8de5746 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 @@ -54,6 +54,7 @@ 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.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; @@ -299,13 +300,15 @@ public class MediaResource extends NuxeoBasedResource { @GET @Path("{csid}/blob/content") public Response getBlobContent( - @PathParam("csid") String csid) { + @PathParam("csid") String csid, + @Context Request requestInfo, + @Context UriInfo uriInfo) { Response result = null; try { ensureCSID(csid, READ); String blobCsid = this.getBlobCsid(csid); - result = getBlobResource().getBlobContent(blobCsid); + result = getBlobResource().getBlobContent(blobCsid, requestInfo, uriInfo); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); } @@ -317,13 +320,15 @@ public class MediaResource extends NuxeoBasedResource { @Path("{csid}/blob/derivatives/{derivativeTerm}/content") public Response getDerivativeContent( @PathParam("csid") String csid, - @PathParam("derivativeTerm") String derivativeTerm) { + @PathParam("derivativeTerm") String derivativeTerm, + @Context Request requestInfo, + @Context UriInfo uriInfo) { Response result = null; try { ensureCSID(csid, READ); String blobCsid = this.getBlobCsid(csid); - result = getBlobResource().getDerivativeContent(blobCsid, derivativeTerm); + result = getBlobResource().getDerivativeContent(blobCsid, derivativeTerm, requestInfo, uriInfo); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); } -- 2.47.3