001/**
002 * Copyright 2015 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;
017
018import static java.net.URI.create;
019import static org.junit.Assert.assertEquals;
020import static org.junit.Assert.assertNotNull;
021import static org.mockito.Matchers.any;
022import static org.mockito.Matchers.anyString;
023import static org.mockito.Matchers.eq;
024import static org.mockito.Mockito.mock;
025import static org.mockito.Mockito.when;
026
027import java.io.ByteArrayInputStream;
028import java.io.InputStream;
029import java.io.IOException;
030import java.net.URI;
031
032import org.apache.camel.Exchange;
033import org.apache.camel.component.http4.HttpMethods;
034import org.apache.camel.converter.stream.InputStreamCache;
035import org.apache.camel.impl.DefaultCamelContext;
036import org.apache.camel.impl.DefaultExchange;
037import org.apache.camel.impl.DefaultUnitOfWork;
038import org.apache.commons.lang3.StringUtils;
039import org.junit.Before;
040import org.junit.Test;
041import org.junit.runner.RunWith;
042import org.mockito.Mock;
043import org.mockito.runners.MockitoJUnitRunner;
044
045/**
046 * @author acoburn
047 */
048@RunWith(MockitoJUnitRunner.class)
049public class FcrepoProducerTest {
050
051    private FcrepoEndpoint testEndpoint;
052
053    private FcrepoProducer testProducer;
054
055    private Exchange testExchange;
056
057    @Mock
058    private FcrepoClient mockClient;
059
060    @Before
061    public void setUp() throws IOException {
062        final FcrepoComponent mockComponent = mock(FcrepoComponent.class);
063
064        final FcrepoConfiguration testConfig = new FcrepoConfiguration();
065        testEndpoint = new FcrepoEndpoint("fcrepo:localhost:8080", "/rest", mockComponent, testConfig);
066        testEndpoint.setBaseUrl("localhost:8080/rest");
067        testExchange = new DefaultExchange(new DefaultCamelContext());
068        testExchange.getIn().setBody(null);
069    }
070
071    public void init() throws IOException {
072        testProducer = new FcrepoProducer(testEndpoint);
073        TestUtils.setField(testProducer, "client", mockClient);
074    }
075
076    @Test
077    public void testGetProducer() throws Exception {
078        final URI uri = create(TestUtils.baseUrl);
079        final int status = 200;
080        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
081        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
082        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
083
084        init();
085
086        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
087
088        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
089        when(mockClient.get(any(URI.class), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(getResponse);
090
091        testProducer.process(testExchange);
092
093        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
094        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
095        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
096    }
097
098    @Test
099    public void testGetAcceptHeaderProducer() throws Exception {
100        final URI uri = create(TestUtils.baseUrl);
101        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
102        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
103        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
104
105        init();
106
107        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
108        testExchange.getIn().setHeader("Accept", TestUtils.N_TRIPLES);
109
110        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
111        when(mockClient.get(any(URI.class), eq(TestUtils.N_TRIPLES), any(String.class))).thenReturn(getResponse);
112
113        testProducer.process(testExchange);
114
115        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
116        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
117    }
118
119    @Test
120    public void testGetPreferHeaderProducer() throws Exception {
121        final URI uri = create(TestUtils.baseUrl);
122        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
123        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
124        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
125        final String prefer = "return=representation; omit=\"http://www.w3.org/ns/ldp#PreferContainment\";";
126
127        init();
128
129        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
130        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_PREFER, prefer);
131
132        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
133        when(mockClient.get(any(URI.class), any(String.class), eq(prefer))).thenReturn(getResponse);
134
135        testProducer.process(testExchange);
136
137        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
138        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
139    }
140
141    @Test
142    public void testGetFixity() throws Exception {
143        final String baseUrl = "http://localhost:8080/rest";
144        final String path = "/binary";
145        final URI uri = create(baseUrl + path);
146        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.fixityTriples.getBytes());
147        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
148        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
149
150        testEndpoint.setFixity(true);
151
152        init();
153
154        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path);
155
156        when(mockClient.head(eq(create(baseUrl + path)))).thenReturn(headResponse);
157        when(mockClient.get(eq(create(baseUrl + path + FcrepoConstants.FIXITY)),
158                    any(String.class), any(String.class))).thenReturn(getResponse);
159
160        testProducer.process(testExchange);
161
162        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.fixityTriples);
163        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
164    }
165
166    @Test
167    public void testGetPreferIncludeLongEndpointProducer() throws Exception {
168        final URI uri = create(TestUtils.baseUrl);
169        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
170        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
171        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
172        final String prefer = "return=representation; " +
173                    "include=\"http://fedora.info/definitions/v4/repository#ServerManaged\";";
174
175        testEndpoint.setPreferInclude("http://fedora.info/definitions/v4/repository#ServerManaged");
176
177        init();
178
179        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
180
181        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
182        when(mockClient.get(any(URI.class), any(String.class), eq(prefer))).thenReturn(getResponse);
183
184        testProducer.process(testExchange);
185
186        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
187        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
188    }
189
190    @Test
191    public void testGetPreferIncludeShortEndpointProducer() throws Exception {
192        final URI uri = create(TestUtils.baseUrl);
193        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
194        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
195        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
196        final String prefer = "return=representation; include=\"http://www.w3.org/ns/ldp#PreferMembership\";";
197
198        testEndpoint.setPreferInclude("PreferMembership");
199
200        init();
201
202        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
203
204        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
205        when(mockClient.get(any(URI.class), any(String.class), eq(prefer))).thenReturn(getResponse);
206
207        testProducer.process(testExchange);
208
209        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
210        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
211    }
212
213    @Test
214    public void testGetPreferOmitLongEndpointProducer() throws Exception {
215        final URI uri = create(TestUtils.baseUrl);
216        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
217        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
218        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
219        final String prefer = "return=representation; " +
220                    "omit=\"http://fedora.info/definitions/v4/repository#EmbedResources\";";
221
222        testEndpoint.setPreferOmit("http://fedora.info/definitions/v4/repository#EmbedResources");
223
224        init();
225
226        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
227
228        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
229        when(mockClient.get(any(URI.class), any(String.class), eq(prefer))).thenReturn(getResponse);
230
231        testProducer.process(testExchange);
232
233        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
234        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
235    }
236
237    @Test
238    public void testGetPreferOmitShortEndpointProducer() throws Exception {
239        final URI uri = create(TestUtils.baseUrl);
240        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
241        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
242        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
243        final String prefer = "return=representation; omit=\"http://www.w3.org/ns/ldp#PreferContainment\";";
244
245        testEndpoint.setPreferOmit("PreferContainment");
246
247        init();
248
249        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
250
251        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
252        when(mockClient.get(any(URI.class), any(String.class), eq(prefer))).thenReturn(getResponse);
253
254        testProducer.process(testExchange);
255
256        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
257        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
258    }
259
260    @Test
261    public void testGetAcceptEndpointProducer() throws Exception {
262        final URI uri = create(TestUtils.baseUrl);
263        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
264        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
265        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.N_TRIPLES, null, body);
266
267        testEndpoint.setAccept(TestUtils.N_TRIPLES);
268
269        init();
270
271        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
272
273        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
274        when(mockClient.get(any(URI.class), eq(TestUtils.N_TRIPLES), any(String.class))).thenReturn(getResponse);
275
276        testProducer.process(testExchange);
277
278        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfTriples);
279        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
280    }
281
282    @Test
283    public void testGetRootProducer() throws Exception {
284        final URI uri = create("http://localhost:8080/rest");
285        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
286        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
287        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.RDF_XML, null, body);
288
289        init();
290
291        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
292        when(mockClient.get(any(URI.class), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(getResponse);
293
294        testProducer.process(testExchange);
295
296        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
297        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
298    }
299
300    @Test
301    public void testGetBinaryProducer() throws Exception {
302        final URI uri = create(TestUtils.baseUrl);
303        final String content = "Foo";
304        final ByteArrayInputStream body = new ByteArrayInputStream(content.getBytes());
305        final FcrepoResponse getResponse = new FcrepoResponse(uri, 200, TestUtils.TEXT_PLAIN, null, body);
306
307        testEndpoint.setMetadata(false);
308
309        init();
310
311        testExchange.getIn().setHeader(JmsHeaders.IDENTIFIER, "/foo");
312        testExchange.getIn().setHeader(Exchange.ACCEPT_CONTENT_TYPE, TestUtils.TEXT_PLAIN);
313        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.GET);
314
315        when(mockClient.get(any(URI.class), eq(TestUtils.TEXT_PLAIN), any(String.class))).thenReturn(getResponse);
316
317        testProducer.process(testExchange);
318
319        assertEquals(testExchange.getIn().getBody(String.class), content);
320        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.TEXT_PLAIN);
321    }
322
323    @Test
324    public void testHeadProducer() throws Exception {
325        final URI uri = create(TestUtils.baseUrl);
326        final URI metadata = create(TestUtils.baseUrl + "/bar");
327        final int status = 200;
328        final FcrepoResponse headResponse = new FcrepoResponse(uri, status, TestUtils.N_TRIPLES, metadata, null);
329
330        init();
331
332        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
333        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.HEAD);
334
335        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
336
337        testProducer.process(testExchange);
338
339        assertEquals(testExchange.getIn().getBody(), null);
340        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.N_TRIPLES);
341        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
342    }
343
344    @Test
345    public void testDeleteProducer() throws Exception {
346        final URI uri = create(TestUtils.baseUrl);
347        final int status = 204;
348        final FcrepoResponse deleteResponse = new FcrepoResponse(uri, status, null, null, null);
349
350        init();
351
352        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
353        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.DELETE);
354
355        when(mockClient.delete(any(URI.class))).thenReturn(deleteResponse);
356
357        testProducer.process(testExchange);
358
359        assertEquals(testExchange.getIn().getBody(), null);
360        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), null);
361        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
362    }
363
364    @Test
365    public void testDeleteTombstoneProducer() throws Exception {
366        final URI uri = create(TestUtils.baseUrl + FcrepoConstants.TOMBSTONE);
367        final int status = 204;
368        final FcrepoResponse deleteResponse = new FcrepoResponse(uri, status, null, null, null);
369
370        testEndpoint.setTombstone(true);
371
372        init();
373
374        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
375        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.DELETE);
376
377        when(mockClient.delete(uri)).thenReturn(deleteResponse);
378
379        testProducer.process(testExchange);
380
381        assertEquals(testExchange.getIn().getBody(), null);
382        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), null);
383        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
384    }
385
386    @Test
387    public void testTransformGetProducer() throws Exception {
388        final URI uri = create(TestUtils.baseUrl);
389        final int status = 200;
390        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
391        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
392                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
393
394        testEndpoint.setTransform("default");
395
396        init();
397
398        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
399        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.GET);
400
401        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
402        when(mockClient.get(create(TestUtils.baseUrl + FcrepoConstants.TRANSFORM + "/default"), TestUtils.JSON, null))
403            .thenReturn(getResponse);
404
405        testProducer.process(testExchange);
406
407        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
408        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
409        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
410    }
411
412    @Test
413    public void testTransformPostProducer() throws Exception {
414        final URI uri = create(TestUtils.baseUrl);
415        final String ldpathText = "@prefix dc : <http://purl.org/dc/elements/1.1/>\n" +
416                            "title = dc:title :: xsd:string;";
417        final ByteArrayInputStream body = new ByteArrayInputStream(ldpathText.getBytes());
418        final int status = 200;
419        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
420        final FcrepoResponse postResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
421                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
422
423        testEndpoint.setTransform("default");
424
425        init();
426
427        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
428        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST);
429        testExchange.getIn().setHeader(Exchange.CONTENT_TYPE, TestUtils.RDF_LDPATH);
430        testExchange.getIn().setBody(body);
431
432        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
433        when(mockClient.post(create(TestUtils.baseUrl + FcrepoConstants.TRANSFORM), body, TestUtils.RDF_LDPATH))
434            .thenReturn(postResponse);
435
436        testProducer.process(testExchange);
437
438        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
439        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
440        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
441    }
442
443    @Test
444    public void testTransformHeaderProducer() throws Exception {
445        final URI uri = create(TestUtils.baseUrl);
446        final int status = 200;
447        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
448        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
449                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
450
451        testEndpoint.setTransform("true");
452
453        init();
454
455        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
456        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_TRANSFORM, "default");
457
458        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
459        when(mockClient.get(create(TestUtils.baseUrl + FcrepoConstants.TRANSFORM + "/default"), TestUtils.JSON, null))
460            .thenReturn(getResponse);
461
462        testProducer.process(testExchange);
463
464        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
465        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
466        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
467    }
468
469    @Test
470    public void testTransformHeaderOnlyProducer() throws Exception {
471        final URI uri = create(TestUtils.baseUrl);
472        final int status = 200;
473        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
474        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
475                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
476
477        testEndpoint.setTransform("");
478
479        init();
480
481        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
482        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_TRANSFORM, "default");
483
484        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
485        when(mockClient.get(create(TestUtils.baseUrl + FcrepoConstants.TRANSFORM + "/default"), TestUtils.JSON, null))
486            .thenReturn(getResponse);
487
488        testProducer.process(testExchange);
489
490        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
491        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
492        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
493    }
494
495    @Test
496    public void testTransformProducer() throws Exception {
497        final URI uri = create(TestUtils.baseUrl);
498        final int status = 200;
499        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
500        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
501                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
502
503        testEndpoint.setTransform("default");
504
505        init();
506
507        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
508
509        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
510        when(mockClient.get(create(TestUtils.baseUrl + FcrepoConstants.TRANSFORM + "/default"), TestUtils.JSON, null))
511            .thenReturn(getResponse);
512
513        testProducer.process(testExchange);
514
515        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
516        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
517        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
518    }
519
520    @Test
521    public void testPostProducer() throws Exception {
522        final URI uri = create(TestUtils.baseUrl);
523        final String responseText = TestUtils.baseUrl + "/e8/0b/ab/e80bab60";
524        final int status = 201;
525        final FcrepoResponse postResponse = new FcrepoResponse(uri, status, TestUtils.TEXT_PLAIN, null,
526                new ByteArrayInputStream(responseText.getBytes()));
527
528        init();
529
530        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
531        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST);
532
533        when(mockClient.post(any(URI.class), any(InputStream.class), any(String.class))).thenReturn(postResponse);
534
535        testProducer.process(testExchange);
536
537        assertEquals(testExchange.getIn().getBody(String.class), responseText);
538        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.TEXT_PLAIN);
539        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
540    }
541
542    @Test
543    public void testPostContentTypeEndpointProducer() throws Exception {
544        final URI uri = create(TestUtils.baseUrl);
545        final int status = 204;
546        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
547        final FcrepoResponse postResponse = new FcrepoResponse(uri, status, null, null, null);
548
549        testEndpoint.setContentType(TestUtils.SPARQL_UPDATE);
550
551        init();
552
553        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
554        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST);
555        testExchange.getIn().setBody(new ByteArrayInputStream(TestUtils.sparqlUpdate.getBytes()));
556
557        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
558        when(mockClient.post(any(URI.class), any(InputStream.class), eq(TestUtils.SPARQL_UPDATE)))
559            .thenReturn(postResponse);
560
561        testProducer.process(testExchange);
562
563        assertEquals(testExchange.getIn().getBody(), null);
564        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
565    }
566
567    @Test
568    public void testPatchProducer() throws Exception {
569        final URI uri = create(TestUtils.baseUrl);
570        final URI metadata = create(TestUtils.baseUrl + "/bar");
571        final int status = 204;
572        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, metadata, null);
573        final FcrepoResponse patchResponse = new FcrepoResponse(uri, status, null, null, null);
574
575        init();
576
577        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
578        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.PATCH);
579        testExchange.getIn().setBody(new ByteArrayInputStream(TestUtils.sparqlUpdate.getBytes()));
580
581        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
582        when(mockClient.patch(any(URI.class), any(InputStream.class))).thenReturn(patchResponse);
583
584        testProducer.process(testExchange);
585
586        assertEquals(testExchange.getIn().getBody(), null);
587        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
588    }
589
590    @Test
591    public void testPatchTransformEnabledProducer() throws Exception {
592        final URI uri = create(TestUtils.baseUrl);
593        final URI metadata = create(TestUtils.baseUrl + "/bar");
594        final int status = 204;
595        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, TestUtils.RDF_XML, metadata, null);
596        final FcrepoResponse patchResponse = new FcrepoResponse(uri, status, null, null, null);
597
598        testEndpoint.setTransform("default");
599
600        init();
601
602        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
603        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.PATCH);
604        testExchange.getIn().setBody(new ByteArrayInputStream(TestUtils.sparqlUpdate.getBytes()));
605
606        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
607        when(mockClient.patch(any(URI.class), any(InputStream.class))).thenReturn(patchResponse);
608
609        testProducer.process(testExchange);
610
611        assertEquals(testExchange.getIn().getBody(), null);
612        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
613    }
614
615    @Test
616    public void testPutProducer() throws Exception {
617        final URI uri = create(TestUtils.baseUrl);
618        final int status = 201;
619        final FcrepoResponse patchResponse = new FcrepoResponse(uri, status, TestUtils.TEXT_PLAIN, null,
620                new ByteArrayInputStream(TestUtils.baseUrl.getBytes()));
621
622        init();
623
624        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
625        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.PUT);
626        testExchange.getIn().setBody(null);
627
628        when(mockClient.put(any(URI.class), any(InputStream.class), any(String.class))).thenReturn(patchResponse);
629
630        testProducer.process(testExchange);
631
632        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.baseUrl);
633        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
634        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.TEXT_PLAIN);
635    }
636
637    @Test
638    public void testPreferProperties() throws Exception {
639        testProducer = new FcrepoProducer(testEndpoint);
640
641        assertEquals(6, RdfNamespaces.PREFER_PROPERTIES.size());
642        final String[] fcrepoPrefer = new String[] { "ServerManaged", "EmbedResources", "InboundReferences" };
643        for (final String s : fcrepoPrefer) {
644            assertEquals(RdfNamespaces.REPOSITORY + s, RdfNamespaces.PREFER_PROPERTIES.get(s));
645        }
646
647        final String[] ldpPrefer = new String[] { "PreferContainment", "PreferMembership",
648            "PreferMinimalContainer" };
649        for (final String s : ldpPrefer) {
650            assertEquals(RdfNamespaces.LDP + s, RdfNamespaces.PREFER_PROPERTIES.get(s));
651        }
652    }
653
654    @Test
655    public void testGetProducerWithScheme() throws Exception {
656        final URI uri = create(TestUtils.baseUrl);
657        final int status = 200;
658        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
659        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
660        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
661
662        // set the baseUrl with an explicit http:// scheme
663        testEndpoint.setBaseUrl("http://localhost:8080/rest");
664        init();
665
666        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
667
668        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
669        when(mockClient.get(eq(create(TestUtils.baseUrl)), eq(TestUtils.RDF_XML),
670                    any(String.class))).thenReturn(getResponse);
671
672        testProducer.process(testExchange);
673
674        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
675        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
676        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
677    }
678
679    @Test
680    public void testGetSecureProducer() throws Exception {
681        final URI uri = create(TestUtils.baseUrlSecure);
682        final int status = 200;
683        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
684        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
685        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
686
687        // set the baseUrl with no scheme but with a secure port
688        testEndpoint.setBaseUrl("localhost:443/rest");
689        init();
690
691        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/secure");
692
693        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
694        when(mockClient.get(eq(create(TestUtils.baseUrlSecure)), eq(TestUtils.RDF_XML),
695                    any(String.class))).thenReturn(getResponse);
696
697        testProducer.process(testExchange);
698
699        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
700        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
701        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
702    }
703
704    @Test
705    public void testGetSecureProducerWithScheme() throws Exception {
706        final URI uri = create(TestUtils.baseUrlSecureWithoutPort);
707        final int status = 200;
708        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
709        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
710        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
711
712        // set the baseUrl with explicit scheme but no port
713        testEndpoint.setBaseUrl("https://localhost/rest");
714        init();
715
716        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/secure");
717
718        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
719        when(mockClient.get(eq(create(TestUtils.baseUrlSecureWithoutPort)), eq(TestUtils.RDF_XML),
720                    any(String.class))).thenReturn(getResponse);
721
722        testProducer.process(testExchange);
723
724        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
725        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
726        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
727    }
728
729    @Test
730    public void testSecureTransformProducer() throws Exception {
731        final URI uri = create(TestUtils.baseUrlSecure);
732        final int status = 200;
733        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
734        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.JSON, null,
735                new ByteArrayInputStream(TestUtils.serializedJson.getBytes()));
736
737        // set the baseUrl with no scheme but explicit secure port
738        testEndpoint.setBaseUrl("localhost:443/rest");
739        testEndpoint.setTransform("default");
740
741        init();
742
743        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/secure");
744
745        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
746        when(mockClient.get(create(TestUtils.baseUrlSecure + FcrepoConstants.TRANSFORM + "/default"),
747                    TestUtils.JSON, null)).thenReturn(getResponse);
748
749        testProducer.process(testExchange);
750
751        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.serializedJson);
752        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE), TestUtils.JSON);
753        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
754    }
755
756    @Test
757    public void testTransactedGetProducer() throws Exception {
758        final String baseUrl = "http://localhost:8080/rest";
759        final String path = "/transact";
760        final String path2 = "/transact2";
761        final String tx = "tx:12345";
762        final URI uri = create(baseUrl + "/" + tx + path);
763        final URI uri2 = create(baseUrl + "/" + tx + path2);
764        final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT);
765        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
766        final int status = 200;
767        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
768        final ByteArrayInputStream body2 = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
769        final DefaultUnitOfWork uow = new DefaultUnitOfWork(testExchange);
770        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
771        txMgr.setBaseUrl(baseUrl);
772
773        testEndpoint.setTransactionManager(txMgr);
774
775        final FcrepoClient otherMockClient = mock(FcrepoClient.class);
776
777        init();
778        TestUtils.setField(txMgr, "client", otherMockClient);
779
780        uow.beginTransactedBy((Object)tx);
781
782        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path);
783        testExchange.setUnitOfWork(uow);
784
785        when(otherMockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
786                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
787        when(otherMockClient.post(eq(commitUri), any(InputStream.class), anyString())).thenReturn(
788                new FcrepoResponse(commitUri, 201, null, null, null));
789
790        when(mockClient.head(any(URI.class))).thenReturn(new FcrepoResponse(uri, 200, null, null, null));
791        when(mockClient.get(eq(uri), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(
792            new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body));
793        when(mockClient.get(eq(uri2), eq(TestUtils.N_TRIPLES), any(String.class))).thenReturn(
794            new FcrepoResponse(uri2, status, TestUtils.N_TRIPLES, null, body2));
795
796        testProducer.process(testExchange);
797
798        assertEquals(status, testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE));
799        assertEquals(TestUtils.RDF_XML, testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class));
800        assertEquals(TestUtils.rdfXml, testExchange.getIn().getBody(String.class));
801
802        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, "GET");
803        testExchange.getIn().setHeader(Exchange.ACCEPT_CONTENT_TYPE, TestUtils.N_TRIPLES);
804        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path2);
805        testExchange.setUnitOfWork(uow);
806        testProducer.process(testExchange);
807        assertEquals(status, testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE));
808        assertEquals(TestUtils.N_TRIPLES, testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class));
809        assertEquals(TestUtils.rdfTriples, testExchange.getIn().getBody(String.class));
810
811    }
812
813    @Test (expected = RuntimeException.class)
814    public void testTransactedProducerWithError() throws Exception {
815        final String baseUrl = "http://localhost:8080/rest";
816        final String path = "/transact";
817        final String path2 = "/transact2";
818        final String tx = "tx:12345";
819        final URI uri = create(baseUrl + "/" + tx + path);
820        final URI uri2 = create(baseUrl + "/" + tx + path2);
821        final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT);
822        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
823        final int status = 200;
824        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
825        final ByteArrayInputStream body2 = new ByteArrayInputStream(TestUtils.rdfTriples.getBytes());
826        final DefaultUnitOfWork uow = new DefaultUnitOfWork(testExchange);
827        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
828        txMgr.setBaseUrl(baseUrl);
829
830        testEndpoint.setTransactionManager(txMgr);
831
832        final FcrepoClient otherMockClient = mock(FcrepoClient.class);
833
834        init();
835        TestUtils.setField(txMgr, "client", otherMockClient);
836
837        uow.beginTransactedBy((Object)tx);
838
839        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path);
840        testExchange.setUnitOfWork(uow);
841
842        when(otherMockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
843                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
844        when(otherMockClient.post(eq(commitUri), any(InputStream.class), anyString())).thenReturn(
845                new FcrepoResponse(commitUri, 201, null, null, null));
846
847        when(mockClient.head(any(URI.class))).thenReturn(new FcrepoResponse(uri, 200, null, null, null));
848        when(mockClient.get(eq(uri), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(
849            new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body));
850        when(mockClient.get(eq(uri2), eq(TestUtils.N_TRIPLES), any(String.class))).thenThrow(
851            new FcrepoOperationFailedException(uri2, 400, "Bad Request"));
852
853        testProducer.process(testExchange);
854
855        assertEquals(status, testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE));
856        assertEquals(TestUtils.RDF_XML, testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class));
857        assertEquals(TestUtils.rdfXml, testExchange.getIn().getBody(String.class));
858
859        testExchange.getIn().setHeader(Exchange.HTTP_METHOD, "GET");
860        testExchange.getIn().setHeader(Exchange.ACCEPT_CONTENT_TYPE, TestUtils.N_TRIPLES);
861        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path2);
862        testExchange.setUnitOfWork(uow);
863        testProducer.process(testExchange);
864    }
865
866    @Test
867    public void testNoStreamCaching() throws Exception {
868        final URI uri = create(TestUtils.baseUrl);
869        final int status = 200;
870        final ByteArrayInputStream body = new ByteArrayInputStream(TestUtils.rdfXml.getBytes());
871        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
872        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
873
874        init();
875
876        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
877        testExchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, true);
878
879        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
880        when(mockClient.get(any(URI.class), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(getResponse);
881
882        testProducer.process(testExchange);
883
884        assertEquals(testExchange.getIn().getBody(String.class), TestUtils.rdfXml);
885        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
886        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
887    }
888
889    @Test
890    public void testStreamCaching() throws Exception {
891        final URI uri = create(TestUtils.baseUrl);
892        final int status = 200;
893        final String rdfConcat = StringUtils.repeat(TestUtils.rdfXml, 10000);
894        final ByteArrayInputStream body = new ByteArrayInputStream(rdfConcat.getBytes());
895        final FcrepoResponse headResponse = new FcrepoResponse(uri, 200, null, null, null);
896        final FcrepoResponse getResponse = new FcrepoResponse(uri, status, TestUtils.RDF_XML, null, body);
897
898        init();
899
900        testExchange.getIn().setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, "/foo");
901        testExchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, false);
902
903        testExchange.getContext().getStreamCachingStrategy().setSpoolThreshold(1024);
904        testExchange.getContext().getStreamCachingStrategy().setBufferSize(256);
905        testExchange.getContext().setStreamCaching(true);
906
907        when(mockClient.head(any(URI.class))).thenReturn(headResponse);
908        when(mockClient.get(any(URI.class), eq(TestUtils.RDF_XML), any(String.class))).thenReturn(getResponse);
909
910        testProducer.process(testExchange);
911
912        assertEquals(true, testExchange.getContext().isStreamCaching());
913        assertNotNull(testExchange.getIn().getBody(InputStreamCache.class));
914        assertEquals(rdfConcat.length(), testExchange.getIn().getBody(InputStreamCache.class).length());
915        assertEquals(rdfConcat.length(), testExchange.getIn().getBody(InputStreamCache.class).length());
916        assertEquals(testExchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class), TestUtils.RDF_XML);
917        assertEquals(testExchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE), status);
918    }
919}