Commit 9f640725 authored by acoburn's avatar acoburn
Browse files

update interface for image extension

parent c0ece8c8
......@@ -4,15 +4,17 @@ Repository Image manipulation service
This comprises an image manipulation service used in combination with ImageMagick's `convert` utility.
This service assumes that ImageMagick is installed somewhere.
The endpoint location is configurable. Any path appended to that endpoint root will be used
as a path to a Fedora Resource. The `options` parameter can be used to add output parameters
The endpoint location is configurable. The `options` parameter can be used to add output parameters
to ImageMagick. The `Accept` header is used to change the format of the image. By default,
the output is JPEG, but any format listed in the configuration under `valid.formats` can be used.
By default, the valid output formats are `image/tiff`, `image/jp2` and `image/jpeg`.
A `context` parameter is used to define the path to the Fedora resource. Alternately, the
`Apix-Ldp-Resource-Path` header may be used to identify the resource path.
An example:
curl http://localhost:9081/image/path/to/binary?options=-resize%20400x400 -H"Accept: image/jpeg"
curl "http://localhost:9081/image?context=http://localhost:8080/fcrepo/rest/image/resource&options=-resize%20400x400" -H"Accept: image/jpeg"
The service is defined to operate on any `fedora:Binary` resources with a MIMEType of `image/*`.
......
......@@ -18,13 +18,13 @@ package edu.amherst.acdc.exts.image;
import static java.util.Arrays.stream;
import static org.apache.camel.Exchange.CONTENT_TYPE;
import static org.apache.camel.Exchange.HTTP_METHOD;
import static org.apache.camel.Exchange.HTTP_PATH;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
import static org.apache.camel.Exchange.HTTP_URI;
import static org.apache.camel.LoggingLevel.INFO;
import static org.apache.camel.builder.PredicateBuilder.and;
import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_ARGS;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.InputStream;
......@@ -37,7 +37,7 @@ import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
/**
* A content router for handling JMS events.
* A content router for handling image conversion requests.
*
* @author Aaron Coburn
*/
......@@ -47,6 +47,7 @@ public class EventRouter extends RouteBuilder {
private static final String IMAGE_INPUT = "CamelImageInput";
private static final String HTTP_ACCEPT = "Accept";
private static final String HTTP_QUERY_OPTIONS = "options";
private static final String HTTP_QUERY_CONTEXT = "context";
private static final Logger LOGGER = getLogger(EventRouter.class);
......@@ -56,58 +57,57 @@ public class EventRouter extends RouteBuilder {
public void configure() throws Exception {
from("jetty:http://{{rest.host}}:{{rest.port}}{{rest.prefix}}?" +
"matchOnUriPrefix=true&sendServerVersion=false&httpMethodRestrict=GET,OPTIONS")
.routeId("ImageRouter")
.process(e -> e.getIn().setHeader(FCREPO_IDENTIFIER,
e.getIn().getHeader("Apix-Ldp-Resource-Path",
e.getIn().getHeader(HTTP_PATH))))
"sendServerVersion=false&" +
"httpMethodRestrict=GET,OPTIONS").routeId("ImageRouter")
.process(e -> e.getIn().setHeader(FCREPO_URI,
e.getIn().getHeader(HTTP_QUERY_CONTEXT,
e.getIn().getHeader("Apix-Ldp-Resource-Path"))))
.setHeader(FCREPO_BASE_URL).simple("{{fcrepo.baseUrl}}")
.setHeader(IMAGE_OUTPUT).header(HTTP_ACCEPT)
.removeHeaders(HTTP_ACCEPT)
.choice()
.when(header(HTTP_METHOD).isEqualTo("GET"))
.when(and(header(HTTP_METHOD).isEqualTo("GET"), header(FCREPO_URI).startsWith(header(FCREPO_BASE_URL))))
.to("direct:get")
.when(header(HTTP_METHOD).isEqualTo("OPTIONS"))
.setHeader(CONTENT_TYPE).constant("text/turtle")
.setHeader(HTTP_ACCEPT).constant("GET,OPTIONS")
.to("language:simple:resource:classpath:options.ttl");
.to("language:simple:resource:classpath:options.ttl")
.otherwise()
.setHeader(HTTP_RESPONSE_CODE).constant(400)
.setHeader(CONTENT_TYPE).constant("text/plain")
.transform(constant("Missing/invalid context parameter"));
from("direct:get")
.routeId("ImageGet")
.setHeader(HTTP_PATH, header(FCREPO_IDENTIFIER))
from("direct:get").routeId("ImageGet")
.setHeader(HTTP_URI).header(FCREPO_URI)
.setHeader(HTTP_METHOD).constant("HEAD")
.setHeader(HTTP_URI).simple("http://{{fcrepo.baseUrl}}")
.to("http4://{{fcrepo.baseUrl}}?authUsername={{fcrepo.authUsername}}" +
.to("http4://localhost?authUsername={{fcrepo.authUsername}}" +
"&authPassword={{fcrepo.authPassword}}&throwExceptionOnFailure=false")
.choice()
.when(and(header(CONTENT_TYPE).startsWith("image/"),
header("Link").contains("<http://www.w3.org/ns/ldp#NonRDFSource>;rel=\"type\"")))
.when(header(CONTENT_TYPE).startsWith("image/"))
.log(INFO, LOGGER, "Image Processing ${headers[CamelHttpPath]}")
.to("direct:convert")
.when(header("Link").contains("<http://www.w3.org/ns/ldp#NonRDFSource>;rel=\"type\""))
.setBody(constant("Error: this resource is not an image"))
.to("direct:invalidFormat")
.when(header(HTTP_RESPONSE_CODE).isEqualTo(200))
.setBody(constant("Error: this resource is not a fedora:Binary"))
.setBody(constant("Error: this resource is not an ldp:NonRDFSource"))
.to("direct:invalidFormat")
.otherwise()
.to("direct:error");
from("direct:invalidFormat")
.routeId("ImageInvalidFormat")
from("direct:invalidFormat").routeId("ImageInvalidFormat")
.removeHeaders("*")
.setHeader(CONTENT_TYPE).constant("text/plain")
.setHeader(HTTP_RESPONSE_CODE).constant(400);
from("direct:error")
.routeId("ImageError")
from("direct:error").routeId("ImageError")
.setBody(constant("Error: this resource is not accessible"))
.setHeader(CONTENT_TYPE).constant("text/plain");
from("direct:convert")
.routeId("ImageConvert")
from("direct:convert").routeId("ImageConvert")
.setHeader(HTTP_METHOD).constant("GET")
.setHeader(HTTP_PATH).header(FCREPO_IDENTIFIER)
.to("http4://{{fcrepo.baseUrl}}?authUsername={{fcrepo.authUsername}}" +
.setHeader(HTTP_URI).header(FCREPO_URI)
.to("http4://localhost?authUsername={{fcrepo.authUsername}}" +
"&authPassword={{fcrepo.authPassword}}&throwExceptionOnFailure=true")
.setHeader(IMAGE_INPUT).header(CONTENT_TYPE)
.process(exchange -> {
......@@ -137,9 +137,8 @@ public class EventRouter extends RouteBuilder {
.removeHeaders("CamelHttp*")
.log(INFO, LOGGER, "Converting from ${headers[CamelImageInput]} to ${headers[CamelImageOutput]}")
.to("exec:{{convert.path}}")
.process(exchange -> {
exchange.getOut().setBody(exchange.getIn().getBody(InputStream.class));
});
.process(exchange ->
exchange.getOut().setBody(exchange.getIn().getBody(InputStream.class)));
}
// Hack - cmdline options are often an array of repeated elements. Fix that
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment