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.reindexing;
019
020import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
021import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_RECIPIENTS;
022
023import java.net.InetAddress;
024import java.util.HashMap;
025import java.util.Map;
026import java.util.Properties;
027
028import org.apache.camel.EndpointInject;
029import org.apache.camel.Produce;
030import org.apache.camel.ProducerTemplate;
031import org.apache.camel.builder.AdviceWithRouteBuilder;
032import org.apache.camel.component.mock.MockEndpoint;
033import org.apache.camel.model.TransformDefinition;
034import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
035import org.apache.camel.util.ObjectHelper;
036
037import org.junit.Test;
038
039/**
040 * Test the route workflow.
041 *
042 * @author acoburn
043 * @since 2015-05-22
044 */
045public class RouteTest extends CamelBlueprintTestSupport {
046
047    private static final String restPrefix = "/reindexing";
048    private static final String reindexingStream = "broker:queue:foo";
049    private static final String baseUrl = "http://localhost/rest";
050
051    @EndpointInject(uri = "mock:result")
052    protected MockEndpoint resultEndpoint;
053
054    @Produce(uri = "direct:start")
055    protected ProducerTemplate template;
056
057    @Override
058    public boolean isUseAdviceWith() {
059        return true;
060    }
061
062    @Override
063    public boolean isUseRouteBuilder() {
064        return false;
065    }
066
067    @Override
068    protected String getBlueprintDescriptor() {
069        return "/OSGI-INF/blueprint/blueprint-test.xml";
070    }
071
072    @Override
073    protected Properties useOverridePropertiesWithPropertiesComponent() {
074
075        final String restPort = System.getProperty("fcrepo.dynamic.reindexing.port", "9080");
076
077        final Properties props = new Properties();
078        props.put("reindexing.stream", reindexingStream);
079        props.put("rest.prefix", restPrefix);
080        props.put("rest.port", restPort);
081        return props;
082    }
083
084    @Test
085    public void testUsageRoute() throws Exception {
086
087        final String restPort = System.getProperty("fcrepo.dynamic.reindexing.port", "9080");
088
089        context.getRouteDefinition("FcrepoReindexingTraverse").adviceWith(context, new AdviceWithRouteBuilder() {
090            @Override
091            public void configure() throws Exception {
092                replaceFromWith("direct:traverse");
093                mockEndpointsAndSkip("broker:*");
094                mockEndpointsAndSkip("fcrepo:*");
095            }
096        });
097        context.getRouteDefinition("FcrepoReindexingUsage").adviceWith(context, new AdviceWithRouteBuilder() {
098            @Override
099            public void configure() throws Exception {
100                weaveAddLast().to("mock:result");
101            }
102        });
103
104        context.start();
105
106        getMockEndpoint("mock:result").expectedMessageCount(1);
107        getMockEndpoint("mock:result").message(0).body().contains("Fedora Reindexing Service");
108        getMockEndpoint("mock:result").message(0).body().contains(
109                InetAddress.getLocalHost().getHostName() + ":" + restPort + restPrefix);
110
111        template.sendBody("direct:usage", null);
112
113        assertMockEndpointsSatisfied();
114    }
115
116
117    @Test
118    public void testReindexNoEndpointsRoute() throws Exception {
119        final String url = "http://localhost:8080/fcrepo/rest/foo";
120
121        context.getRouteDefinition("FcrepoReindexingReindex").adviceWith(context, new AdviceWithRouteBuilder() {
122            @Override
123            public void configure() throws Exception {
124                mockEndpointsAndSkip(reindexingStream + "?disableTimeToLive=true");
125                weaveByType(TransformDefinition.class).after().to("mock:result");
126            }
127        });
128        context.getRouteDefinition("FcrepoReindexingTraverse").adviceWith(context, new AdviceWithRouteBuilder() {
129            @Override
130            public void configure() throws Exception {
131                replaceFromWith("direct:traverse");
132                mockEndpointsAndSkip("broker:*");
133                mockEndpointsAndSkip("fcrepo:*");
134            }
135        });
136        context.start();
137
138        getMockEndpoint("mock:" + reindexingStream).expectedMessageCount(0);
139        getMockEndpoint("mock:result").expectedMessageCount(1);
140        getMockEndpoint("mock:result").expectedHeaderReceived(FCREPO_URI, url);
141        getMockEndpoint("mock:result").expectedBodiesReceived("No endpoints configured for indexing");
142
143
144        final Map<String, Object> headers = new HashMap<>();
145        headers.put(FCREPO_URI, url);
146        headers.put(REINDEXING_RECIPIENTS, "");
147
148        template.sendBodyAndHeaders("direct:reindex", null, headers);
149
150        assertMockEndpointsSatisfied();
151    }
152
153    @Test
154    public void testReindexWithEndpointsRoute() throws Exception {
155        final String url = "http://localhost:8080/fcrepo/rest/foo";
156
157        context.getRouteDefinition("FcrepoReindexingReindex").adviceWith(context, new AdviceWithRouteBuilder() {
158            @Override
159            public void configure() throws Exception {
160                mockEndpointsAndSkip(reindexingStream + "?disableTimeToLive=true");
161                weaveByType(TransformDefinition.class).after().to("mock:result");
162            }
163        });
164        context.getRouteDefinition("FcrepoReindexingTraverse").adviceWith(context, new AdviceWithRouteBuilder() {
165            @Override
166            public void configure() throws Exception {
167                replaceFromWith("direct:traverse");
168                mockEndpointsAndSkip("broker:*");
169                mockEndpointsAndSkip("fcrepo:*");
170            }
171        });
172        context.start();
173
174        getMockEndpoint("mock:" + reindexingStream).expectedMessageCount(1);
175        getMockEndpoint("mock:result").expectedMessageCount(1);
176        getMockEndpoint("mock:result").expectedHeaderReceived(FCREPO_URI, url);
177        getMockEndpoint("mock:result").expectedBodiesReceived("Indexing started at " + url);
178
179        final Map<String, Object> headers = new HashMap<>();
180        headers.put(FCREPO_URI, url);
181        headers.put(REINDEXING_RECIPIENTS, "mock:endpoint");
182
183        template.sendBodyAndHeaders("direct:reindex", null, headers);
184
185        assertMockEndpointsSatisfied();
186    }
187
188    @Test
189    public void testTraversal() throws Exception {
190
191        final String baseUrl = "http://localhost:8080/fcrepo4/rest";
192
193        getMockEndpoint("mock:direct:recipients").expectedMessageCount(1);
194        getMockEndpoint("mock:" + reindexingStream).expectedMessageCount(7);
195        getMockEndpoint("mock:" + reindexingStream).expectedHeaderValuesReceivedInAnyOrder(FCREPO_URI,
196                baseUrl + "/foo/a", baseUrl + "/foo/b", baseUrl + "/foo/c", baseUrl + "/foo/d", baseUrl + "/foo/e",
197                baseUrl + "/foo/f", baseUrl + "/foo/g");
198
199        context.getRouteDefinition("FcrepoReindexingTraverse").adviceWith(context, new AdviceWithRouteBuilder() {
200            @Override
201            public void configure() throws Exception {
202                replaceFromWith("direct:traverse");
203                mockEndpointsAndSkip("fcrepo:*");
204                mockEndpointsAndSkip(reindexingStream + "*");
205                mockEndpointsAndSkip("direct:recipients");
206            }
207        });
208        context.start();
209
210        template.sendBodyAndHeader("direct:traverse", ObjectHelper.loadResourceAsStream("indexable.nt"),
211                FCREPO_URI, "http://localhost:8080/fcrepo4/rest/foo");
212
213        assertMockEndpointsSatisfied();
214    }
215
216    @Test
217    public void testRecipientList() throws Exception {
218        final String id = "/foo";
219
220        context.getRouteDefinition("FcrepoReindexingTraverse").adviceWith(context, new AdviceWithRouteBuilder() {
221            @Override
222            public void configure() throws Exception {
223                replaceFromWith("direct:traverse");
224                mockEndpointsAndSkip("broker:*");
225                mockEndpointsAndSkip("fcrepo:*");
226            }
227        });
228        context.start();
229
230        getMockEndpoint("mock:foo").expectedMessageCount(1);
231        getMockEndpoint("mock:foo").expectedHeaderReceived(FCREPO_URI, baseUrl + id);
232        getMockEndpoint("mock:bar").expectedMessageCount(1);
233        getMockEndpoint("mock:bar").expectedHeaderReceived(FCREPO_URI, baseUrl + id);
234
235        final Map<String, Object> headers = new HashMap<>();
236        headers.put(FCREPO_URI, baseUrl + id);
237        headers.put(REINDEXING_RECIPIENTS, "mock:foo,mock:bar");
238
239        template.sendBodyAndHeaders("direct:recipients", null, headers);
240
241        assertMockEndpointsSatisfied();
242    }
243}