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.httpforwarding; 007 008import org.apache.camel.LoggingLevel; 009import org.apache.camel.builder.RouteBuilder; 010import org.fcrepo.camel.common.processor.AddBasicAuthProcessor; 011import org.apache.camel.support.builder.Namespaces; 012import org.fcrepo.camel.processor.EventProcessor; 013import org.slf4j.Logger; 014import org.springframework.beans.factory.annotation.Autowired; 015 016import static org.apache.camel.builder.PredicateBuilder.in; 017import static org.apache.camel.builder.PredicateBuilder.not; 018import static org.apache.camel.builder.PredicateBuilder.or; 019import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 020import static java.util.stream.Collectors.toList; 021import static org.fcrepo.camel.processor.ProcessorUtils.tokenizePropertyPlaceholder; 022 023import static org.apache.camel.Exchange.CONTENT_TYPE; 024import static org.apache.camel.Exchange.HTTP_METHOD; 025import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE; 026import static org.slf4j.LoggerFactory.getLogger; 027 028/** 029 * A content router for handling JMS events. 030 * 031 * @author Geoff Scholl 032 * @author Demian Katz 033 */ 034public class HttpRouter extends RouteBuilder { 035 036 private static final Logger LOGGER = getLogger(HttpRouter.class); 037 038 @Autowired 039 private FcrepoHttpForwardingConfig config; 040 041 /** 042 * Configure the message route workflow. 043 */ 044 public void configure() throws Exception { 045 046 final Namespaces ns = new Namespaces("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 047 ns.add("indexing", "http://fedora.info/definitions/v4/indexing#"); 048 ns.add("ldp", "http://www.w3.org/ns/ldp#"); 049 050 /* 051 * A generic error handler (specific to this RouteBuilder) 052 */ 053 onException(Exception.class) 054 .maximumRedeliveries(config.getMaxRedeliveries()) 055 .log("Index Routing Error: ${routeId}"); 056 057 /* 058 * route a message to the proper queue 059 */ 060 from(config.getInputStream()) 061 .routeId("FcrepoHttpRouter") 062 .process(new EventProcessor()) 063 .log(LoggingLevel.TRACE, "Received message from Fedora routing to index.http") 064 .to("direct:add.type.to.http.message"); 065 066 /* 067 * Handle re-index events 068 */ 069 from(config.getReindexStream()) 070 .routeId("FcrepoHttpReindex") 071 .to("direct:add.type.to.http.message"); 072 073 /* 074 * Add event type header to message; we want to use the header.org.fcrepo.jms.eventtype 075 * value when it is available. If it is unset, that likely indicates a reindex operation, 076 * in which case we should default to an Update. 077 */ 078 from("direct:add.type.to.http.message") 079 .routeId("FcrepoHttpAddType") 080 .choice() 081 .when(simple("${header.org.fcrepo.jms.eventtype}")) 082 .setHeader(FCREPO_EVENT_TYPE).simple("${header.org.fcrepo.jms.eventtype}") 083 .to("direct:send.to.http") 084 .otherwise() 085 .setHeader(FCREPO_EVENT_TYPE).constant("https://www.w3.org/ns/activitystreams#Update") 086 .to("direct:send.to.http"); 087 088 /* 089 * Forward message to Http 090 */ 091 from("direct:send.to.http").routeId("FcrepoHttpSend") 092 .filter(not(in(tokenizePropertyPlaceholder(getContext(), config.getFilterContainers(), ",").stream() 093 .map(uri -> or( 094 header(FCREPO_URI).startsWith(constant(uri + "/")), 095 header(FCREPO_URI).isEqualTo(constant(uri)))) 096 .collect(toList())))) 097 .log(LoggingLevel.INFO, LOGGER, "sending ${headers[CamelFcrepoUri]} to http endpoint...") 098 .to("mustache:org/fcrepo/camel/httpforwarding/httpMessage.mustache") 099 .setHeader(HTTP_METHOD).constant("POST") 100 .setHeader(CONTENT_TYPE).constant("application/json") 101 .process(new AddBasicAuthProcessor(config.getHttpAuthUsername(), config.getHttpAuthPassword())) 102 .to(config.getHttpBaseUrl().isEmpty() ? "direct:http.baseurl.missing" : config.getHttpBaseUrl()); 103 104 /* 105 * Stop the route if configuration is incomplete. 106 */ 107 from("direct:http.baseurl.missing") 108 .routeId("FcrepoHttpBaseUrlMissing") 109 .log(LoggingLevel.ERROR, LOGGER, "Cannot forward HTTP message because http.baseUrl property is empty.") 110 .stop(); 111 } 112}