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