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.CamelContext; 009import org.apache.camel.Produce; 010import org.apache.camel.ProducerTemplate; 011import org.apache.camel.builder.AdviceWith; 012import org.apache.camel.builder.RouteBuilder; 013import org.apache.camel.component.mock.MockEndpoint; 014import org.apache.camel.model.ModelCamelContext; 015import org.apache.camel.spring.javaconfig.CamelConfiguration; 016import org.junit.BeforeClass; 017import org.junit.Test; 018import org.junit.runner.RunWith; 019import org.springframework.beans.factory.annotation.Autowired; 020import org.springframework.context.annotation.Bean; 021import org.springframework.context.annotation.ComponentScan; 022import org.springframework.context.annotation.Configuration; 023import org.springframework.test.annotation.DirtiesContext; 024import org.springframework.test.context.ContextConfiguration; 025import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 026import org.springframework.test.context.support.AnnotationConfigContextLoader; 027 028import java.util.HashMap; 029import java.util.List; 030import java.util.Map; 031 032import static java.util.Arrays.asList; 033import static java.util.Collections.emptyList; 034import static org.fcrepo.camel.FcrepoHeaders.FCREPO_AGENT; 035import static org.fcrepo.camel.FcrepoHeaders.FCREPO_DATE_TIME; 036import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE; 037import static org.fcrepo.camel.FcrepoHeaders.FCREPO_RESOURCE_TYPE; 038import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 039 040/** 041 * Test the route workflow. 042 * 043 * @author Aaron Coburn 044 * @author Demian Katz 045 * @since 2015-04-10 046 */ 047@RunWith(SpringJUnit4ClassRunner.class) 048@ContextConfiguration(classes = {RouteTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 049public class RouteTest { 050 private final String EVENT_NS = "https://www.w3.org/ns/activitystreams#"; 051 private static final String baseURL = "http://localhost/rest"; 052 private static final String httpURL = "http://localhost/http_endpoint"; 053 private static final String fileID = "/file1"; 054 private static final String eventDate = "2015-04-06T22:45:20Z"; 055 private static final String userID = "bypassAdmin"; 056 private static final String userAgent = "curl/7.37.1"; 057 private static final String auditContainer = "/audit"; 058 private static final String inputStream = "seda:foo"; 059 private static final String reindexStream = "seda:bar"; 060 061 @Autowired 062 private CamelContext camelContext; 063 064 @Produce("direct:start") 065 protected ProducerTemplate template; 066 067 @BeforeClass 068 public static void beforeClass() { 069 System.setProperty("http.enabled", "true"); 070 System.setProperty("http.filter.containers", baseURL + auditContainer); 071 System.setProperty("http.input.stream", inputStream); 072 System.setProperty("http.reindex.stream", reindexStream); 073 System.setProperty("error.maxRedeliveries", "10"); 074 System.setProperty("fcrepo.baseUrl", baseURL); 075 System.setProperty("http.baseUrl", httpURL); 076 System.setProperty("http.reindex.stream", "seda:reindex"); 077 } 078 079 @DirtiesContext 080 @Test 081 public void testEventTypeForwarding() throws Exception { 082 // Let's be sure "Delete" gets passed along as expected 083 final List<String> eventTypes = asList(EVENT_NS + "Delete"); 084 085 final var context = camelContext.adapt(ModelCamelContext.class); 086 AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> { 087 a.mockEndpointsAndSkip(httpURL); 088 }); 089 090 final var sendEndpoint = MockEndpoint.resolve(camelContext, "mock:http:localhost/http_endpoint"); 091 sendEndpoint.expectedMessageCount(1); 092 sendEndpoint.expectedHeaderReceived(FCREPO_EVENT_TYPE, "https://www.w3.org/ns/activitystreams#Delete"); 093 template.sendBodyAndHeaders(inputStream, "{}", 094 createEvent(baseURL + fileID, eventTypes)); 095 096 MockEndpoint.assertIsSatisfied(sendEndpoint); 097 } 098 099 @DirtiesContext 100 @Test 101 public void testEventTypeInjection() throws Exception { 102 // Let's make sure "Update" is the default when no event type is provided 103 final List<String> eventTypes = emptyList(); 104 105 final var context = camelContext.adapt(ModelCamelContext.class); 106 AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> { 107 a.mockEndpointsAndSkip(httpURL); 108 }); 109 110 final var sendEndpoint = MockEndpoint.resolve(camelContext, "mock:http:localhost/http_endpoint"); 111 sendEndpoint.expectedMessageCount(1); 112 // We expect "Update" as default if nothing is provided 113 sendEndpoint.expectedHeaderReceived(FCREPO_EVENT_TYPE, "https://www.w3.org/ns/activitystreams#Update"); 114 template.sendBodyAndHeaders(inputStream, "{}", 115 createEvent(baseURL + fileID, eventTypes)); 116 117 MockEndpoint.assertIsSatisfied(sendEndpoint); 118 } 119 120 private static Map<String, Object> createEvent(final String identifier, final List<String> eventTypes) { 121 return createEvent(identifier, eventTypes, emptyList()); 122 } 123 124 private static Map<String, Object> createEvent(final String identifier, final List<String> eventTypes, 125 final List<String> resourceTypes) { 126 final Map<String, Object> headers = new HashMap<>(); 127 headers.put(FCREPO_URI, identifier); 128 headers.put(FCREPO_DATE_TIME, eventDate); 129 headers.put(FCREPO_AGENT, asList(userID, userAgent)); 130 // The HttpRouter expects to find org.fcrepo.jms.eventtype and move it into 131 // FCREPO_EVENT_TYPE (or set a default) 132 if (eventTypes.size() > 0) { 133 headers.put("org.fcrepo.jms.eventtype", eventTypes.get(0)); 134 } 135 headers.put(FCREPO_RESOURCE_TYPE, resourceTypes); 136 return headers; 137 } 138 139 @Configuration 140 @ComponentScan(resourcePattern = "**/Fcrepo*.class") 141 static class ContextConfig extends CamelConfiguration { 142 143 @Bean 144 public RouteBuilder route() { 145 return new HttpRouter(); 146 } 147 } 148}