/*
* Licensed to DuraSpace under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* DuraSpace licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fcrepo.http.api;
import static com.google.common.base.Predicates.containsPattern;
import static java.net.URI.create;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
import static java.util.stream.Stream.of;
import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE;
import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH;
import static javax.ws.rs.core.HttpHeaders.LINK;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.NO_CONTENT;
import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT;
import static org.apache.commons.io.IOUtils.toInputStream;
import static org.apache.jena.graph.NodeFactory.createURI;
import static org.apache.jena.riot.WebContent.contentTypeSPARQLUpdate;
import static org.fcrepo.http.api.ContentExposingResource.getSimpleContentType;
import static org.fcrepo.http.api.FedoraBaseResource.JMS_BASEURL_PROP;
import static org.fcrepo.http.api.FedoraLdp.HTTP_HEADER_ACCEPT_PATCH;
import static org.fcrepo.http.commons.domain.RDFMediaType.NTRIPLES_TYPE;
import static org.fcrepo.http.commons.test.util.TestHelpers.getUriInfoImpl;
import static org.fcrepo.kernel.api.FedoraTypes.LDP_BASIC_CONTAINER;
import static org.fcrepo.kernel.api.FedoraTypes.LDP_DIRECT_CONTAINER;
import static org.fcrepo.kernel.api.FedoraTypes.LDP_INDIRECT_CONTAINER;
import static org.fcrepo.kernel.api.RdfCollectors.toModel;
import static org.fcrepo.kernel.api.RdfLexicon.BASIC_CONTAINER;
import static org.fcrepo.kernel.api.RdfLexicon.DIRECT_CONTAINER;
import static org.fcrepo.kernel.api.RdfLexicon.INBOUND_REFERENCES;
import static org.fcrepo.kernel.api.RdfLexicon.INDIRECT_CONTAINER;
import static org.fcrepo.kernel.api.RdfLexicon.LDP_NAMESPACE;
import static org.fcrepo.kernel.api.observer.OptionalValues.BASE_URL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.slf4j.LoggerFactory.getLogger;
import static org.springframework.test.util.ReflectionTestUtils.setField;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.apache.jena.graph.Triple;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.fcrepo.http.api.PathLockManager.AcquiredLock;
import org.fcrepo.http.commons.api.rdf.HttpResourceConverter;
import org.fcrepo.http.commons.domain.MultiPrefer;
import org.fcrepo.http.commons.responses.RdfNamespacedStream;
import org.fcrepo.http.commons.session.HttpSession;
import org.fcrepo.kernel.api.FedoraSession;
import org.fcrepo.kernel.api.RdfStream;
import org.fcrepo.kernel.api.TripleCategory;
import org.fcrepo.kernel.api.exception.CannotCreateResourceException;
import org.fcrepo.kernel.api.exception.ConstraintViolationException;
import org.fcrepo.kernel.api.exception.InsufficientStorageException;
import org.fcrepo.kernel.api.exception.InvalidChecksumException;
import org.fcrepo.kernel.api.exception.MalformedRdfException;
import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
import org.fcrepo.kernel.api.models.Container;
import org.fcrepo.kernel.api.models.FedoraBinary;
import org.fcrepo.kernel.api.models.FedoraResource;
import org.fcrepo.kernel.api.models.NonRdfSourceDescription;
import org.fcrepo.kernel.api.rdf.DefaultRdfStream;
import org.fcrepo.kernel.api.services.BinaryService;
import org.fcrepo.kernel.api.services.ContainerService;
import org.fcrepo.kernel.api.services.NodeService;
import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.server.ContainerRequest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.springframework.mock.web.MockHttpServletResponse;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* @author cabeer
* @author ajs6f
*/
@RunWith(MockitoJUnitRunner.class)
public class FedoraLdpTest {
private final String path = "/some/path";
private final String binaryPath = "/some/binary/path";
private final String binaryDescriptionPath = "/some/other/path";
private FedoraLdp testObj;
@Mock
private Request mockRequest;
private HttpServletResponse mockResponse;
@Mock
private HttpSession mockSession;
@Mock
private FedoraSession mockFedoraSession;
@Mock
private Container mockContainer;
@Mock
private NonRdfSourceDescription mockNonRdfSourceDescription;
@Mock
private FedoraBinary mockBinary;
private IdentifierConverter<Resource, FedoraResource> idTranslator;
@Mock
private NodeService mockNodeService;
@Mock
private ContainerService mockContainerService;
@Mock
private BinaryService mockBinaryService;
@Mock
private FedoraHttpConfiguration mockHttpConfiguration;
@Mock
private HttpHeaders mockHeaders;
@Mock
private SecurityContext mockSecurityContext;
@Mock
private PathLockManager mockLockManager;
@Mock
private AcquiredLock mockLock;
private static final Logger log = getLogger(FedoraLdpTest.class);
@Before
public void setUp() {
testObj = spy(new FedoraLdp(path));
mockResponse = new MockHttpServletResponse();
idTranslator = new HttpResourceConverter(mockSession,
UriBuilder.fromUri("http://localhost/fcrepo/{path: .*}"));
setField(testObj, "request", mockRequest);
setField(testObj, "servletResponse", mockResponse);
setField(testObj, "uriInfo", getUriInfoImpl());
setField(testObj, "headers", mockHeaders);
setField(testObj, "idTranslator", idTranslator);
setField(testObj, "nodeService", mockNodeService);
setField(testObj, "containerService", mockContainerService);
setField(testObj, "binaryService", mockBinaryService);
setField(testObj, "httpConfiguration", mockHttpConfiguration);
setField(testObj, "session", mockSession);
setField(testObj, "securityContext", mockSecurityContext);
setField(testObj, "lockManager", mockLockManager);
when(mockHttpConfiguration.putRequiresIfMatch()).thenReturn(false);
when(mockContainer.getEtagValue()).thenReturn("");
when(mockContainer.getPath()).thenReturn(path);
when(mockContainer.getDescription()).thenReturn(mockContainer);
when(mockContainer.getDescribedResource()).thenReturn(mockContainer);
when(mockNonRdfSourceDescription.getEtagValue()).thenReturn("");
when(mockNonRdfSourceDescription.getPath()).thenReturn(binaryDescriptionPath);
when(mockNonRdfSourceDescription.getDescribedResource()).thenReturn(mockBinary);
when(mockBinary.getEtagValue()).thenReturn("");
when(mockBinary.getPath()).thenReturn(binaryPath);
when(mockBinary.getDescription()).thenReturn(mockNonRdfSourceDescription);
when(mockHeaders.getHeaderString("user-agent")).thenReturn("Test UserAgent");
when(mockLockManager.lockForRead(any())).thenReturn(mockLock);
when(mockLockManager.lockForWrite(any(), any(), any())).thenReturn(mockLock);
when(mockLockManager.lockForDelete(any())).thenReturn(mockLock);
when(mockSession.getId()).thenReturn("foo1234");
when(mockSession.getFedoraSession()).thenReturn(mockFedoraSession);
}
private FedoraResource setResource(final Class<? extends FedoraResource> klass) {
final FedoraResource mockResource = mock(klass);
if (mockResource instanceof FedoraBinary) {
when(((FedoraBinary) mockResource).getContentSize()).thenReturn(1l);
}
final Answer<RdfStream> answer = invocationOnMock -> new DefaultRdfStream(
createURI(invocationOnMock.getMock().toString()),
of(Triple.create(createURI(invocationOnMock.getMock().toString()),
createURI("called"),
createURI(invocationOnMock.getArguments()[1].toString()))));
doReturn(mockResource).when(testObj).resource();
when(mockResource.getPath()).thenReturn(path);
when(mockResource.getEtagValue()).thenReturn("");
when(mockResource.getDescription()).thenReturn(mockResource);
when(mockResource.getDescribedResource()).thenReturn(mockResource);
when(mockResource.getTriples(eq(idTranslator), anySetOf(TripleCategory.class))).thenAnswer(answer);
when(mockResource.getTriples(eq(idTranslator), any(TripleCategory.class))).thenAnswer(answer);
return mockResource;
}
@Test
public void testHead() throws Exception {
setResource(FedoraResource.class);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should have a Link header", mockResponse.containsHeader(LINK));
assertTrue("Should have an Allow header", mockResponse.containsHeader("Allow"));
assertTrue("Should be an LDP Resource",
mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE + "Resource>;rel=\"type\""));
}
@Test
public void testHeadWithObject() throws Exception {
setResource(Container.class);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
assertTrue("Should advertise Accept-Patch flavors", mockResponse.containsHeader(
FedoraLdp.HTTP_HEADER_ACCEPT_PATCH));
}
@Test
public void testHeadWithDefaultContainer() throws Exception {
setResource(Container.class);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPBasicContainer();
}
private void assertShouldBeAnLDPBasicContainer() {
assertTrue("Should be an LDP BasicContainer",
mockResponse.getHeaders(LINK).contains("<" + BASIC_CONTAINER.getURI() + ">;rel=\"type\""));
}
@Test
public void testHeadWithBasicContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_BASIC_CONTAINER)).thenReturn(true);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPBasicContainer();
}
@Test
public void testHeadWithDirectContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_DIRECT_CONTAINER)).thenReturn(true);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPDirectContainer();
}
private void assertShouldBeAnLDPDirectContainer() {
assertTrue("Should be an LDP DirectContainer",
mockResponse.getHeaders(LINK).contains("<" + DIRECT_CONTAINER.getURI() + ">;rel=\"type\""));
}
@Test
public void testHeadWithIndirectContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_INDIRECT_CONTAINER)).thenReturn(true);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPIndirectContainer();
}
private void assertShouldBeAnLDPIndirectContainer() {
assertTrue("Should be an LDP IndirectContainer",
mockResponse.getHeaders(LINK).contains("<" + INDIRECT_CONTAINER.getURI() + ">;rel=\"type\""));
}
@Test
public void testHeadWithBinary() throws Exception {
final FedoraBinary mockResource = (FedoraBinary)setResource(FedoraBinary.class);
when(mockResource.getDescription()).thenReturn(mockNonRdfSourceDescription);
when(mockResource.getMimeType()).thenReturn("image/jpeg");
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertContentLengthGreaterThan0(mockResponse.getHeader(CONTENT_LENGTH));
assertShouldBeAnLDPNonRDFSource();
assertShouldNotAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToBinaryDescription();
}
private void assertContentLengthGreaterThan0(final String contentLength) {
assertTrue("Should have a content length header greater than 0", Integer.parseInt(contentLength) > 0);
}
private void assertShouldContainLinkToBinaryDescription() {
assertTrue("Should contain a link to the binary description",
mockResponse.getHeaders(LINK)
.contains("<" + idTranslator.toDomain(binaryDescriptionPath + "/fcr:metadata")
+ ">; rel=\"describedby\""));
}
private void assertShouldNotAdvertiseAcceptPatchFlavors() {
assertFalse("Should not advertise Accept-Patch flavors", mockResponse.containsHeader(HTTP_HEADER_ACCEPT_PATCH));
}
private void assertShouldNotAdvertiseAcceptPostFlavors() {
assertFalse("Should not advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
}
@Test
public void testHeadWithExternalBinary() throws Exception {
final FedoraBinary mockResource = (FedoraBinary)setResource(FedoraBinary.class);
when(mockResource.getDescription()).thenReturn(mockNonRdfSourceDescription);
when(mockResource.getMimeType()).thenReturn("message/external-body; access-type=URL; URL=\"some:uri\"");
final Response actual = testObj.head();
assertEquals(TEMPORARY_REDIRECT.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPNonRDFSource();
assertShouldNotAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToBinaryDescription();
}
@Test
public void testHeadWithBinaryDescription() throws Exception {
final NonRdfSourceDescription mockResource
= (NonRdfSourceDescription)setResource(NonRdfSourceDescription.class);
when(mockResource.getDescribedResource()).thenReturn(mockBinary);
final Response actual = testObj.head();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP RDFSource", mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE +
"RDFSource>;rel=\"type\""));
assertShouldNotAdvertiseAcceptPostFlavors();
assertShouldAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToTheBinary();
assertShouldAllowOnlyResourceDescriptionMethods();
}
private void assertShouldContainLinkToTheBinary() {
assertTrue("Should contain a link to the binary",
mockResponse.getHeaders(LINK)
.contains("<" + idTranslator.toDomain(binaryPath) + ">; rel=\"describes\""));
}
private void assertShouldAdvertiseAcceptPatchFlavors() {
assertTrue("Should advertise Accept-Patch flavors", mockResponse.containsHeader(HTTP_HEADER_ACCEPT_PATCH));
}
@Test
public void testOption() throws Exception {
setResource(FedoraResource.class);
final Response actual = testObj.options();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should have an Allow header", mockResponse.containsHeader("Allow"));
}
@Test
public void testOptionWithObject() throws Exception {
setResource(Container.class);
final Response actual = testObj.options();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
assertShouldAdvertiseAcceptPatchFlavors();
}
@Test
public void testOptionWithBinary() throws Exception {
final FedoraBinary mockResource = (FedoraBinary)setResource(FedoraBinary.class);
when(mockResource.getDescription()).thenReturn(mockNonRdfSourceDescription);
final Response actual = testObj.options();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldNotAdvertiseAcceptPostFlavors();
assertShouldNotAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToBinaryDescription();
}
@Test
public void testOptionWithBinaryDescription() throws Exception {
final NonRdfSourceDescription mockResource
= (NonRdfSourceDescription)setResource(NonRdfSourceDescription.class);
when(mockResource.getDescribedResource()).thenReturn(mockBinary);
final Response actual = testObj.options();
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldNotAdvertiseAcceptPostFlavors();
assertShouldAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToTheBinary();
}
@Test
public void testGet() throws Exception {
setResource(FedoraResource.class);
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should have a Link header", mockResponse.containsHeader(LINK));
assertTrue("Should have an Allow header", mockResponse.containsHeader("Allow"));
assertTrue("Should be an LDP Resource",
mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE + "Resource>;rel=\"type\""));
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
assertTrue("Expected RDF contexts missing", rdfNodes.containsAll(ImmutableSet.of(
"LDP_CONTAINMENT", "LDP_MEMBERSHIP", "PROPERTIES", "SERVER_MANAGED")));
}
}
@Test
public void testGetWithObject() throws Exception {
setResource(Container.class);
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should advertise Accept-Post flavors", mockResponse.containsHeader("Accept-Post"));
assertShouldAdvertiseAcceptPatchFlavors();
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
assertTrue("Expected RDF contexts missing", rdfNodes.containsAll(ImmutableSet.of(
"LDP_CONTAINMENT", "LDP_MEMBERSHIP", "PROPERTIES", "SERVER_MANAGED")));
}
}
@Test
public void testGetWithBasicContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_BASIC_CONTAINER)).thenReturn(true);
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPBasicContainer();
}
@Test
public void testGetWithDirectContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_DIRECT_CONTAINER)).thenReturn(true);
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPDirectContainer();
}
@Test
public void testGetWithIndirectContainer() throws Exception {
final FedoraResource resource = setResource(Container.class);
when(resource.hasType(LDP_INDIRECT_CONTAINER)).thenReturn(true);
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPIndirectContainer();
}
@Test
public void testGetWithObjectPreferMinimal() throws Exception {
setResource(Container.class);
setField(testObj, "prefer", new MultiPrefer("return=minimal"));
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
assertTrue("Expected RDF contexts missing", rdfNodes.stream()
.filter(x -> x.contains("PROPERTIES") && x.contains("MINIMAL")).findFirst().isPresent());
assertFalse("Included non-minimal contexts", rdfNodes.contains("LDP_MEMBERSHIP"));
assertFalse("Included non-minimal contexts", rdfNodes.contains("LDP_CONTAINMENT"));
}
}
/**
* Emulates an 'If-None-Match' precondition failing for a GET request. There should not be any entity body set
* on the response.
*
* @throws Exception if something exceptional happens
*/
@Test
public void testGetWhenIfNoneMatchPreconditionFails() throws Exception {
setResource(FedoraResource.class);
// Set up the expectations for the ResponseBuilder
final Response.ResponseBuilder builder = mock(Response.ResponseBuilder.class);
when(builder.entity(any())).thenReturn(builder);
when(builder.cacheControl(any())).thenReturn(builder);
when(builder.lastModified((any()))).thenReturn(builder);
when(builder.tag(any(EntityTag.class))).thenReturn(builder);
// Set up expectations for the Request; returning a ResponseBuilder from evaluatePreconditions(...) indicates
// that satisfying the precondition fails, which is what we want to simulate in this test
when(mockRequest.evaluatePreconditions(any(EntityTag.class))).thenReturn(builder);
// Execute the method under test. Preconditions should fail, resulting in an exception being thrown.
try {
testObj.evaluateRequestPreconditions(mockRequest, mockResponse, testObj.resource(),
mockSession, true);
fail("Expected " + WebApplicationException.class.getName() + " to be thrown.");
} catch (WebApplicationException e) {
// expected
}
// an entity body should _not_ be set under these conditions
verify(mockRequest).evaluatePreconditions(any(EntityTag.class));
verify(builder, times(0)).entity(any());
}
/**
* Emulates an 'If-Modified-Since' precondition failing for a GET request. There should not be any entity body set
* on the response.
*
* @throws Exception if something exceptional happens
*/
@Test
public void testGetWhenIfModifiedSincePreconditionFails() throws Exception {
setResource(FedoraResource.class);
// Set up the expectations for the ResponseBuilder
final Response.ResponseBuilder builder = mock(Response.ResponseBuilder.class);
when(builder.entity(any())).thenReturn(builder);
when(builder.cacheControl(any())).thenReturn(builder);
when(builder.lastModified((any()))).thenReturn(builder);
when(builder.tag(any(EntityTag.class))).thenReturn(builder);
// Set up expectations for the Request; returning a ResponseBuilder from evaluatePreconditions(...) indicates
// that satisfying the precondition fails, which is what we want to simulate in this test
when(mockRequest.evaluatePreconditions(any(Date.class))).thenReturn(builder);
// Execute the method under test. Preconditions should fail, resulting in an exception being thrown.
try {
testObj.evaluateRequestPreconditions(mockRequest, mockResponse, testObj.resource(),
mockSession, true);
fail("Expected " + WebApplicationException.class.getName() + " to be thrown.");
} catch (WebApplicationException e) {
// expected
}
// an entity body should _not_ be set under these conditions
verify(mockRequest).evaluatePreconditions(any(Date.class));
verify(builder, times(0)).entity(any());
}
@Test
public void testGetWithObjectOmitContainment() throws Exception {
setResource(Container.class);
setField(testObj, "prefer",
new MultiPrefer("return=representation; omit=\"" + LDP_NAMESPACE + "PreferContainment\""));
final Response actual = testObj.getResource( null);
assertEquals(OK.getStatusCode(), actual.getStatus());
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
assertTrue("Should include membership contexts", rdfNodes.contains("LDP_MEMBERSHIP"));
assertFalse("Should not include containment contexts", rdfNodes.contains("LDP_CONTAINMENT"));
}
}
@Test
public void testGetWithObjectOmitMembership() throws Exception {
setResource(Container.class);
setField(testObj, "prefer",
new MultiPrefer("return=representation; omit=\"" + LDP_NAMESPACE + "PreferMembership\""));
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
assertFalse("Should not include membership contexts", rdfNodes.contains("LDP_MEMBERSHIP"));
assertTrue("Should include containment contexts", rdfNodes.contains("LDP_CONTAINMENT"));
}
}
@Test
public void testGetWithObjectIncludeReferences() throws ParseException, IOException {
setResource(Container.class);
setField(testObj, "prefer", new MultiPrefer("return=representation; include=\"" + INBOUND_REFERENCES + "\""));
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
try (final RdfNamespacedStream entity = (RdfNamespacedStream) actual.getEntity()) {
final Model model = entity.stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
log.debug("Received RDF nodes: {}", rdfNodes);
assertTrue("Should include references contexts",
rdfNodes.stream().anyMatch(containsPattern("REFERENCES")::apply));
}
}
@Test
public void testGetWithBinary() throws Exception {
final FedoraBinary mockResource = (FedoraBinary)setResource(FedoraBinary.class);
when(mockResource.getDescription()).thenReturn(mockNonRdfSourceDescription);
when(mockResource.getMimeType()).thenReturn("text/plain");
when(mockResource.getContent()).thenReturn(toInputStream("xyz", UTF_8));
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertShouldBeAnLDPNonRDFSource();
assertShouldNotAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToBinaryDescription();
assertTrue(IOUtils.toString((InputStream)actual.getEntity(), UTF_8).equals("xyz"));
}
private void assertShouldBeAnLDPNonRDFSource() {
assertTrue("Should be an LDP NonRDFSource",
mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\""));
assertShouldNotAdvertiseAcceptPostFlavors();
}
@Test
public void testGetWithExternalMessageBinary() throws Exception {
final FedoraBinary mockResource = (FedoraBinary)setResource(FedoraBinary.class);
when(mockResource.getDescription()).thenReturn(mockNonRdfSourceDescription);
when(mockResource.getMimeType()).thenReturn("message/external-body; access-type=URL; URL=\"some:uri\"");
when(mockResource.getContent()).thenReturn(toInputStream("xyz", UTF_8));
final Response actual = testObj.getResource(null);
assertEquals(TEMPORARY_REDIRECT.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP NonRDFSource", mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE +
"NonRDFSource>;rel=\"type\""));
assertShouldContainLinkToBinaryDescription();
assertEquals(new URI("some:uri"), actual.getLocation());
}
@Test
@SuppressWarnings({"resource", "unchecked"})
public void testGetWithBinaryDescription() throws IOException {
final NonRdfSourceDescription mockResource
= (NonRdfSourceDescription)setResource(NonRdfSourceDescription.class);
when(mockResource.getDescribedResource()).thenReturn(mockBinary);
when(mockBinary.getTriples(eq(idTranslator), any(TripleCategory.class)))
.thenReturn(new DefaultRdfStream(createURI("mockBinary")));
when(mockBinary.getTriples(eq(idTranslator), any(EnumSet.class)))
.thenReturn(new DefaultRdfStream(createURI("mockBinary"), of(new Triple
(createURI("mockBinary"), createURI("called"), createURI("child:properties")))));
final Response actual = testObj.getResource(null);
assertEquals(OK.getStatusCode(), actual.getStatus());
assertTrue("Should be an LDP RDFSource",
mockResponse.getHeaders(LINK).contains("<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\""));
assertShouldNotAdvertiseAcceptPostFlavors();
assertShouldAdvertiseAcceptPatchFlavors();
assertShouldContainLinkToTheBinary();
assertShouldAllowOnlyResourceDescriptionMethods();
final Model model = ((RdfNamespacedStream) actual.getEntity()).stream.collect(toModel());
final List<String> rdfNodes = model.listObjects().mapWith(RDFNode::toString).toList();
log.info("Found RDF objects\n{}", rdfNodes);
assertTrue("Expected RDF contexts missing", rdfNodes.containsAll(ImmutableSet.of(
"LDP_CONTAINMENT", "LDP_MEMBERSHIP", "PROPERTIES", "SERVER_MANAGED")));
}
private void assertShouldAllowOnlyResourceDescriptionMethods() {
final String[] allows = mockResponse.getHeader(HttpHeaders.ALLOW).split(",");
final Set<String> allowedMethods = new HashSet<>(Arrays.asList(allows));
final Set<String> validMethods = ImmutableSet.of("GET", "HEAD", "DELETE", "PUT", "PATCH",
"OPTIONS");
allowedMethods.removeAll(validMethods);
assertEquals("Allow header contains invalid methods: " + allowedMethods, 0, allowedMethods.size());
}
@Test
public void testDelete() throws Exception {
final FedoraResource fedoraResource = setResource(FedoraResource.class);
final Response actual = testObj.deleteObject();
assertEquals(NO_CONTENT.getStatusCode(), actual.getStatus());
verify(fedoraResource).delete();
}
@Test
public void testPutNewObject() throws Exception {
setField(testObj, "externalPath", "some/path");
final FedoraBinary mockObject = (FedoraBinary)setResource(FedoraBinary.class);
doReturn(mockObject).when(testObj).resource();
when(mockContainer.isNew()).thenReturn(true);
when(mockNodeService.exists(mockFedoraSession, "/some/path")).thenReturn(false);
when(mockContainerService.findOrCreate(mockFedoraSession, "/some/path")).thenReturn(mockContainer);
final Response actual = testObj.createOrReplaceObjectRdf(null, null, null, null, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
}
@Test(expected = CannotCreateResourceException.class)
public void testPutNewObjectLdpr() throws Exception {
testObj.createOrReplaceObjectRdf(null, null, null, null,
"<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"", null);
}
@Test
public void testPutNewObjectWithRdf() throws Exception {
setField(testObj, "externalPath", "some/path");
final FedoraBinary mockObject = (FedoraBinary)setResource(FedoraBinary.class);
doReturn(mockObject).when(testObj).resource();
when(mockContainer.isNew()).thenReturn(true);
when(mockNodeService.exists(mockFedoraSession, "/some/path")).thenReturn(false);
when(mockContainerService.findOrCreate(mockFedoraSession, "/some/path")).thenReturn(mockContainer);
final Response actual = testObj.createOrReplaceObjectRdf(NTRIPLES_TYPE,
toInputStream("_:a <info:x> _:c .", UTF_8), null, null, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockContainer).replaceProperties(eq(idTranslator), any(Model.class), any(RdfStream.class));
}
@Test
public void testPutNewBinary() throws Exception {
setField(testObj, "externalPath", "some/path");
final FedoraBinary mockObject = (FedoraBinary)setResource(FedoraBinary.class);
doReturn(mockObject).when(testObj).resource();
when(mockBinary.isNew()).thenReturn(true);
when(mockNodeService.exists(mockFedoraSession, "/some/path")).thenReturn(false);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/some/path")).thenReturn(mockBinary);
final Response actual = testObj.createOrReplaceObjectRdf(TEXT_PLAIN_TYPE,
toInputStream("xyz", UTF_8), null, null, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
}
@Test
public void testPutReplaceRdfObject() throws Exception {
setField(testObj, "externalPath", "some/path");
final Container mockObject = (Container)setResource(Container.class);
doReturn(mockObject).when(testObj).resource();
when(mockObject.isNew()).thenReturn(false);
when(mockNodeService.exists(mockFedoraSession, "/some/path")).thenReturn(true);
when(mockContainerService.findOrCreate(mockFedoraSession, "/some/path")).thenReturn(mockObject);
final Response actual = testObj.createOrReplaceObjectRdf(NTRIPLES_TYPE,
toInputStream("_:a <info:x> _:c .", UTF_8), null, null, null, null);
assertEquals(NO_CONTENT.getStatusCode(), actual.getStatus());
verify(mockObject).replaceProperties(eq(idTranslator), any(Model.class), any(RdfStream.class));
}
@Test(expected = ClientErrorException.class)
public void testPutWithStrictIfMatchHandling() throws Exception {
when(mockHttpConfiguration.putRequiresIfMatch()).thenReturn(true);
final Container mockObject = (Container)setResource(Container.class);
doReturn(mockObject).when(testObj).resource();
when(mockObject.isNew()).thenReturn(false);
when(mockNodeService.exists(mockFedoraSession, "/some/path")).thenReturn(true);
when(mockContainerService.findOrCreate(mockFedoraSession, "/some/path")).thenReturn(mockObject);
testObj.createOrReplaceObjectRdf(NTRIPLES_TYPE,
toInputStream("_:a <info:x> _:c .", UTF_8), null, null, null, null);
}
@Test
public void testPatchObject() throws Exception {
setResource(Container.class);
testObj.updateSparql(toInputStream("xyz", UTF_8));
}
@Test
@SuppressWarnings({"resource", "unchecked"})
public void testPatchBinaryDescription() throws MalformedRdfException, IOException {
final NonRdfSourceDescription mockObject = (NonRdfSourceDescription)setResource(NonRdfSourceDescription.class);
when(mockObject.getDescribedResource()).thenReturn(mockBinary);
when(mockBinary.getTriples(eq(idTranslator), any(TripleCategory.class)))
.thenReturn(new DefaultRdfStream(createURI("mockBinary")));
when(mockBinary.getTriples(eq(idTranslator), any(EnumSet.class)))
.thenReturn(new DefaultRdfStream(createURI("mockBinary"),
of(new Triple(createURI("mockBinary"), createURI("called"),
createURI("child:properties")))));
doReturn(mockObject).when(testObj).resource();
testObj.updateSparql(toInputStream("xyz", UTF_8));
}
@Test(expected = BadRequestException.class)
public void testPatchWithoutContent() throws MalformedRdfException, IOException {
testObj.updateSparql(null);
}
@Test(expected = BadRequestException.class)
public void testPatchWithMissingContent() throws MalformedRdfException, IOException {
setResource(Container.class);
testObj.updateSparql(toInputStream("", UTF_8));
}
@Test(expected = BadRequestException.class)
public void testPatchBinary() throws MalformedRdfException, IOException {
setResource(FedoraBinary.class);
testObj.updateSparql(toInputStream("", UTF_8));
}
@Test
public void testCreateNewObject() throws MalformedRdfException, InvalidChecksumException,
IOException {
setResource(Container.class);
when(mockContainerService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockContainer);
final Response actual = testObj.createObject(null, null, "b", null, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
}
@Test
public void testCreateNewObjectWithSparql() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockContainerService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockContainer);
final Response actual = testObj.createObject(null,
MediaType.valueOf(contentTypeSPARQLUpdate), "b", toInputStream("x", UTF_8), null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockContainer).updateProperties(eq(idTranslator), eq("x"), any(RdfStream.class));
}
@Test
public void testCreateNewObjectWithRdf() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockContainerService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockContainer);
final Response actual = testObj.createObject(null, NTRIPLES_TYPE, "b",
toInputStream("_:a <info:b> _:c .", UTF_8), null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockContainer).replaceProperties(eq(idTranslator), any(Model.class), any(RdfStream.class));
}
@Test
public void testCreateNewBinary() throws MalformedRdfException, InvalidChecksumException,
IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final Response actual = testObj.createObject(null, APPLICATION_OCTET_STREAM_TYPE, "b", content, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockBinary).setContent(content, APPLICATION_OCTET_STREAM, Collections.emptySet(), "", null);
}
}
@Test(expected = InsufficientStorageException.class)
public void testCreateNewBinaryWithInsufficientResources() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final RuntimeException ex = new RuntimeException(new IOException("root exception", new IOException(
FedoraLdp.INSUFFICIENT_SPACE_IDENTIFYING_MESSAGE)));
doThrow(ex).when(mockBinary).setContent(content, APPLICATION_OCTET_STREAM_TYPE.toString(),
Collections
.emptySet(),
"", null);
testObj.createObject(null, APPLICATION_OCTET_STREAM_TYPE, "b", content, null, null);
}
}
@Test
public void testCreateNewBinaryWithContentTypeWithParams() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final MediaType requestContentType = MediaType.valueOf("some/mime-type; with=some; param=s");
final Response actual = testObj.createObject(null, requestContentType, "b", content, null, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockBinary).setContent(content, requestContentType.toString(), Collections.emptySet(), "", null);
}
}
@Test
public void testCreateNewBinaryWithChecksumSHA() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final MediaType requestContentType = MediaType.valueOf("some/mime-type; with=some; param=s");
final String sha = "07a4d371f3b7b6283a8e1230b7ec6764f8287bf2";
final String requestSHA = "sha1=" + sha;
final Set<URI> shaURI = singleton(URI.create("urn:sha1:" + sha));
final Response actual = testObj.createObject(null, requestContentType, "b", content, null, requestSHA);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockBinary).setContent(content, requestContentType.toString(), shaURI, "", null);
}
}
@Test
public void testCreateNewBinaryWithChecksumMD5() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final MediaType requestContentType = MediaType.valueOf("some/mime-type; with=some; param=s");
final String md5 = "HUXZLQLMuI/KZ5KDcJPcOA==";
final String requestMD5 = "md5=" + md5;
final Set<URI> md5URI = singleton(URI.create("urn:md5:" + md5));
final Response actual = testObj.createObject(null, requestContentType, "b", content, null, requestMD5);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockBinary).setContent(content, requestContentType.toString(), md5URI, "", null);
}
}
@Test
public void testCreateNewBinaryWithChecksumSHAandMD5() throws MalformedRdfException,
InvalidChecksumException, IOException {
setResource(Container.class);
when(mockBinaryService.findOrCreate(mockFedoraSession, "/b")).thenReturn(mockBinary);
try (final InputStream content = toInputStream("x", UTF_8)) {
final MediaType requestContentType = MediaType.valueOf("some/mime-type; with=some; param=s");
final String sha = "07a4d371f3b7b6283a8e1230b7ec6764f8287bf2";
final String requestSHA = "sha1=" + sha;
final URI shaURI = URI.create("urn:sha1:" + sha);
final String md5 = "HUXZLQLMuI/KZ5KDcJPcOA==";
final String requestMD5 = "md5=" + md5;
final URI md5URI = URI.create("urn:md5:" + md5);
final String requestChecksum = requestSHA + "," + requestMD5;
final HashSet<URI> checksumURIs = new HashSet<>(asList(shaURI, md5URI));
final Response actual = testObj.createObject(null, requestContentType, "b", content, null, requestChecksum);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockBinary).setContent(content, requestContentType.toString(), checksumURIs, "", null);
}
}
@Test(expected = ClientErrorException.class)
public void testPostToBinary() throws MalformedRdfException, InvalidChecksumException, IOException {
final FedoraBinary mockObject = (FedoraBinary)setResource(FedoraBinary.class);
doReturn(mockObject).when(testObj).resource();
testObj.createObject(null, null, null, null, null, null);
}
@Test(expected = CannotCreateResourceException.class)
public void testLDPRNotImplemented() throws ConstraintViolationException, InvalidChecksumException,
IOException {
testObj.createObject(null, null, null, null, "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"", null);
}
@Test(expected = ClientErrorException.class)
public void testLDPRNotImplementedInvalidLink() throws MalformedRdfException, InvalidChecksumException,
IOException {
testObj.createObject(null, null, null, null, "Link: <http://www.w3.org/ns/ldp#Resource;rel=type", null);
}
@Test
public void testGetSimpleContentType() {
final MediaType mediaType = new MediaType("text", "plain", ImmutableMap.of("charset", "UTF-8"));
final MediaType sanitizedMediaType = getSimpleContentType(mediaType);
assertEquals("text/plain", sanitizedMediaType.toString());
}
/**
* Demonstrates that when the {@link FedoraBaseResource#JMS_BASEURL_PROP fcrepo.jms.baseUrl} system property is not
* set, the url used for JMS messages is the same as the base url found in the {@code UriInfo}.
* <p>
* Implementation note: this test requires a concrete instance of {@link UriInfo}, because it is the interaction of
* {@code javax.ws.rs.core.UriBuilder} and {@code FedoraBaseResource} that is being tested.
* </p>
*/
@Test
public void testJmsBaseUrlDefault() {
// Obtain a concrete instance of UriInfo
final URI baseUri = create("http://localhost/fcrepo");
final URI requestUri = create("http://localhost/fcrepo/foo");
final ContainerRequest req = new ContainerRequest(baseUri, requestUri, "GET", mock(SecurityContext.class),
mock(PropertiesDelegate.class));
final UriInfo info = spy(req.getUriInfo());
final String expectedBaseUrl = baseUri.toString();
testObj.setUpJMSInfo(info, mockHeaders);
verify(mockFedoraSession).addSessionData(BASE_URL, expectedBaseUrl);
verify(info, times(0)).getBaseUriBuilder();
verify(info).getBaseUri();
}
/**
* Demonstrates that the host supplied by the {@link FedoraBaseResource#JMS_BASEURL_PROP fcrepo.jms.baseUrl} system
* property is used as the as the base url for JMS messages, and not the base url found in {@code UriInfo}.
* <p>
* Note: the path from the request is preserved, the host from the fcrepo.jms.baseUrl is used
* </p>
* <p>
* Implementation note: this test requires a concrete instance of {@link UriInfo}, because it is the interaction of
* {@code javax.ws.rs.core.UriBuilder} and {@code FedoraBaseResource} that is being tested.
* </p>
*/
@Test
public void testJmsBaseUrlOverrideHost() {
// Obtain a concrete implementation of UriInfo
final URI baseUri = create("http://localhost/fcrepo");
final URI requestUri = create("http://localhost/fcrepo/foo");
final ContainerRequest req = new ContainerRequest(baseUri, requestUri, "GET", mock(SecurityContext.class),
mock(PropertiesDelegate.class));
final UriInfo info = spy(req.getUriInfo());
final String baseUrl = "http://example.org";
final String expectedBaseUrl = baseUrl + baseUri.getPath();
System.setProperty(JMS_BASEURL_PROP, baseUrl);
testObj.setUpJMSInfo(info, mockHeaders);
verify(mockFedoraSession).addSessionData(BASE_URL, expectedBaseUrl);
verify(info).getBaseUriBuilder();
System.clearProperty(JMS_BASEURL_PROP);
}
/**
* Demonstrates that the host and port supplied by the {@link FedoraBaseResource#JMS_BASEURL_PROP
* fcrepo.jms.baseUrl} system property is used as the as the base url for JMS messages, and not the base url found
* in {@code UriInfo}.
* <p>
* Note: the path from the request is preserved, but the host and port from the request is overridden by the values
* from fcrepo.jms.baseUrl
* </p>
* <p>
* Implementation note: this test requires a concrete instance of {@link UriInfo}, because it is the interaction of
* {@code javax.ws.rs.core.UriBuilder} and {@code FedoraBaseResource} that is being tested.
* </p>
*/
@Test
public void testJmsBaseUrlOverrideHostAndPort() {
// Obtain a concrete implementation of UriInfo
final URI baseUri = create("http://localhost/fcrepo");
final URI requestUri = create("http://localhost/fcrepo/foo");
final ContainerRequest req = new ContainerRequest(baseUri, requestUri, "GET", mock(SecurityContext.class),
mock(PropertiesDelegate.class));
final UriInfo info = spy(req.getUriInfo());
final String baseUrl = "http://example.org:9090";
final String expectedBaseUrl = baseUrl + baseUri.getPath();
System.setProperty(JMS_BASEURL_PROP, baseUrl);
testObj.setUpJMSInfo(info, mockHeaders);
verify(mockFedoraSession).addSessionData(BASE_URL, expectedBaseUrl);
verify(info).getBaseUriBuilder();
System.clearProperty(JMS_BASEURL_PROP);
}
/**
* Demonstrates that the url supplied by the {@link FedoraBaseResource#JMS_BASEURL_PROP fcrepo.jms.baseUrl} system
* property is used as the as the base url for JMS messages, and not the base url found in {@code UriInfo}.
* <p>
* Note: the host and path from the request is overridden by the values from fcrepo.jms.baseUrl
* </p>
* <p>
* Implementation note: this test requires a concrete instance of {@link UriInfo}, because it is the interaction of
* {@code javax.ws.rs.core.UriBuilder} and {@code FedoraBaseResource} that is being tested.
* </p>
*/
@Test
public void testJmsBaseUrlOverrideUrl() {
// Obtain a concrete implementation of UriInfo
final URI baseUri = create("http://localhost/fcrepo");
final URI requestUri = create("http://localhost/fcrepo/foo");
final ContainerRequest req = new ContainerRequest(baseUri, requestUri, "GET", mock(SecurityContext.class),
mock(PropertiesDelegate.class));
final UriInfo info = spy(req.getUriInfo());
final String expectedBaseUrl = "http://example.org/fcrepo/rest";
System.setProperty(JMS_BASEURL_PROP, expectedBaseUrl);
testObj.setUpJMSInfo(info, mockHeaders);
verify(mockFedoraSession).addSessionData(BASE_URL, expectedBaseUrl);
verify(info).getBaseUriBuilder();
System.clearProperty(JMS_BASEURL_PROP);
}
/**
* Demonstrates that when the the base url in {@code UriInfo} contains a port number, and the base url defined by
* {@link FedoraBaseResource#JMS_BASEURL_PROP fcrepo.jms.baseUrl} does <em>not</em> contain a port number, that the
* base url for JMS messages does not contain a port number.
* <p>
* Note: the host, port, and path from the request is overridden by values from fcrepo.jms.baseUrl
* </p>
* <p>
* Implementation note: this test requires a concrete instance of {@link UriInfo}, because it is the interaction of
* {@code javax.ws.rs.core.UriBuilder} and {@code FedoraBaseResource} that is being tested.
* </p>
*/
@Test
public void testJmsBaseUrlOverrideRequestUrlWithPort8080() {
// Obtain a concrete implementation of UriInfo
final URI baseUri = create("http://localhost:8080/fcrepo/rest");
final URI reqUri = create("http://localhost:8080/fcrepo/rest/foo");
final ContainerRequest req = new ContainerRequest(baseUri, reqUri, "GET", mock(SecurityContext.class),
mock(PropertiesDelegate.class));
final UriInfo info = spy(req.getUriInfo());
final String expectedBaseUrl = "http://example.org/fcrepo/rest/";
System.setProperty(JMS_BASEURL_PROP, expectedBaseUrl);
testObj.setUpJMSInfo(info, mockHeaders);
verify(mockFedoraSession).addSessionData(BASE_URL, expectedBaseUrl);
verify(info).getBaseUriBuilder();
System.clearProperty(JMS_BASEURL_PROP);
}
}