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