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.ldpath;
007
008import com.fasterxml.jackson.databind.ObjectMapper;
009import org.apache.camel.CamelContext;
010import org.apache.camel.EndpointInject;
011import org.apache.camel.Produce;
012import org.apache.camel.ProducerTemplate;
013import org.apache.camel.builder.AdviceWith;
014import org.apache.camel.component.mock.MockEndpoint;
015import org.apache.camel.model.ModelCamelContext;
016import org.apache.camel.spring.javaconfig.CamelConfiguration;
017import org.apache.commons.io.FileUtils;
018import org.junit.AfterClass;
019import org.junit.BeforeClass;
020import org.junit.Test;
021import org.junit.runner.RunWith;
022import org.springframework.beans.factory.annotation.Autowired;
023import org.springframework.context.annotation.ComponentScan;
024import org.springframework.context.annotation.Configuration;
025import org.springframework.test.context.ContextConfiguration;
026import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
027import org.springframework.test.context.support.AnnotationConfigContextLoader;
028
029import java.io.File;
030import java.util.HashMap;
031import java.util.List;
032import java.util.Map;
033
034import static org.apache.camel.Exchange.CONTENT_TYPE;
035import static org.apache.camel.Exchange.HTTP_METHOD;
036import static org.apache.camel.Exchange.HTTP_URI;
037import static org.apache.camel.util.ObjectHelper.loadResourceAsStream;
038import static org.junit.Assert.assertFalse;
039import static org.junit.Assert.assertTrue;
040
041/**
042 * Test the route workflow with functions enabled.
043 *
044 * @author Peter Eichman
045 * @since May 11, 2018
046 */
047@RunWith(SpringJUnit4ClassRunner.class)
048@ContextConfiguration(classes = {RouteWithFunctionsTest.ContextConfig.class},
049        loader = AnnotationConfigContextLoader.class)
050public class RouteWithFunctionsTest {
051
052    private final ObjectMapper MAPPER = new ObjectMapper();
053
054    @EndpointInject("mock:http:localhost")
055    protected MockEndpoint httpEndpoint;
056
057    @EndpointInject("mock:language:simple:resource:classpath:org/fcrepo/camel/ldpath/options.ttl")
058    protected MockEndpoint optionsEndpoint;
059
060    @Produce("direct:start")
061    protected ProducerTemplate template;
062
063    @Autowired
064    protected CamelContext camelContext;
065
066    @BeforeClass
067    public static void beforeClass() {
068        final String targetDir = System.getProperty("project.build.directory", "target");
069        final var ldCacheDir = targetDir + File.separator + RouteWithFunctionsTest.class.getCanonicalName() +
070                File.separator + "ldcache";
071        new File(ldCacheDir).mkdirs();
072
073        System.setProperty("ldpath.ldcache.directory", ldCacheDir);
074        final String restPort = System.getProperty("fcrepo.dynamic.ldpath.port", "9085");
075        System.setProperty("ldpath.rest.port", restPort);
076        System.setProperty("ldpath.rest.host", "0.0.0.0");
077
078    }
079
080    @AfterClass
081    public static void afterClass() {
082        FileUtils.deleteQuietly(new File(System.getProperty("ldpath.ldcache.directory")));
083    }
084
085    @Test
086    public void testGetDefault() throws Exception {
087        final String uri = "http://fedora.info/definitions/v4/event#ResourceCreation";
088        final String endpoint = "mock:resultGet";
089        final MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint(endpoint);
090        mockEndpoint.expectedMessageCount(1);
091        mockEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/json");
092
093        final var context = camelContext.adapt(ModelCamelContext.class);
094        AdviceWith.adviceWith(context, "FcrepoLDPathGet", a -> {
095            a.weaveAddLast().to(endpoint);
096        });
097
098        template.sendBodyAndHeader("direct:get", null, "context", uri);
099
100        mockEndpoint.assertIsSatisfied();
101        final String result = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class);
102
103        @SuppressWarnings("unchecked")
104        final List<Map<String, List<String>>> data = MAPPER.readValue(result, List.class);
105
106        assertFalse(data.isEmpty());
107        assertTrue(data.get(0).containsKey("label"));
108        assertTrue(data.get(0).containsKey("type_ss"));
109
110        assertTrue(data.get(0).get("id").contains(uri));
111        assertTrue(data.get(0).get("label").contains("resource creation"));
112        assertTrue(data.get(0).get("type_ss").contains("http://www.w3.org/2000/01/rdf-schema#Class"));
113    }
114
115    @Test
116    public void testOptions() throws Exception {
117       optionsEndpoint.expectedMessageCount(1);
118
119        final var context = camelContext.adapt(ModelCamelContext.class);
120        AdviceWith.adviceWith(context, "FcrepoLDPathRest", a -> {
121            a.replaceFromWith("direct:start");
122            a.mockEndpointsAndSkip("language:simple:resource:classpath:org/fcrepo/camel/ldpath/options.ttl");
123        });
124
125        template.sendBodyAndHeader(null, HTTP_METHOD, "OPTIONS");
126        optionsEndpoint.assertIsSatisfied();
127    }
128
129    @Test
130    public void testGetParam() throws Exception {
131        final String uri = "http://fedora.info/definitions/v4/repository#Binary";
132        final String endpoint = "mock:resultGetParam";
133        final MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint(endpoint);
134        httpEndpoint.expectedMessageCount(1);
135        httpEndpoint.expectedHeaderReceived(HTTP_URI, "http://example.org/ldpath");
136
137        mockEndpoint.expectedMessageCount(1);
138        mockEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/json");
139
140        final var context = camelContext.adapt(ModelCamelContext.class);
141        AdviceWith.adviceWith(context, "FcrepoLDPathGet", a -> {
142            a.mockEndpointsAndSkip("http:*");
143            a.weaveAddLast().to(endpoint);
144        });
145
146        final Map<String, Object> headers = new HashMap<>();
147        headers.put("ldpath", "http://example.org/ldpath");
148        headers.put("context", uri);
149        template.sendBodyAndHeaders("direct:get", loadResourceAsStream("test.ldpath"), headers);
150
151        mockEndpoint.assertIsSatisfied();
152        httpEndpoint.assertIsSatisfied();
153        final String result = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class);
154
155        @SuppressWarnings("unchecked")
156        final List<Map<String, List<String>>> data = MAPPER.readValue(result, List.class);
157
158        assertFalse(data.isEmpty());
159        assertTrue(data.get(0).containsKey("label"));
160        assertTrue(data.get(0).containsKey("type"));
161        assertTrue(data.get(0).get("id").contains(uri));
162        assertTrue(data.get(0).get("label").contains("binary"));
163        assertTrue(data.get(0).get("type").contains("Class"));
164    }
165
166    @Test
167    public void testMimicPost() throws Exception {
168        final String uri = "http://fedora.info/definitions/v4/repository#Container";
169        final String endpoint = "mock:resultPost";
170        final MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint(endpoint);
171        mockEndpoint.expectedMessageCount(1);
172        mockEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/json");
173
174        final var context = camelContext.adapt(ModelCamelContext.class);
175        AdviceWith.adviceWith(context, "FcrepoLDPathPrepare", a -> {
176            a.weaveAddLast().to(endpoint);
177        });
178
179        template.sendBodyAndHeader("direct:ldpathPrepare",
180                loadResourceAsStream("test.ldpath"), "context", uri);
181
182        mockEndpoint.assertIsSatisfied();
183        final String result = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class);
184
185        @SuppressWarnings("unchecked")
186        final List<Map<String, List<String>>> data = MAPPER.readValue(result, List.class);
187
188        assertFalse(data.isEmpty());
189        assertTrue(data.get(0).containsKey("label"));
190        assertTrue(data.get(0).containsKey("type"));
191        assertTrue(data.get(0).get("label").contains("Fedora Container"));
192        assertTrue(data.get(0).get("type").contains("Class"));
193        assertTrue(data.get(0).get("id").contains(uri));
194
195    }
196
197    @Test
198    public void testMimicPostWithFunctions() throws Exception {
199        final String uri = "http://fedora.info/definitions/v4/repository#Container";
200        final String endpoint = "mock:resultPostWithFunctions";
201        final MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint(endpoint);
202        mockEndpoint.expectedMessageCount(1);
203        mockEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/json");
204
205        final var context = camelContext.adapt(ModelCamelContext.class);
206        AdviceWith.adviceWith(context, "FcrepoLDPathPrepare", a -> {
207            a.weaveAddLast().to(endpoint);
208        });
209
210
211        template.sendBodyAndHeader("direct:ldpathPrepare",
212                loadResourceAsStream("test-with-functions.ldpath"),
213                "context", uri);
214
215        mockEndpoint.assertIsSatisfied();
216        final String result = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class);
217
218        @SuppressWarnings("unchecked")
219        final List<Map<String, List<String>>> data = MAPPER.readValue(result, List.class);
220
221        assertFalse(data.isEmpty());
222        assertTrue(data.get(0).containsKey("label"));
223        assertTrue(data.get(0).containsKey("type"));
224        assertTrue(data.get(0).containsKey("description"));
225        assertTrue(data.get(0).get("label").contains("Fedora Container"));
226        assertTrue(data.get(0).get("type").contains("Class"));
227        assertTrue(data.get(0).get("id").contains(uri));
228        assertTrue(data.get(0).get("description").contains("Class : Fedora Container"));
229
230    }
231
232
233    @Configuration
234    @ComponentScan(resourcePattern = "**/Fcrepo*.class")
235    static class ContextConfig extends CamelConfiguration {
236    }
237}
238