001/* 002 * Copyright 2016 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 RESOURCE_DELETION = "http://fedora.info/definitions/v4/event#ResourceDeletion"; 048 049 private static final String isBinaryResourceXPath = 050 "/rdf:RDF/rdf:Description/rdf:type[@rdf:resource=\"" + REPOSITORY + "Binary\"]"; 051 /** 052 * Configure the message route workflow 053 * 054 */ 055 056 public void configure() throws Exception { 057 058 final Namespaces ns = new Namespaces("rdf", RDF).add("fedora", REPOSITORY); 059 060 /** 061 * A generic error handler (specific to this RouteBuilder) 062 */ 063 onException(Exception.class) 064 .maximumRedeliveries("{{error.maxRedeliveries}}") 065 .log("Index Routing Error: ${routeId}"); 066 067 /** 068 * Handle Serialization Events 069 */ 070 from("{{input.stream}}") 071 .routeId("FcrepoSerialization") 072 .setHeader(FCREPO_IDENTIFIER).header(IDENTIFIER) 073 .filter(not(or(header(FCREPO_IDENTIFIER).startsWith(simple("{{audit.container}}/")), 074 header(FCREPO_IDENTIFIER).isEqualTo(simple("{{audit.container}}"))))) 075 .choice() 076 // this clause supports Fedora 4.5.1 and earlier but may be removed in a future release 077 .when(header(EVENT_TYPE).isEqualTo(REPOSITORY + "NODE_REMOVED")) 078 .to("direct:delete") 079 .when(header(EVENT_TYPE).isEqualTo(RESOURCE_DELETION)) 080 .to("direct:delete") 081 .otherwise() 082 .multicast().to("direct:metadata", "direct:binary"); 083 084 from("{{serialization.stream}}") 085 .routeId("FcrepoReSerialization") 086 .filter(not(or(header(FCREPO_IDENTIFIER).startsWith(simple("{{audit.container}}/")), 087 header(FCREPO_IDENTIFIER).isEqualTo(simple("{{audit.container}}"))))) 088 .multicast().to("direct:metadata", "direct:binary"); 089 090 from("direct:metadata") 091 .routeId("FcrepoSerializationMetadataUpdater") 092 .to("fcrepo:{{fcrepo.baseUrl}}?accept={{serialization.mimeType}}") 093 .log(INFO, LOGGER, 094 "Serializing object ${headers[CamelFcrepoIdentifier]}") 095 .setHeader(FILE_NAME) 096 .simple("${headers[CamelFcrepoIdentifier]}.{{serialization.extension}}") 097 .log(DEBUG, LOGGER, "filename is ${headers[CamelFileName]}") 098 .to("file://{{serialization.descriptions}}"); 099 100 from("direct:binary") 101 .routeId("FcrepoSerializationBinaryUpdater") 102 .filter().simple("{{serialization.includeBinaries}} == 'true'") 103 .to("fcrepo:{{fcrepo.baseUrl}}?preferInclude=PreferMinimalContainer" + 104 "&accept=application/rdf+xml") 105 .filter().xpath(isBinaryResourceXPath, ns) 106 .log(INFO, LOGGER, "Writing binary ${headers[CamelFcrepoIdentifier]}") 107 .to("fcrepo:{{fcrepo.baseUrl}}?metadata=false") 108 .setHeader(FILE_NAME).header(FCREPO_IDENTIFIER) 109 .log(DEBUG, LOGGER, "header filename is: ${headers[CamelFileName]}") 110 .to("file://{{serialization.binaries}}"); 111 112 from("direct:delete") 113 .routeId("FcrepoSerializationDeleter") 114 .setHeader(EXEC_COMMAND_ARGS).simple( 115 "-rf {{serialization.descriptions}}${headers[CamelFcrepoIdentifier]}.{{serialization.extension}} " + 116 "{{serialization.descriptions}}${headers[CamelFcrepoIdentifier]} " + 117 "{{serialization.binaries}}${headers[CamelFcrepoIdentifier]}") 118 .to("exec:rm"); 119 } 120}