import org.collectionspace.services.common.publicitem.PublicItemUtil;
import org.collectionspace.services.nuxeo.client.java.CommonList;
import org.collectionspace.services.common.CSWebApplicationException;
-
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
@Consumes("application/xml")
@Produces("application/xml")
public class BlobResource extends NuxeoBasedResource {
+
+ private static final int DEFAULT_MAX_CACHE_AGE = 86400; // 1 day of seconds.
@Override
public String getServiceName(){
return response;
}
+ @Override
+ protected int getCacheMaxAge(ServiceContext ctx) {
+ int result = super.getCacheMaxAge(ctx);
+
+ if (result <= 0) {
+ result = this.DEFAULT_MAX_CACHE_AGE;
+ }
+
+ return result;
+ }
+
@GET
@Path("{csid}/content")
public Response getBlobContent( @PathParam("csid") String csid) {
InputStream contentStream = getBlobContent(ctx, csid, null /*derivative term*/, mimeType /*will get set*/);
Response.ResponseBuilder responseBuilder = Response.ok(contentStream, mimeType.toString());
+ setCacheControl(ctx, responseBuilder);
responseBuilder = responseBuilder.header("Content-Disposition","inline;filename=\""
+ blobsCommon.getName() +"\"");
result = responseBuilder.build();
} catch (Exception e) {
throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
}
-
+
return result;
}
StringBuffer mimeType = new StringBuffer();
InputStream contentStream = getBlobContent(ctx, csid, derivativeTerm, mimeType);
Response.ResponseBuilder responseBuilder = Response.ok(contentStream, mimeType.toString());
+ setCacheControl(ctx, responseBuilder);
responseBuilder = responseBuilder.header("Content-Disposition","inline;filename=\""
+ blobsCommon.getName() +"\"");
result = responseBuilder.build();
</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: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.GET;
import javax.ws.rs.Path;
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.Response;
import org.collectionspace.services.client.CollectionSpaceClient;
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.config.TenantBindingConfigReaderImpl;
-import org.collectionspace.services.common.context.MultipartServiceContext;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.context.ServiceContextProperties;
import org.collectionspace.services.common.document.BadRequestException;
import org.collectionspace.services.common.storage.StorageClient;
import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
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;
public ServiceDescription getDescription(@Context UriInfo uriInfo) {
ServiceDescription result = null;
- ServiceContext ctx = null;
+ ServiceContext<IT, OT> ctx = null;
try {
ctx = createServiceContext(uriInfo);
result = getDescription(ctx);
* @param ctx
* @return
*/
- public ServiceDescription getDescription(ServiceContext ctx) {
+ public ServiceDescription getDescription(ServiceContext<IT, OT> ctx) {
ServiceDescription result = new ServiceDescription();
result.setDocumentType(getDocType(ctx.getTenantId()));
public TenantBindingConfigReaderImpl getTenantBindingsReader() {
return ServiceMain.getInstance().getTenantBindingConfigReader();
}
-
+
+ /**
+ * Get max cache age for HTTP responses from the tenant's service bindings.
+ *
+ * @param ctx
+ * @return
+ */
+ protected int getCacheMaxAge(ServiceContext<IT, OT> ctx) {
+ BigInteger result = null;
+
+ try {
+ Params docHandlerParams = ServiceConfigUtils.getDocHandlerParams(ctx.getTenantId(), ctx.getServiceName());
+ if (docHandlerParams.getCacheMaxAge() != null) {
+ result = docHandlerParams.getCacheMaxAge();
+ }
+ } catch (DocumentException e) {
+ logger.debug("Failed to retrieve cache-age-max from service bindings.", e);
+ }
+
+ return result != null ? result.intValue() : 0;
+ }
+
+ protected Response.ResponseBuilder setCacheControl(ServiceContext<IT, OT> ctx, Response.ResponseBuilder responseBuilder) {
+ int cacheMaxAge = getCacheMaxAge(ctx);
+
+ if (cacheMaxAge > 0) {
+ CacheControl cacheControl = new CacheControl();
+ cacheControl.setMaxAge(getCacheMaxAge(ctx));
+ 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()));
+ }
+
+ return responseBuilder;
+ }
}
import java.util.ArrayList;
import java.util.List;
+import org.collectionspace.services.common.ServiceMain;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.document.DocumentException;
import org.collectionspace.services.common.document.DocumentHandler;
final static Logger logger = LoggerFactory.getLogger(ServiceConfigUtils.class);
+ public static DocHandlerParams.Params getDocHandlerParams(String tenantId, String serviceName) throws DocumentException {
+ TenantBindingConfigReaderImpl tReader =
+ ServiceMain.getInstance().getTenantBindingConfigReader();
+ TenantBindingType tenantBinding = tReader.getTenantBinding(tenantId);
+ if (tenantBinding == null) {
+ String msg = "No tenant binding found for tenantId=" + tenantId
+ + " while processing request for service= " + serviceName;
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ ServiceBindingType serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
+ DocHandlerParams dhb = serviceBinding.getDocHandlerParams();
+ if (dhb != null && dhb.getParams() != null) {
+ return dhb.getParams();
+ }
+
+ throw new DocumentException("No DocHandlerParams configured for: "
+ + serviceBinding.getName());
+ }
+
/*
* Returns the document handler parameters that were loaded at startup from the
* tenant bindings config file.
<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="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"/>