001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.integration;
019
020import static java.lang.Integer.MAX_VALUE;
021import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
022import static javax.ws.rs.core.HttpHeaders.LINK;
023import static org.apache.http.HttpStatus.SC_BAD_REQUEST;
024import static org.apache.http.HttpStatus.SC_CONFLICT;
025import static org.apache.http.HttpStatus.SC_CREATED;
026import static org.apache.http.HttpStatus.SC_NO_CONTENT;
027import static org.apache.http.HttpStatus.SC_OK;
028import static org.fcrepo.kernel.api.RdfLexicon.CONSTRAINED_BY;
029import static org.junit.Assert.assertEquals;
030
031import java.io.IOException;
032import java.net.URI;
033
034import org.apache.http.HttpResponse;
035import org.apache.http.auth.AuthScope;
036import org.apache.http.client.CredentialsProvider;
037import org.apache.http.client.HttpClient;
038import org.apache.http.client.methods.HttpGet;
039import org.apache.http.client.methods.HttpPost;
040import org.apache.http.client.methods.HttpPut;
041import org.apache.http.client.methods.HttpUriRequest;
042import org.apache.http.entity.StringEntity;
043import org.apache.http.impl.client.HttpClientBuilder;
044import org.apache.http.util.EntityUtils;
045import org.junit.Before;
046import org.junit.Test;
047import org.slf4j.Logger;
048import org.slf4j.LoggerFactory;
049
050import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
051
052import javax.ws.rs.core.Link;
053
054/**
055 * <p>SanityCheckIT class.</p>
056 *
057 * @author fasseg
058 */
059public class SanityCheckIT {
060
061    /**
062     * The server port of the application, set as system property by
063     * maven-failsafe-plugin.
064     */
065    private static final String SERVER_PORT = System.getProperty("fcrepo.dynamic.test.port");
066
067    /**
068    * The context path of the application (including the leading "/"), set as
069    * system property by maven-failsafe-plugin.
070    */
071    private static final String CONTEXT_PATH = System
072            .getProperty("fcrepo.test.context.path");
073
074    private Logger logger;
075
076    @Before
077    public void setLogger() {
078        logger = LoggerFactory.getLogger(this.getClass());
079    }
080
081    private static final String HOSTNAME = "localhost";
082
083    private static final String serverAddress = "http://" + HOSTNAME + ":" +
084            SERVER_PORT + CONTEXT_PATH;
085
086    private static final HttpClient client;
087
088    static {
089        final CredentialsProvider creds = new DefaultCredentialsProvider();
090        creds.setCredentials(AuthScope.ANY, AbstractResourceIT.FEDORA_ADMIN_CREDENTIALS);
091        client =
092                HttpClientBuilder.create().setMaxConnPerRoute(MAX_VALUE)
093                        .setMaxConnTotal(MAX_VALUE).setDefaultCredentialsProvider(creds).build();
094    }
095
096    @Test
097    public void doASanityCheck() throws IOException {
098        executeAndVerify(new HttpGet(serverAddress + "rest/"), SC_OK);
099    }
100
101    private HttpResponse executeAndVerify(final HttpUriRequest method, final int statusCode) throws IOException {
102        logger.debug("Executing: " + method.getMethod() + " to " + method.getURI());
103        final HttpResponse response = client.execute(method);
104
105        assertEquals(statusCode, response.getStatusLine().getStatusCode());
106        return response;
107    }
108
109    @Test
110    public void testConstraintLink() throws Exception {
111        // Create a resource
112        final HttpPost post = new HttpPost(serverAddress + "rest/");
113        final HttpResponse postResponse = executeAndVerify(post, SC_CREATED);
114
115        final String location = postResponse.getFirstHeader("Location").getValue();
116        logger.debug("new resource location: {}", location);
117
118        // GET the new resource
119        final HttpGet get = new HttpGet(location);
120        final HttpResponse getResponse = executeAndVerify(get, SC_OK);
121
122        final String body = EntityUtils.toString(getResponse.getEntity());
123        logger.debug("new resource body: {}", body);
124
125        // PUT the exact body back to the new resource... successfully
126        final HttpPut put = new HttpPut(location);
127        put.setEntity(new StringEntity(body));
128        put.setHeader(CONTENT_TYPE, "text/turtle");
129        executeAndVerify(put, SC_NO_CONTENT);
130
131        // Update a server managed property in the resource body... not allowed!
132        final String body2 = body.replaceFirst("fedora:created \"2\\d\\d\\d", "fedora:created \"1999");
133
134        // PUT the erroneous body back to the new resource... unsuccessfully
135        final HttpPut put2 = new HttpPut(location);
136        put2.setEntity(new StringEntity(body2));
137        put2.setHeader(CONTENT_TYPE, "text/turtle");
138        final HttpResponse put2Response = executeAndVerify(put2, SC_CONFLICT);
139
140        // Verify the returned LINK header
141        final String linkHeader = put2Response.getFirstHeader(LINK).getValue();
142        final Link link = Link.valueOf(linkHeader);
143        logger.debug("constraint linkHeader: {}", linkHeader);
144
145        // Verify the LINK rel
146        final String linkRel = link.getRel();
147        assertEquals(CONSTRAINED_BY.getURI(), linkRel);
148
149        // Verify the LINK URI by fetching it
150        final URI linkURI = link.getUri();
151        logger.debug("constraint linkURI: {}", linkURI);
152
153        final HttpGet getLink = new HttpGet(linkURI);
154        executeAndVerify(getLink, SC_OK);
155    }
156
157    @Test
158    public void testCannotCreateResourceConstraintLink() throws Exception {
159        // Create a ldp:Resource resource, this should fail
160        final HttpPost post = new HttpPost(serverAddress + "rest/");
161        post.setHeader(LINK,"<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"");
162        final HttpResponse postResponse = executeAndVerify(post, SC_BAD_REQUEST);
163
164        // Verify the returned LINK header
165        final String linkHeader = postResponse.getFirstHeader(LINK).getValue();
166        final Link link = Link.valueOf(linkHeader);
167        logger.debug("constraint linkHeader: {}", linkHeader);
168
169        // Verify the LINK rel
170        final String linkRel = link.getRel();
171        assertEquals(CONSTRAINED_BY.getURI(), linkRel);
172
173        // Verify the LINK URI by fetching it
174        final URI linkURI = link.getUri();
175        logger.debug("constraint linkURI: {}", linkURI);
176
177        final HttpGet getLink = new HttpGet(linkURI);
178        executeAndVerify(getLink, SC_OK);
179    }
180}