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