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;
@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<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(uriInfo);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(request, uriInfo);
DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
Specifier spec = Specifier.getSpecifier(specifier, "getAuthority", "GET");
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;
}
/**
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;
}
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 {
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;
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.
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;
/*
* 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,
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<PoxPayloadIn, PoxPayloadOut> 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;
@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<PoxPayloadIn, PoxPayloadOut> ctx = null;
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> 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*/);
return result;
}
- private BlobsCommon getBlobsCommon(String csid) throws Exception {
+ private BlobsCommon getBlobsCommon(String csid) throws Exception {
BlobsCommon result = null;
ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
@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<PoxPayloadIn, PoxPayloadOut> 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=\""
} catch (Exception e) {
throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
}
-
+
return result;
}
</service:documentHandler>
<service:DocHandlerParams xmlns:service="http://collectionspace.org/services/config/service">
<service:params>
- <service:CacheMaxAge>86400</service:CacheMaxAge> <!-- By default, cache blobs for 1 full day -->
+ <service:CacheControlConfigElement> <!-- See service.xsd XML Schema definitation for all potential cache settings -->
+ <service:CacheControlConfigList>
+ <service:key>GET/blobs/*/content</service:key>
+ <service:maxAge>86401</service:maxAge> <!-- By default, cache blobs for 1 full day -->
+ </service:CacheControlConfigList>
+ <service:CacheControlConfigList>
+ <service:key>GET/blobs/*/derivatives/*/content</service:key>
+ <service:maxAge>86402</service:maxAge> <!-- By default, cache blobs for 1 full day -->
+ </service:CacheControlConfigList>
+ </service:CacheControlConfigElement>
<service:ListResultsFields>
<service:ListResultField>
<service:element>name</service:element>
*/
package org.collectionspace.services.common;
-import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
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;
return docHandler;
}
+ protected ServiceContext<IT, OT> createServiceContext(Request requestInfo, UriInfo uriInfo) throws Exception {
+ ServiceContext<IT, OT> result = this.createServiceContext(uriInfo);
+
+ result.setRequestInfo(requestInfo);
+
+ return result;
+ }
+
/**
* Creates the service context.
*
}
/**
- * 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<IT, OT> ctx) {
- BigInteger result = null;
+ private CacheControlConfig getCacheControl(CacheControlConfigElement element, String cacheKey) {
+ CacheControlConfig result = null;
+
+ List<CacheControlConfig> 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<IT, OT> 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<IT, OT> 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<IT, OT> 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;
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;
*/
@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";
//======================= 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<PoxPayloadIn, PoxPayloadOut> ctx = (RemoteServiceContext<PoxPayloadIn, PoxPayloadOut>) 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<PoxPayloadIn, PoxPayloadOut> ctx =
+ (RemoteServiceContext<PoxPayloadIn, PoxPayloadOut>) 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.
*/
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 ";
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;
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 */
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.
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;
* @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
* @return
*/
public boolean shouldForceSync();
+
+ /**
+ *
+ * @return The JAX-RS request information
+ */
+ Request getRequestInfo();
}
<xs:element name="params">
<xs:complexType>
<xs:sequence>
- <xs:element name="CacheMaxAge" type="xs:integer" minOccurs="0" maxOccurs="1" default="86400"/> <!-- default of 1 day -->
+ <xs:element name="CacheControlConfigElement" minOccurs="0" maxOccurs="1"> <!-- Create a cache control setting for a service's responses. You can have different ones for different responses. -->
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="CacheControlConfigList" type="CacheControlConfig" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
<xs:element name="SchemaName" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="RefnameDisplayNameField" type="ListResultField" minOccurs="0" maxOccurs="1"/> <!-- Should rename 'ListResultField' to a more generic name -->
<xs:element name="SupportsHierarchy" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/>
</xs:sequence>
</xs:complexType>
-
-
-
+ <xs:complexType name="CacheControlConfig">
+ <xs:sequence>
+ <xs:element name="key" type="xs:string" minOccurs="1" maxOccurs="1" default="default"/> <!-- The lookup name CSpace used to find these settings. Set to "default" by default, but pick a unique name among sibling items. -->
+ <xs:element name="private" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/> <!-- only clients (mostly the browser) and no one else in the chain (like a proxy) should cache this -->
+ <xs:element name="public" type="xs:boolean" minOccurs="0" maxOccurs="1" default="true"/> <!-- any entity in the chain can cache this -->
+ <xs:element name="noCache" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/> <!-- should not be cached in any way/method -->
+ <xs:element name="mustRevalidate" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/> <!-- See http://bit.ly/2mnCwIi -->
+ <xs:element name="proxyRevalidate" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/>
+ <xs:element name="noStore" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/> <!-- can be cached but should not be stored on disk (most browsers will hold the resources in memory until they will be quit) -->
+ <xs:element name="noTransform" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false"/> <!-- the resource should not be modified (for example shrink image by proxy) -->
+ <xs:element name="maxAge" type="xs:integer" minOccurs="0" maxOccurs="1" default="86400"/> <!-- how long the resource is valid (measured in seconds) -->
+ <xs:element name="sMaxAge" type="xs:integer" minOccurs="0" maxOccurs="1" default="-1"/> <!-- same like max-age but this value is just for non clients -->
+ </xs:sequence>
+ </xs:complexType>
</xs:schema>
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;
@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);
}
@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);
}