001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.camel.serialization;
017
018import static org.apache.camel.LoggingLevel.INFO;
019import static org.apache.camel.LoggingLevel.DEBUG;
020import static org.apache.camel.Exchange.FILE_NAME;
021import static org.apache.camel.builder.PredicateBuilder.not;
022import static org.apache.camel.builder.PredicateBuilder.or;
023import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_ARGS;
024import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER;
025import static org.fcrepo.camel.JmsHeaders.EVENT_TYPE;
026import static org.fcrepo.camel.JmsHeaders.IDENTIFIER;
027import static org.fcrepo.camel.RdfNamespaces.RDF;
028import static org.fcrepo.camel.RdfNamespaces.REPOSITORY;
029
030import org.apache.camel.builder.RouteBuilder;
031import org.apache.camel.builder.xml.Namespaces;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034
035/**
036 *
037 * A router for serializing fedora objects and binaries.
038 *
039 * @author Bethany Seeger
040 * @since 2015-09-28
041 */
042
043public class SerializationRouter extends RouteBuilder {
044
045    private static final Logger LOGGER = LoggerFactory.getLogger(SerializationRouter.class);
046
047    private static final String isBinaryResourceXPath =
048        "/rdf:RDF/rdf:Description/rdf:type[@rdf:resource=\"" + REPOSITORY + "Binary\"]";
049    /**
050     * Configure the message route workflow
051     *
052     */
053
054    public void configure() throws Exception {
055
056        final Namespaces ns = new Namespaces("rdf", RDF).add("fedora", REPOSITORY);
057
058        /**
059         * A generic error handler (specific to this RouteBuilder)
060         */
061        onException(Exception.class)
062                .maximumRedeliveries("{{error.maxRedeliveries}}")
063                .log("Index Routing Error: ${routeId}");
064
065        /**
066         * Handle Serialization Events
067         */
068        from("{{input.stream}}")
069            .routeId("FcrepoSerialization")
070            .setHeader(FCREPO_IDENTIFIER).header(IDENTIFIER)
071            .filter(not(or(header(FCREPO_IDENTIFIER).startsWith(simple("{{audit.container}}/")),
072                    header(FCREPO_IDENTIFIER).isEqualTo(simple("{{audit.container}}")))))
073            .choice()
074                .when(header(EVENT_TYPE).isEqualTo(REPOSITORY + "NODE_REMOVED"))
075                      .to("direct:delete").endChoice()
076                .otherwise()
077                    .multicast().to("direct:metadata", "direct:binary");
078
079        from("{{serialization.stream}}")
080            .routeId("FcrepoReSerialization")
081            .filter(not(or(header(FCREPO_IDENTIFIER).startsWith(simple("{{audit.container}}/")),
082                    header(FCREPO_IDENTIFIER).isEqualTo(simple("{{audit.container}}")))))
083            .multicast().to("direct:metadata", "direct:binary");
084
085        from("direct:metadata")
086            .routeId("FcrepoSerializationMetadataUpdater")
087            .to("fcrepo:{{fcrepo.baseUrl}}?accept={{serialization.mimeType}}")
088            .log(INFO, LOGGER,
089                    "Serializing object ${headers[CamelFcrepoIdentifier]}")
090            .setHeader(FILE_NAME)
091                .simple("${headers[CamelFcrepoIdentifier]}.{{serialization.extension}}")
092            .log(DEBUG, LOGGER, "filename is ${headers[CamelFileName]}")
093            .to("file://{{serialization.descriptions}}");
094
095        from("direct:binary")
096            .routeId("FcrepoSerializationBinaryUpdater")
097            .filter().simple("{{serialization.includeBinaries}} == 'true'")
098            .to("fcrepo:{{fcrepo.baseUrl}}?preferInclude=PreferMinimalContainer" +
099                    "&accept=application/rdf+xml")
100            .filter().xpath(isBinaryResourceXPath, ns)
101            .log(INFO, LOGGER, "Writing binary ${headers[CamelFcrepoIdentifier]}")
102            .to("fcrepo:{{fcrepo.baseUrl}}?metadata=false")
103            .setHeader(FILE_NAME).header(FCREPO_IDENTIFIER)
104            .log(DEBUG, LOGGER, "header filename is: ${headers[CamelFileName]}")
105            .to("file://{{serialization.binaries}}");
106
107        from("direct:delete")
108            .routeId("FcrepoSerializationDeleter")
109            .setHeader(EXEC_COMMAND_ARGS).simple(
110                    "-rf {{serialization.descriptions}}${headers[CamelFcrepoIdentifier]}.{{serialization.extension}} " +
111                    "{{serialization.descriptions}}${headers[CamelFcrepoIdentifier]} " +
112                    "{{serialization.binaries}}${headers[CamelFcrepoIdentifier]}")
113            .to("exec:rm");
114    }
115}