001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.camel.ldpath;
007
008import static java.lang.String.format;
009import static org.apache.camel.builder.PredicateBuilder.and;
010import static org.apache.camel.builder.PredicateBuilder.not;
011import static org.apache.camel.model.dataformat.JsonLibrary.Jackson;
012import static org.apache.camel.Exchange.CONTENT_TYPE;
013import static org.apache.camel.Exchange.HTTP_METHOD;
014import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
015import static org.apache.camel.Exchange.HTTP_URI;
016import static org.slf4j.LoggerFactory.getLogger;
017
018import org.apache.camel.builder.RouteBuilder;
019import org.apache.camel.support.builder.ExpressionBuilder;
020import org.slf4j.Logger;
021import org.springframework.beans.factory.annotation.Autowired;
022
023/**
024 * A content router for an LDPath service.
025 *
026 * @author Aaron Coburn
027 * @since Aug 5, 2016
028 */
029
030public class LDPathRouter extends RouteBuilder {
031
032    private static final Logger LOGGER = getLogger(LDPathRouter.class);
033
034    @Autowired
035    private LDPathWrapper ldpathWrapper;
036
037    @Autowired
038    private FcrepoLdPathConfig config;
039    /**
040     * Configure the message route workflow.
041     */
042    public void configure() throws Exception {
043
044        /**
045         * Expose a RESTful endpoint for LDPath processing
046         */
047        from(format("jetty:http://%s:%d%s?" +
048                "httpMethodRestrict=GET,POST,OPTIONS" +
049                "&sendServerVersion=false", config.getRestHost(), config.getRestPort(),config.getRestPrefix()))
050            .routeId("FcrepoLDPathRest")
051            .routeDescription("Expose the ldpath endpoint over HTTP")
052            .choice()
053                .when(header(HTTP_METHOD).isEqualTo("OPTIONS"))
054                    .setHeader(CONTENT_TYPE).constant("text/turtle")
055                    .setHeader("Allow").constant("GET,POST,OPTIONS")
056                    .to("language:simple:resource:classpath:org/fcrepo/camel/ldpath/options.ttl")
057                // make sure the required context parameter is present
058                .when(not(and(header("context").isNotNull(), header("context").regex("^https?://.+"))))
059                    .setHeader(HTTP_RESPONSE_CODE).constant(400)
060                    .setHeader(CONTENT_TYPE).constant("text/plain")
061                    .transform(constant("Missing context parameter"))
062                .when(header(HTTP_METHOD).isEqualTo("GET"))
063                    .to("direct:get")
064                .when(header(HTTP_METHOD).isEqualTo("POST"))
065                    .to("direct:ldpathPrepare");
066
067
068        from("direct:get")
069            .routeId("FcrepoLDPathGet")
070            .choice()
071                .when(and(header("ldpath").isNotNull(), header("ldpath").regex("^https?://.*")))
072                    .removeHeaders("CamelHttp*")
073                    .setHeader(HTTP_URI).header("ldpath")
074                    .to("http://localhost?useSystemProperties=true")
075                    .to("direct:ldpathPrepare")
076                .otherwise()
077                    .to("language:simple:resource:" + config.getLdpathTransformPath())
078                    .to("direct:ldpathPrepare");
079
080        from("direct:ldpathPrepare").routeId("FcrepoLDPathPrepare")
081            .to("direct:ldpath")
082            .to("direct:format");
083
084        from("direct:format").routeId("FcrepoLDPathFormat")
085            .marshal().json(Jackson)
086            .removeHeaders("*")
087            .setHeader(CONTENT_TYPE).constant("application/json");
088
089        from("direct:ldpath")
090                .setBody(ExpressionBuilder.beanExpression(ldpathWrapper,
091                        "programQuery(${headers.context}, ${body})"));
092    }
093}