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.http.api; 019 020import static java.nio.charset.StandardCharsets.UTF_8; 021import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE; 022import static javax.ws.rs.core.HttpHeaders.LINK; 023import static javax.ws.rs.core.Response.Status.CREATED; 024import static javax.ws.rs.core.Response.Status.NO_CONTENT; 025import static javax.ws.rs.core.Response.Status.OK; 026import static org.apache.jena.graph.Node.ANY; 027import static org.apache.jena.graph.NodeFactory.createLiteral; 028import static org.apache.jena.graph.NodeFactory.createURI; 029import static org.apache.jena.vocabulary.DC_11.title; 030import static org.fcrepo.kernel.api.RdfLexicon.BASIC_CONTAINER; 031import static org.fcrepo.kernel.api.RdfLexicon.CONTAINER; 032import static org.fcrepo.kernel.api.RdfLexicon.CONTAINS; 033import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE; 034import static org.fcrepo.kernel.api.RdfLexicon.DIRECT_CONTAINER; 035import static org.fcrepo.kernel.api.RdfLexicon.EMBED_CONTAINED; 036import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_CONTAINER; 037import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_RESOURCE; 038import static org.fcrepo.kernel.api.RdfLexicon.HAS_MEMBER_RELATION; 039import static org.fcrepo.kernel.api.RdfLexicon.INBOUND_REFERENCES; 040import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_DATE; 041import static org.fcrepo.kernel.api.RdfLexicon.LDP_MEMBER; 042import static org.fcrepo.kernel.api.RdfLexicon.MEMBERSHIP_RESOURCE; 043import static org.fcrepo.kernel.api.RdfLexicon.PREFER_CONTAINMENT; 044import static org.fcrepo.kernel.api.RdfLexicon.PREFER_MEMBERSHIP; 045import static org.fcrepo.kernel.api.RdfLexicon.PREFER_MINIMAL_CONTAINER; 046import static org.fcrepo.kernel.api.RdfLexicon.PREFER_SERVER_MANAGED; 047import static org.fcrepo.kernel.api.RdfLexicon.RDF_SOURCE; 048import static org.junit.Assert.assertEquals; 049import static org.junit.Assert.assertFalse; 050import static org.junit.Assert.assertNotEquals; 051import static org.junit.Assert.assertTrue; 052 053import java.io.IOException; 054import java.nio.charset.StandardCharsets; 055import java.util.Collection; 056 057import org.fcrepo.http.commons.test.util.CloseableDataset; 058 059import org.apache.http.client.methods.CloseableHttpResponse; 060import org.apache.http.client.methods.HttpGet; 061import org.apache.http.client.methods.HttpPatch; 062import org.apache.http.client.methods.HttpPost; 063import org.apache.http.client.methods.HttpPut; 064import org.apache.http.client.methods.HttpUriRequest; 065import org.apache.http.entity.StringEntity; 066import org.apache.jena.graph.Node; 067import org.apache.jena.sparql.core.DatasetGraph; 068import org.apache.jena.sparql.core.Quad; 069import org.apache.jena.vocabulary.DC_11; 070import org.junit.Test; 071import org.springframework.test.context.TestExecutionListeners; 072 073/** 074 * Integration tests for various Prefer headers 075 * @author whikloj 076 * @since 6.0.0 077 */ 078@TestExecutionListeners( 079 listeners = { TestIsolationExecutionListener.class }, 080 mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS) 081public class PrefersLdpIT extends AbstractResourceIT { 082 083 private String mainResource; 084 085 private Quad userRdfTriple; 086 087 private Quad systemManagedPropertyTriple; 088 089 private Quad membershipTriple; 090 091 private Quad inboundReferenceTriple; 092 093 private Quad containmentTriple; 094 095 private Quad embededTriple; 096 097 /** 098 * Execute a request, test for a CREATED response code and return the location. 099 * @param request the request. 100 * @return the location URI. 101 * @throws Exception on problems with request. 102 */ 103 private String createAndGetLocation(final HttpUriRequest request) throws Exception { 104 try (final var response = execute(request)) { 105 assertEquals(CREATED.getStatusCode(), getStatus(response)); 106 return getLocation(response); 107 } 108 } 109 110 /** 111 * Generate a quad. 112 * @param subject the subject 113 * @param predicate the predicate 114 * @param object the object 115 * @return the quad 116 */ 117 private Quad generateQuad(final String subject, final String predicate, final Node object) { 118 return generateQuad(createURI(subject), predicate, object); 119 } 120 121 /** 122 * Generate a quad. 123 * @param subject the subject 124 * @param predicate the predicate 125 * @param object the object 126 * @return the quad 127 */ 128 private Quad generateQuad(final Node subject, final String predicate, final String object) { 129 final Node objectNode = (object == null ? ANY : createURI(object)); 130 return generateQuad(subject, predicate, objectNode); 131 } 132 133 /** 134 * Generate a quad. 135 * @param subject the subject 136 * @param predicate the predicate 137 * @param object the object 138 * @return the quad 139 */ 140 private Quad generateQuad(final Node subject, final String predicate, final Node object) { 141 return Quad.create(ANY, subject, createURI(predicate), object); 142 } 143 144 /** 145 * Generate a common set of triples for the Prefer header tests. 146 * @throws Exception problems with a http request. 147 */ 148 private void generateResources() throws Exception { 149 // Make the main resource to check with a user triple. 150 final var postMain = postObjMethod(); 151 final String body = "<> <" + DC_11.title + "> \"The object's title\" ."; 152 postMain.setHeader(CONTENT_TYPE, "text/turtle"); 153 postMain.setEntity(new StringEntity(body, StandardCharsets.UTF_8)); 154 mainResource = createAndGetLocation(postMain); 155 final Node mainNode = createURI(mainResource); 156 userRdfTriple = generateQuad(mainNode, DC_11.title.getURI(), createLiteral("The object's title")); 157 systemManagedPropertyTriple = generateQuad(mainNode, CREATED_DATE.getURI(), ANY); 158 // Make a DirectContainer pointing at the main resource. 159 final var postDC = postObjMethod(); 160 postDC.setHeader("Link", "<" + DIRECT_CONTAINER + ">; rel=\"type\""); 161 final String pcdmHasMember = "http://pcdm.org/models#hasMember"; 162 final String dcBody = 163 "@prefix ldp: <http://www.w3.org/ns/ldp#> . <> " + 164 "ldp:membershipResource <" + mainResource + "> ; ldp:hasMemberRelation " + 165 "<" + pcdmHasMember + "> ."; 166 postDC.setHeader(CONTENT_TYPE, "text/turtle"); 167 postDC.setEntity(new StringEntity(dcBody, StandardCharsets.UTF_8)); 168 final String directResource = createAndGetLocation(postDC); 169 // Make a member of the DC. 170 final var postDCchild = new HttpPost(directResource); 171 final String directResourceReference = createAndGetLocation(postDCchild); 172 membershipTriple = generateQuad(mainNode, pcdmHasMember, directResourceReference); 173 // Make a contained resource. 174 final var postChild = new HttpPost(mainResource); 175 final String childBody = "<> <" + DC_11.title + "> \"The child's title\" ."; 176 postChild.setHeader(CONTENT_TYPE, "text/turtle"); 177 postChild.setEntity(new StringEntity(childBody, StandardCharsets.UTF_8)); 178 final String containedResource = createAndGetLocation(postChild); 179 containmentTriple = generateQuad(mainNode, CONTAINS.getURI(), containedResource); 180 embededTriple = generateQuad(containedResource, DC_11.title.getURI(), createLiteral("The child's title")); 181 // Make an inbound reference. 182 final var otherRef = postObjMethod(); 183 final String refBody = "<> <http://example.org/related> <" + mainResource + "> ."; 184 otherRef.setHeader(CONTENT_TYPE, "text/turtle"); 185 otherRef.setEntity(new StringEntity(refBody, StandardCharsets.UTF_8)); 186 final String otherReference = createAndGetLocation(otherRef); 187 inboundReferenceTriple = generateQuad(otherReference, "http://example.org/related", mainNode); 188 } 189 190 @Test 191 public void testNormalTriples() throws Exception { 192 generateResources(); 193 final var getReq = new HttpGet(mainResource); 194 try (final var dataset = getDataset(getReq)) { 195 final var graph = dataset.asDatasetGraph(); 196 assertTrue(graph.contains(userRdfTriple)); 197 assertTrue(graph.contains(systemManagedPropertyTriple)); 198 assertTrue(graph.contains(containmentTriple)); 199 assertTrue(graph.contains(membershipTriple)); 200 assertFalse(graph.contains(inboundReferenceTriple)); 201 assertFalse(graph.contains(embededTriple)); 202 } 203 } 204 205 @Test 206 public void testPreferIncludeMinimal() throws Exception { 207 generateResources(); 208 final var getReq = new HttpGet(mainResource); 209 getReq.setHeader("Prefer", preferLink(PREFER_MINIMAL_CONTAINER.getURI(), null)); 210 try (final var dataset = getDataset(getReq)) { 211 final var graph = dataset.asDatasetGraph(); 212 assertTrue(graph.contains(userRdfTriple)); 213 assertTrue(graph.contains(systemManagedPropertyTriple)); 214 assertFalse(graph.contains(containmentTriple)); 215 assertFalse(graph.contains(membershipTriple)); 216 assertFalse(graph.contains(inboundReferenceTriple)); 217 assertFalse(graph.contains(embededTriple)); 218 } 219 } 220 221 @Test 222 public void testPreferOmitMinimal() throws Exception { 223 generateResources(); 224 final var getReq = new HttpGet(mainResource); 225 getReq.setHeader("Prefer", preferLink(null, PREFER_MINIMAL_CONTAINER.getURI())); 226 try (final var dataset = getDataset(getReq)) { 227 final var graph = dataset.asDatasetGraph(); 228 assertFalse(graph.contains(userRdfTriple)); 229 assertFalse(graph.contains(systemManagedPropertyTriple)); 230 assertTrue(graph.contains(containmentTriple)); 231 assertTrue(graph.contains(membershipTriple)); 232 assertFalse(graph.contains(inboundReferenceTriple)); 233 assertFalse(graph.contains(embededTriple)); 234 } 235 } 236 237 @Test 238 public void testPreferIncludeMinimalAndSystem() throws Exception { 239 generateResources(); 240 final var getReq = new HttpGet(mainResource); 241 getReq.setHeader("Prefer", preferLink( 242 PREFER_MINIMAL_CONTAINER.getURI() + " " + PREFER_SERVER_MANAGED.getURI(), 243 null)); 244 try (final var dataset = getDataset(getReq)) { 245 final var graph = dataset.asDatasetGraph(); 246 assertTrue(graph.contains(userRdfTriple)); 247 assertTrue(graph.contains(systemManagedPropertyTriple)); 248 assertFalse(graph.contains(containmentTriple)); 249 assertFalse(graph.contains(membershipTriple)); 250 assertFalse(graph.contains(inboundReferenceTriple)); 251 assertFalse(graph.contains(embededTriple)); 252 } 253 } 254 255 @Test 256 public void testPreferOmitSystem() throws Exception { 257 generateResources(); 258 final var getReq = new HttpGet(mainResource); 259 getReq.setHeader("Prefer", preferLink( 260 null, 261 PREFER_SERVER_MANAGED.getURI())); 262 try (final var dataset = getDataset(getReq)) { 263 final var graph = dataset.asDatasetGraph(); 264 assertTrue(graph.contains(userRdfTriple)); 265 assertFalse(graph.contains(systemManagedPropertyTriple)); 266 // Containment is consider system managed. 267 assertFalse(graph.contains(containmentTriple)); 268 // Membership is considered system managed. 269 assertFalse(graph.contains(membershipTriple)); 270 assertFalse(graph.contains(inboundReferenceTriple)); 271 assertFalse(graph.contains(embededTriple)); 272 } 273 } 274 275 @Test 276 public void testPreferOmitSystemIncludeContainment() throws Exception { 277 generateResources(); 278 final var getReq = new HttpGet(mainResource); 279 getReq.setHeader("Prefer", preferLink( 280 PREFER_CONTAINMENT.getURI(), 281 PREFER_SERVER_MANAGED.getURI())); 282 try (final var dataset = getDataset(getReq)) { 283 final var graph = dataset.asDatasetGraph(); 284 assertTrue(graph.contains(userRdfTriple)); 285 assertFalse(graph.contains(systemManagedPropertyTriple)); 286 assertTrue(graph.contains(containmentTriple)); 287 assertFalse(graph.contains(membershipTriple)); 288 assertFalse(graph.contains(inboundReferenceTriple)); 289 assertFalse(graph.contains(embededTriple)); 290 } 291 } 292 293 @Test 294 public void testPreferIncludeMinimalOmitSystem() throws Exception { 295 generateResources(); 296 final var getReq = new HttpGet(mainResource); 297 getReq.setHeader("Prefer", preferLink( 298 PREFER_MINIMAL_CONTAINER.getURI(), 299 PREFER_SERVER_MANAGED.getURI())); 300 try (final var dataset = getDataset(getReq)) { 301 final var graph = dataset.asDatasetGraph(); 302 assertTrue(graph.contains(userRdfTriple)); 303 assertFalse(graph.contains(systemManagedPropertyTriple)); 304 assertFalse(graph.contains(containmentTriple)); 305 assertFalse(graph.contains(membershipTriple)); 306 assertFalse(graph.contains(inboundReferenceTriple)); 307 assertFalse(graph.contains(embededTriple)); 308 } 309 } 310 311 @Test 312 public void testPreferExcludeMembership() throws Exception { 313 generateResources(); 314 final var getReq = new HttpGet(mainResource); 315 getReq.setHeader("Prefer", preferLink( 316 null, 317 PREFER_MEMBERSHIP.getURI())); 318 try (final var dataset = getDataset(getReq)) { 319 final var graph = dataset.asDatasetGraph(); 320 assertTrue(graph.contains(userRdfTriple)); 321 assertTrue(graph.contains(systemManagedPropertyTriple)); 322 assertTrue(graph.contains(containmentTriple)); 323 assertFalse(graph.contains(membershipTriple)); 324 assertFalse(graph.contains(inboundReferenceTriple)); 325 assertFalse(graph.contains(embededTriple)); 326 } 327 } 328 329 @Test 330 public void testPreferIncludeInbound() throws Exception { 331 generateResources(); 332 final var getReq = new HttpGet(mainResource); 333 getReq.setHeader("Prefer", preferLink( 334 INBOUND_REFERENCES.getURI(), 335 null)); 336 try (final var dataset = getDataset(getReq)) { 337 final var graph = dataset.asDatasetGraph(); 338 assertTrue(graph.contains(userRdfTriple)); 339 assertTrue(graph.contains(systemManagedPropertyTriple)); 340 assertTrue(graph.contains(containmentTriple)); 341 assertTrue(graph.contains(membershipTriple)); 342 assertTrue(graph.contains(inboundReferenceTriple)); 343 assertFalse(graph.contains(embededTriple)); 344 } 345 } 346 347 @Test 348 public void testPreferIncludeEmbed() throws Exception { 349 generateResources(); 350 final var getReq = new HttpGet(mainResource); 351 getReq.setHeader("Prefer", preferLink( 352 EMBED_CONTAINED.getURI(), 353 null)); 354 try (final var dataset = getDataset(getReq)) { 355 final var graph = dataset.asDatasetGraph(); 356 assertTrue(graph.contains(userRdfTriple)); 357 assertTrue(graph.contains(systemManagedPropertyTriple)); 358 assertTrue(graph.contains(containmentTriple)); 359 assertTrue(graph.contains(membershipTriple)); 360 assertFalse(graph.contains(inboundReferenceTriple)); 361 assertTrue(graph.contains(embededTriple)); 362 } 363 } 364 365 @Test 366 public void testPreferIncludeEmbedInbound_OmitMinimal() throws Exception { 367 generateResources(); 368 final var getReq = new HttpGet(mainResource); 369 getReq.setHeader("Prefer", preferLink( 370 EMBED_CONTAINED.getURI() + " " + INBOUND_REFERENCES.getURI(), 371 PREFER_MINIMAL_CONTAINER.getURI())); 372 try (final var dataset = getDataset(getReq)) { 373 final var graph = dataset.asDatasetGraph(); 374 assertFalse(graph.contains(userRdfTriple)); 375 assertFalse(graph.contains(systemManagedPropertyTriple)); 376 assertTrue(graph.contains(containmentTriple)); 377 assertTrue(graph.contains(membershipTriple)); 378 assertTrue(graph.contains(inboundReferenceTriple)); 379 // Omitting minimal removes user rdf, this also happens to the embedded resources. 380 assertFalse(graph.contains(embededTriple)); 381 } 382 } 383 384 @Test 385 public void testGetObjectGraphMinimal() throws IOException { 386 final String uri; 387 final HttpPost httpPost = postObjMethod(); 388 httpPost.setHeader("Link", BASIC_CONTAINER_LINK_HEADER); 389 httpPost.setHeader(CONTENT_TYPE, "text/turtle"); 390 httpPost.setEntity(new StringEntity("<> <" + DCTITLE.getURI() + "> \"The title\" .")); 391 try (final CloseableHttpResponse response = execute(httpPost)) { 392 assertEquals(CREATED.getStatusCode(), getStatus(response)); 393 uri = getLocation(response); 394 } 395 final Node resource = createURI(uri); 396 // Create a contained child. 397 final HttpPut httpPut = new HttpPut(uri + "/a"); 398 assertEquals(CREATED.getStatusCode(), getStatus(httpPut)); 399 400 // Now test with include preference 401 final HttpGet httpGet = new HttpGet(uri); 402 final String preferHeader2 = preferLink(PREFER_MINIMAL_CONTAINER.toString(), null); 403 httpGet.setHeader("Prefer", preferHeader2); 404 try (final CloseableHttpResponse response = execute(httpGet); 405 final CloseableDataset dataset = getDataset(response)) { 406 assertEquals(OK.getStatusCode(), getStatus(response)); 407 final DatasetGraph graph = dataset.asDatasetGraph(); 408 assertFalse("Didn't expect members", graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 409 final Collection<String> preferenceApplied = getHeader(response, "Preference-Applied"); 410 assertTrue("Preference-Applied header doesn't matched", 411 preferenceApplied.contains(preferHeader2)); 412 assertTrue("Missing a user RDF triple", graph.contains(ANY, resource, DCTITLE, ANY)); 413 } 414 // Now try with Omit minimal 415 final HttpGet getOmit = new HttpGet(uri); 416 final String preferOmitHeader = preferLink(null, PREFER_MINIMAL_CONTAINER.toString()); 417 getOmit.addHeader("Prefer", preferOmitHeader); 418 try (final CloseableHttpResponse response = execute(getOmit); 419 final CloseableDataset dataset = getDataset(response)) { 420 assertEquals(OK.getStatusCode(), getStatus(response)); 421 final DatasetGraph graph = dataset.asDatasetGraph(); 422 assertTrue("Expected members", graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 423 final Collection<String> preferenceApplied = getHeader(response, "Preference-Applied"); 424 assertTrue("Preference-Applied header doesn't matched", 425 preferenceApplied.contains(preferOmitHeader)); 426 assertFalse("Should not return user RDF triples", graph.contains(ANY, resource, DCTITLE, ANY)); 427 } 428 } 429 430 @Test 431 public void testGetObjectOmitMembership() throws IOException { 432 final String id = getRandomUniqueId(); 433 final Node resource = createURI(serverAddress + id); 434 createObjectAndClose(id, BASIC_CONTAINER_LINK_HEADER); 435 final String initialEtag = getEtag(serverAddress + id); 436 createObjectAndClose(id + "/a"); 437 final String withChildEtag = getEtag(serverAddress + id); 438 assertNotEquals(initialEtag, withChildEtag); 439 final HttpGet getObjMethod = getObjMethod(id); 440 getObjMethod.addHeader("Prefer", preferLink(null, PREFER_CONTAINMENT + " " + PREFER_MEMBERSHIP)); 441 final String omitEtag = getEtag(getObjMethod); 442 assertEquals(initialEtag, omitEtag); 443 assertNotEquals(withChildEtag, omitEtag); 444 try (final CloseableDataset dataset = getDataset(getObjMethod)) { 445 final DatasetGraph graph = dataset.asDatasetGraph(); 446 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, CONTAINER.asNode()).hasNext()); 447 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, BASIC_CONTAINER.asNode()).hasNext()); 448 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, RDF_SOURCE.asNode()).hasNext()); 449 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, FEDORA_CONTAINER.asNode()).hasNext()); 450 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, FEDORA_RESOURCE.asNode()).hasNext()); 451 assertTrue("Expected server managed", graph.find(ANY, resource, CREATED_DATE.asNode(), ANY).hasNext()); 452 assertTrue("Expected server managed", 453 graph.find(ANY, resource, LAST_MODIFIED_DATE.asNode(), ANY).hasNext()); 454 assertFalse("Expected no members", graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 455 } 456 } 457 458 @Test 459 public void testGetObjectOmitContainment() throws IOException { 460 final String id = getRandomUniqueId(); 461 createObjectAndClose(id); 462 final String initialEtag = getEtag(serverAddress + id); 463 final String location = serverAddress + id; 464 final String updateString = "<> <" + MEMBERSHIP_RESOURCE.getURI() + 465 "> <" + location + "> ; <" + HAS_MEMBER_RELATION + "> <" + LDP_MEMBER + "> ."; 466 final HttpPut put = putObjMethod(id + "/a", "text/turtle", updateString); 467 put.setHeader(LINK, DIRECT_CONTAINER_LINK_HEADER); 468 assertEquals(CREATED.getStatusCode(), getStatus(put)); 469 assertTrue(getLinkHeaders(getObjMethod(id + "/a")).contains(DIRECT_CONTAINER_LINK_HEADER)); 470 createObject(id + "/a/1"); 471 472 final String withMemberEtag = getEtag(serverAddress + id); 473 assertNotEquals(initialEtag, withMemberEtag); 474 475 final HttpGet getObjMethod = getObjMethod(id); 476 getObjMethod.addHeader("Prefer", preferLink(null, PREFER_CONTAINMENT.toString())); 477 final String omitEtag = getEtag(getObjMethod); 478 assertNotEquals("Should not match initial because of membership", initialEtag, omitEtag); 479 assertNotEquals(withMemberEtag, omitEtag); 480 try (final CloseableDataset dataset = getDataset(getObjMethod)) { 481 final DatasetGraph graph = dataset.asDatasetGraph(); 482 final Node resource = createURI(serverAddress + id); 483 assertTrue("Didn't find member resources", graph.find(ANY, resource, LDP_MEMBER.asNode(), ANY).hasNext()); 484 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, CONTAINER.asNode()).hasNext()); 485 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, BASIC_CONTAINER.asNode()).hasNext()); 486 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, RDF_SOURCE.asNode()).hasNext()); 487 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, FEDORA_CONTAINER.asNode()).hasNext()); 488 assertTrue("Expected server managed", graph.find(ANY, resource, ANY, FEDORA_RESOURCE.asNode()).hasNext()); 489 assertTrue("Expected server managed", graph.find(ANY, resource, CREATED_DATE.asNode(), ANY).hasNext()); 490 assertTrue("Expected server managed", 491 graph.find(ANY, resource, LAST_MODIFIED_DATE.asNode(), ANY).hasNext()); 492 assertFalse("Expected nothing contained", graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 493 } 494 } 495 496 @Test 497 public void testGetObjectOmitServerManaged() throws IOException { 498 final String id = getRandomUniqueId(); 499 createObjectAndClose(id); 500 501 final String location = serverAddress + id; 502 final String updateString = "<> <" + MEMBERSHIP_RESOURCE.getURI() + 503 "> <" + location + "> ; <" + HAS_MEMBER_RELATION + "> <" + LDP_MEMBER + "> ."; 504 final HttpPut put = putObjMethod(id + "/a", "text/turtle", updateString); 505 put.setHeader(LINK, DIRECT_CONTAINER_LINK_HEADER); 506 assertEquals(CREATED.getStatusCode(), getStatus(put)); 507 assertTrue(getLinkHeaders(getObjMethod(id + "/a")).contains(DIRECT_CONTAINER_LINK_HEADER)); 508 createObject(id + "/a/1"); 509 510 final String withMemberEtag = getEtag(serverAddress + id); 511 512 final HttpGet getObjMethod = getObjMethod(id); 513 getObjMethod.addHeader("Prefer", preferLink(null, PREFER_SERVER_MANAGED.toString())); 514 assertNotEquals("Etag should not match with SMTs excluded", withMemberEtag, getEtag(getObjMethod)); 515 try (final CloseableDataset dataset = getDataset(getObjMethod)) { 516 final DatasetGraph graph = dataset.asDatasetGraph(); 517 final Node resource = createURI(serverAddress + id); 518 // Membership is now consider system managed and so is removed with the rest. 519 assertFalse("Didn't find member resources", graph.find(ANY, resource, LDP_MEMBER.asNode(), ANY).hasNext()); 520 assertFalse("Expected nothing server managed", 521 graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 522 assertFalse("Expected nothing server managed", 523 graph.find(ANY, resource, ANY, CONTAINER.asNode()).hasNext()); 524 assertFalse("Expected nothing server managed", 525 graph.find(ANY, resource, ANY, BASIC_CONTAINER.asNode()).hasNext()); 526 assertFalse("Expected nothing server managed", 527 graph.find(ANY, resource, ANY, RDF_SOURCE.asNode()).hasNext()); 528 assertFalse("Expected nothing server managed", 529 graph.find(ANY, resource, ANY, FEDORA_CONTAINER.asNode()).hasNext()); 530 assertFalse("Expected nothing server managed", 531 graph.find(ANY, resource, ANY, FEDORA_RESOURCE.asNode()).hasNext()); 532 assertFalse("Expected nothing server managed", 533 graph.find(ANY, resource, CREATED_DATE.asNode(), ANY).hasNext()); 534 assertFalse("Expected nothing server managed", 535 graph.find(ANY, resource, LAST_MODIFIED_DATE.asNode(), ANY).hasNext()); 536 } 537 } 538 539 @Test 540 public void testGetObjectIncludeContainmentAndOmitServerManaged() throws IOException { 541 final String id = getRandomUniqueId(); 542 createObjectAndClose(id); 543 final String location = serverAddress + id; 544 final String updateString = "<> <" + MEMBERSHIP_RESOURCE.getURI() + 545 "> <" + location + "> ; <" + HAS_MEMBER_RELATION + "> <" + LDP_MEMBER + "> ."; 546 final HttpPut put = putObjMethod(id + "/a", "text/turtle", updateString); 547 put.setHeader(LINK, DIRECT_CONTAINER_LINK_HEADER); 548 assertEquals(CREATED.getStatusCode(), getStatus(put)); 549 assertTrue(getLinkHeaders(getObjMethod(id + "/a")).contains(DIRECT_CONTAINER_LINK_HEADER)); 550 createObject(id + "/a/1"); 551 552 final String withMemberEtag = getEtag(serverAddress + id); 553 554 final HttpGet getObjMethod = getObjMethod(id); 555 getObjMethod.addHeader("Prefer", preferLink(PREFER_CONTAINMENT.toString(), PREFER_SERVER_MANAGED.toString())); 556 assertNotEquals("Etag should not match with SMTs excluded", withMemberEtag, getEtag(getObjMethod)); 557 try (final CloseableDataset dataset = getDataset(getObjMethod)) { 558 final DatasetGraph graph = dataset.asDatasetGraph(); 559 final Node resource = createURI(serverAddress + id); 560 assertTrue("Didn't find ldp containment", graph.find(ANY, resource, CONTAINS.asNode(), ANY).hasNext()); 561 } 562 } 563 564 @Test 565 public void testGetLDPRmOmitServerManaged() throws Exception { 566 final String versionedResourceURI = createAndGetLocation(postObjMethod()); 567 final String mementoResourceURI = getLocation(new HttpPost(versionedResourceURI + "/fcr:versions")); 568 final String mementoEtag = getEtag(mementoResourceURI); 569 570 final HttpGet mementoGetMethod = new HttpGet(mementoResourceURI); 571 mementoGetMethod.addHeader("Prefer", preferLink(null, PREFER_SERVER_MANAGED.toString())); 572 assertNotEquals(mementoEtag, getEtag(mementoGetMethod)); 573 try (final CloseableDataset dataset = getDataset(mementoGetMethod)) { 574 final DatasetGraph graph = dataset.asDatasetGraph(); 575 final Node resource = createURI(versionedResourceURI); 576 assertFalse("Expected nothing server managed", 577 graph.find(ANY, resource, ANY, CONTAINER.asNode()).hasNext()); 578 assertFalse("Expected nothing server managed", 579 graph.find(ANY, resource, ANY, RDF_SOURCE.asNode()).hasNext()); 580 assertFalse("Expected nothing server managed", 581 graph.find(ANY, resource, ANY, FEDORA_CONTAINER.asNode()).hasNext()); 582 assertFalse("Expected nothing server managed", 583 graph.find(ANY, resource, ANY, FEDORA_RESOURCE.asNode()).hasNext()); 584 assertFalse("Expected nothing server managed", 585 graph.find(ANY, resource, CREATED_DATE.asNode(), ANY).hasNext()); 586 assertFalse("Expected nothing server managed", 587 graph.find(ANY, resource, LAST_MODIFIED_DATE.asNode(), ANY).hasNext()); 588 } 589 } 590 591 @Test 592 public void testGetLDPRmWithoutOmitServerManager() throws Exception { 593 final String versionedResourceURI = createAndGetLocation(postObjMethod()); 594 final String mementoResourceURI = getLocation(new HttpPost(versionedResourceURI + "/fcr:versions")); 595 596 final HttpGet mementoGetMethod = new HttpGet(mementoResourceURI); 597 try (final CloseableDataset dataset = getDataset(mementoGetMethod)) { 598 final DatasetGraph graph = dataset.asDatasetGraph(); 599 final Node resource = createURI(versionedResourceURI); 600 assertTrue("Expected server managed", 601 graph.find(ANY, resource, ANY, CONTAINER.asNode()).hasNext()); 602 assertTrue("Expected server managed", 603 graph.find(ANY, resource, ANY, RDF_SOURCE.asNode()).hasNext()); 604 assertTrue("Expected server managed", 605 graph.find(ANY, resource, ANY, FEDORA_CONTAINER.asNode()).hasNext()); 606 assertTrue("Expected server managed", 607 graph.find(ANY, resource, ANY, FEDORA_RESOURCE.asNode()).hasNext()); 608 assertTrue("Expected server managed", 609 graph.find(ANY, resource, CREATED_DATE.asNode(), ANY).hasNext()); 610 assertTrue("Expected server managed", 611 graph.find(ANY, resource, LAST_MODIFIED_DATE.asNode(), ANY).hasNext()); 612 } 613 } 614 615 @Test 616 public void testEmbeddedContainedResources() throws IOException { 617 final String id = getRandomUniqueId(); 618 final String binaryId = "binary0"; 619 final String preferEmbed = preferLink(EMBED_CONTAINED.toString(), null); 620 621 assertEquals(CREATED.getStatusCode(), getStatus(putObjMethod(id))); 622 assertEquals(CREATED.getStatusCode(), getStatus(putDSMethod(id, binaryId, "some test content"))); 623 624 final HttpPatch httpPatch = patchObjMethod(id + "/" + binaryId + "/fcr:metadata"); 625 httpPatch.addHeader(CONTENT_TYPE, "application/sparql-update"); 626 httpPatch.setEntity(new StringEntity( 627 "INSERT { <> <http://purl.org/dc/elements/1.1/title> 'this is a title' } WHERE {}")); 628 assertEquals(NO_CONTENT.getStatusCode(), getStatus(httpPatch)); 629 630 final String withoutEmbedEtag = getEtag(serverAddress + id); 631 632 final HttpGet httpGet = getObjMethod(id); 633 httpGet.setHeader("Prefer", preferEmbed); 634 assertNotEquals(withoutEmbedEtag, getEtag(httpGet)); 635 try (final CloseableHttpResponse response = execute(httpGet)) { 636 final Collection<String> preferenceApplied = getHeader(response, "Preference-Applied"); 637 assertTrue("Preference-Applied header doesn't match", preferenceApplied.contains(preferEmbed)); 638 639 final DatasetGraph graphStore = getDataset(response).asDatasetGraph(); 640 assertTrue("Property on child binary should be found!" + graphStore, graphStore.contains(ANY, 641 createURI(serverAddress + id + "/" + binaryId), 642 title.asNode(), createLiteral("this is a title"))); 643 } 644 } 645 646 @Test 647 public void testEmbeddedContainedResourcesNotToDeep() throws IOException { 648 final String id = getRandomUniqueId(); 649 final String level1 = id + "/" + getRandomUniqueId(); 650 final String level2 = level1 + "/" + getRandomUniqueId(); 651 final String preferEmbed = preferLink(EMBED_CONTAINED.toString(), null); 652 653 assertEquals(CREATED.getStatusCode(), getStatus(putObjMethod(id))); 654 655 final HttpPut putLevel1 = putObjMethod(level1); 656 putLevel1.addHeader(CONTENT_TYPE, "text/turtle"); 657 putLevel1.setEntity(new StringEntity("<> <" + title + "> \"First level\"", UTF_8)); 658 assertEquals(CREATED.getStatusCode(), getStatus(putLevel1)); 659 660 final HttpPut putLevel2 = putObjMethod(level2); 661 putLevel2.addHeader(CONTENT_TYPE, "text/turtle"); 662 putLevel2.setEntity(new StringEntity("<> <" + title + "> \"Second level\"", UTF_8)); 663 assertEquals(CREATED.getStatusCode(), getStatus(putLevel2)); 664 665 final HttpGet httpGet = getObjMethod(id); 666 httpGet.setHeader("Prefer", preferEmbed); 667 try (final CloseableHttpResponse response = execute(httpGet)) { 668 final Collection<String> preferenceApplied = getHeader(response, "Preference-Applied"); 669 assertTrue("Preference-Applied header doesn't match", preferenceApplied.contains(preferEmbed)); 670 671 final DatasetGraph graphStore = getDataset(response).asDatasetGraph(); 672 assertTrue("Property on child binary should be found!" + graphStore, graphStore.contains(ANY, 673 createURI(serverAddress + level1), 674 title.asNode(), createLiteral("First level"))); 675 assertFalse("Property from embedded resource's own child should not be found.", 676 graphStore.contains(ANY, 677 createURI(serverAddress + level2), 678 title.asNode(), createLiteral("Second level") 679 ) 680 ); 681 } 682 } 683}