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