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; 033import java.util.Objects; 034 035import com.google.common.base.Strings; 036import org.apache.http.HttpResponse; 037import org.apache.http.auth.AuthScope; 038import org.apache.http.client.CredentialsProvider; 039import org.apache.http.client.HttpClient; 040import org.apache.http.client.methods.HttpGet; 041import org.apache.http.client.methods.HttpPost; 042import org.apache.http.client.methods.HttpPut; 043import org.apache.http.client.methods.HttpUriRequest; 044import org.apache.http.entity.StringEntity; 045import org.apache.http.impl.client.HttpClientBuilder; 046import org.apache.http.util.EntityUtils; 047import org.junit.Before; 048import org.junit.Test; 049import org.slf4j.Logger; 050import org.slf4j.LoggerFactory; 051 052import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider; 053 054import javax.ws.rs.core.Link; 055 056/** 057 * <p>SanityCheckIT class.</p> 058 * 059 * @author fasseg 060 */ 061public class SanityCheckIT { 062 063 /** 064 * The server port of the application, set as system property by 065 * maven-failsafe-plugin. 066 */ 067 private static final String SERVER_PORT = Objects.requireNonNullElse( 068 Strings.emptyToNull(System.getProperty("fcrepo.dynamic.test.port")), "8080"); 069 070 /** 071 * The context path of the application (including the leading "/"), set as 072 * system property by maven-failsafe-plugin. 073 */ 074 private static final String CONTEXT_PATH = System.getProperty("fcrepo.test.context.path"); 075 076 private Logger logger; 077 078 @Before 079 public void setLogger() { 080 logger = LoggerFactory.getLogger(this.getClass()); 081 } 082 083 private static final String HOSTNAME = "localhost"; 084 085 private static final String serverAddress = "http://" + HOSTNAME + ":" + 086 SERVER_PORT + CONTEXT_PATH + (CONTEXT_PATH.endsWith("/") ? "" : "/") + "rest"; 087 088 private static final HttpClient client; 089 090 static { 091 final CredentialsProvider creds = new DefaultCredentialsProvider(); 092 creds.setCredentials(AuthScope.ANY, AbstractResourceIT.FEDORA_ADMIN_CREDENTIALS); 093 client = 094 HttpClientBuilder.create().setMaxConnPerRoute(MAX_VALUE) 095 .setMaxConnTotal(MAX_VALUE).setDefaultCredentialsProvider(creds).build(); 096 } 097 098 @Test 099 public void doASanityCheck() throws IOException { 100 executeAndVerify(new HttpGet(serverAddress), SC_OK); 101 } 102 103 private HttpResponse executeAndVerify(final HttpUriRequest method, final int statusCode) throws IOException { 104 logger.debug("Executing: " + method.getMethod() + " to " + method.getURI()); 105 final HttpResponse response = client.execute(method); 106 107 assertEquals(statusCode, response.getStatusLine().getStatusCode()); 108 return response; 109 } 110 111 @Test 112 public void testConstraintLink() throws Exception { 113 // Create a resource 114 final HttpPost post = new HttpPost(serverAddress); 115 final HttpResponse postResponse = executeAndVerify(post, SC_CREATED); 116 117 final String location = postResponse.getFirstHeader("Location").getValue(); 118 logger.debug("new resource location: {}", location); 119 120 // GET the new resource 121 final HttpGet get = new HttpGet(location); 122 final HttpResponse getResponse = executeAndVerify(get, SC_OK); 123 124 final String body = EntityUtils.toString(getResponse.getEntity()); 125 logger.debug("new resource body: {}", body); 126 127 // PUT the exact body back to the new resource... successfully 128 final HttpPut put = new HttpPut(location); 129 put.setEntity(new StringEntity(body)); 130 put.setHeader(CONTENT_TYPE, "text/turtle"); 131 put.setHeader("Prefer", "handling=lenient"); 132 executeAndVerify(put, SC_NO_CONTENT); 133 134 // Update a server managed property in the resource body... not allowed! 135 final String body2 = body.replaceFirst("fedora:created \"2\\d\\d\\d", "fedora:created \"1999"); 136 137 // PUT the erroneous body back to the new resource... unsuccessfully 138 final HttpPut put2 = new HttpPut(location); 139 put2.setEntity(new StringEntity(body2)); 140 put2.setHeader(CONTENT_TYPE, "text/turtle"); 141 final HttpResponse put2Response = executeAndVerify(put2, SC_CONFLICT); 142 143 // Verify the returned LINK header 144 final String linkHeader = put2Response.getFirstHeader(LINK).getValue(); 145 final Link link = Link.valueOf(linkHeader); 146 logger.debug("constraint linkHeader: {}", linkHeader); 147 148 // Verify the LINK rel 149 final String linkRel = link.getRel(); 150 assertEquals(CONSTRAINED_BY.getURI(), linkRel); 151 152 // Verify the LINK URI by fetching it 153 final URI linkURI = link.getUri(); 154 logger.debug("constraint linkURI: {}", linkURI); 155 156 final HttpGet getLink = new HttpGet(linkURI); 157 executeAndVerify(getLink, SC_OK); 158 } 159 160 @Test 161 public void testCannotCreateResourceConstraintLink() throws Exception { 162 // Create a ldp:Resource resource, this should fail 163 final HttpPost post = new HttpPost(serverAddress); 164 post.setHeader(LINK,"<http://www.w3.org/ns/ldp#Resource>; rel=\"type\""); 165 final HttpResponse postResponse = executeAndVerify(post, SC_BAD_REQUEST); 166 167 // Verify the returned LINK header 168 final String linkHeader = postResponse.getFirstHeader(LINK).getValue(); 169 final Link link = Link.valueOf(linkHeader); 170 logger.debug("constraint linkHeader: {}", linkHeader); 171 172 // Verify the LINK rel 173 final String linkRel = link.getRel(); 174 assertEquals(CONSTRAINED_BY.getURI(), linkRel); 175 176 // Verify the LINK URI by fetching it 177 final URI linkURI = link.getUri(); 178 logger.debug("constraint linkURI: {}", linkURI); 179 180 final HttpGet getLink = new HttpGet(linkURI); 181 executeAndVerify(getLink, SC_OK); 182 } 183 184 @Test 185 public void testUnicodeCharsAllowed() throws Exception { 186 final var id = "ÅŤéșţ!"; 187 final var url = serverAddress + "/" + id; 188 189 final HttpPut put = new HttpPut(url); 190 put.setEntity(new StringEntity("testing")); 191 put.setHeader(CONTENT_TYPE, "text/plain"); 192 executeAndVerify(put, SC_CREATED); 193 194 executeAndVerify(new HttpGet(url), SC_OK); 195 } 196}