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.client.integration; 007 008import static javax.ws.rs.core.Response.Status.BAD_REQUEST; 009import static javax.ws.rs.core.Response.Status.CONFLICT; 010import static javax.ws.rs.core.Response.Status.CREATED; 011import static javax.ws.rs.core.Response.Status.GONE; 012import static javax.ws.rs.core.Response.Status.NOT_FOUND; 013import static javax.ws.rs.core.Response.Status.NOT_MODIFIED; 014import static javax.ws.rs.core.Response.Status.NO_CONTENT; 015import static javax.ws.rs.core.Response.Status.OK; 016import static javax.ws.rs.core.Response.Status.PARTIAL_CONTENT; 017import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED; 018import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT; 019import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION_FILENAME; 020import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE; 021import static org.fcrepo.client.FedoraHeaderConstants.DIGEST; 022import static org.fcrepo.client.FedoraHeaderConstants.ETAG; 023import static org.fcrepo.client.FedoraHeaderConstants.LAST_MODIFIED; 024import static org.fcrepo.client.FedoraHeaderConstants.STATE_TOKEN; 025import static org.fcrepo.client.FedoraTypes.LDP_DIRECT_CONTAINER; 026import static org.fcrepo.client.TestUtils.TEXT_TURTLE; 027import static org.fcrepo.client.TestUtils.sparqlUpdate; 028import static org.junit.Assert.assertEquals; 029import static org.junit.Assert.assertNotEquals; 030import static org.junit.Assert.assertNotNull; 031import static org.junit.Assert.assertNull; 032import static org.junit.Assert.assertTrue; 033 034import java.io.ByteArrayInputStream; 035import java.io.IOException; 036import java.io.InputStream; 037import java.net.URI; 038import java.nio.file.Files; 039import java.nio.file.Path; 040import java.util.Arrays; 041import java.util.Calendar; 042import java.util.Date; 043import java.util.HashMap; 044import java.util.Map; 045import java.util.UUID; 046 047import javax.ws.rs.core.EntityTag; 048 049import org.apache.commons.io.FileUtils; 050import org.apache.commons.io.IOUtils; 051import org.apache.http.client.utils.DateUtils; 052import org.fcrepo.client.ExternalContentHandling; 053import org.fcrepo.client.FcrepoClient; 054import org.fcrepo.client.FcrepoOperationFailedException; 055import org.fcrepo.client.FcrepoResponse; 056import org.fcrepo.client.HeaderHelpers; 057import org.junit.AfterClass; 058import org.junit.Before; 059import org.junit.BeforeClass; 060import org.junit.Test; 061 062/** 063 * @author bbpennel 064 */ 065public class FcrepoClientIT extends AbstractResourceIT { 066 067 private static FcrepoClient client; 068 069 private URI url; 070 071 final private String UNMODIFIED_DATE = "Mon, 1 Jan 2001 00:00:00 GMT"; 072 073 @BeforeClass 074 public static void beforeClass() { 075 client = FcrepoClient.client() 076 .credentials("fedoraAdmin", "fedoraAdmin") 077 .authScope("localhost") 078 .build(); 079 } 080 081 @AfterClass 082 public static void afterClass() throws IOException { 083 client.close(); 084 } 085 086 @Before 087 public void before() { 088 url = URI.create(SERVER_ADDRESS + UUID.randomUUID().toString()); 089 } 090 091 @Test 092 public void testPost() throws Exception { 093 try (final FcrepoResponse response = 094 client.post(new URI(SERVER_ADDRESS)).perform()) { 095 assertEquals(CREATED.getStatusCode(), response.getStatusCode()); 096 } 097 } 098 099 @Test 100 public void testPostBinary() throws Exception { 101 final String slug = UUID.randomUUID().toString(); 102 final String filename = "hello.txt"; 103 final String mimetype = "text/plain"; 104 final String bodyContent = "Hello world"; 105 106 final URI createdResourceUri; 107 try (final FcrepoResponse response = 108 client.post(new URI(SERVER_ADDRESS)) 109 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 110 .filename(filename) 111 .slug(slug) 112 .perform()) { 113 114 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 115 final int status = response.getStatusCode(); 116 createdResourceUri = response.getLocation(); 117 118 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 119 CREATED.getStatusCode(), status); 120 assertEquals("Location did not match slug", SERVER_ADDRESS + slug, createdResourceUri.toString()); 121 122 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 123 } 124 125 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 126 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 127 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 128 129 assertEquals(mimetype, getResponse.getContentType()); 130 131 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 132 assertEquals(bodyContent, getContent); 133 } 134 } 135 136 @Test 137 public void testPostExternalContent() throws Exception { 138 final String filename = "hello.txt"; 139 final String mimetype = "text/plain"; 140 final String fileContent = "Hello post world"; 141 142 final Path contentPath = Files.createTempFile(null, ".txt"); 143 FileUtils.write(contentPath.toFile(), fileContent, "UTF-8"); 144 145 final URI createdResourceUri; 146 try (final FcrepoResponse response = 147 client.post(new URI(SERVER_ADDRESS)) 148 .externalContent(contentPath.toUri(), mimetype, ExternalContentHandling.PROXY) 149 .filename(filename) 150 .perform()) { 151 152 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 153 final int status = response.getStatusCode(); 154 createdResourceUri = response.getLocation(); 155 156 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 157 CREATED.getStatusCode(), status); 158 } 159 160 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 161 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 162 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 163 164 assertEquals(mimetype, getResponse.getContentType()); 165 166 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 167 assertEquals(fileContent, getContent); 168 } 169 } 170 171 @Test 172 public void testPostDigestMismatch() throws Exception { 173 final String bodyContent = "Hello world"; 174 final String invalidDigest = "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc"; 175 176 try (final FcrepoResponse response = 177 client.post(new URI(SERVER_ADDRESS)) 178 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 179 .digestSha1(invalidDigest) 180 .perform()) { 181 182 assertEquals("Invalid checksum was not rejected", CONFLICT.getStatusCode(), response.getStatusCode()); 183 } 184 } 185 186 @Test 187 public void testPostDigestMultipleChecksums() throws Exception { 188 final String bodyContent = "Hello world"; 189 190 try (final FcrepoResponse response = 191 client.post(new URI(SERVER_ADDRESS)) 192 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 193 .digestMd5("3e25960a79dbc69b674cd4ec67a72c62") 194 .digestSha1("7b502c3a1f48c8609ae212cdfb639dee39673f5e") 195 .digestSha256("64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c") 196 .perform()) { 197 198 assertEquals("Checksums rejected", CREATED.getStatusCode(), response.getStatusCode()); 199 } 200 } 201 202 @Test 203 public void testPostDigestMultipleChecksumsOneMismatch() throws Exception { 204 final String bodyContent = "Hello world"; 205 206 try (final FcrepoResponse response = 207 client.post(new URI(SERVER_ADDRESS)) 208 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 209 .digestMd5("3e25960a79dbc69b674cd4ec67a72c62") 210 .digestSha1("7b502c3a1f48c8609ae212cdfb639dee39673f5e") 211 // Incorrect sha256 212 .digestSha256("123488ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c") 213 .perform()) { 214 215 assertEquals("Invalid checksum was not rejected", CONFLICT.getStatusCode(), response.getStatusCode()); 216 } 217 } 218 219 @Test 220 public void testPostBinaryNullFilename() throws Exception { 221 final String bodyContent = "Hello world"; 222 223 try (final FcrepoResponse response = 224 client.post(new URI(SERVER_ADDRESS)) 225 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 226 .filename(null) 227 .perform()) { 228 229 assertEquals("Empty filename rejected", CREATED.getStatusCode(), response.getStatusCode()); 230 } 231 } 232 233 @Test 234 public void testPostDirectContainer() throws Exception { 235 final URI createdResourceUri; 236 try (final FcrepoResponse response = 237 client.post(new URI(SERVER_ADDRESS)) 238 .addInteractionModel(LDP_DIRECT_CONTAINER) 239 .perform()) { 240 241 final int status = response.getStatusCode(); 242 createdResourceUri = response.getLocation(); 243 244 assertEquals("Didn't get a CREATED response!", CREATED.getStatusCode(), status); 245 } 246 247 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 248 assertTrue("Did not have ldp:DirectContainer type", getResponse.hasType(LDP_DIRECT_CONTAINER)); 249 } 250 } 251 252 @Test 253 public void testPostBinaryFilenameSpecialCharacters() throws Exception { 254 final String slug = UUID.randomUUID().toString(); 255 final String filename = "hello world\nof_weird:+\tchar/acters.tx\rt"; 256 final String expectedFilename = "hello world of_weird:+\tchar/acters.tx t"; 257 final String mimetype = "text/plain"; 258 final String bodyContent = "Hello world"; 259 260 final URI createdResourceUri; 261 try (final FcrepoResponse response = 262 client.post(new URI(SERVER_ADDRESS)) 263 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 264 .filename(filename) 265 .slug(slug) 266 .perform()) { 267 268 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 269 final int status = response.getStatusCode(); 270 createdResourceUri = response.getLocation(); 271 272 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 273 CREATED.getStatusCode(), status); 274 assertEquals("Location did not match slug", SERVER_ADDRESS + slug, response.getLocation().toString()); 275 276 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 277 } 278 279 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 280 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 281 assertEquals(expectedFilename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 282 283 assertEquals(mimetype, getResponse.getContentType()); 284 285 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 286 assertEquals(bodyContent, getContent); 287 } 288 } 289 290 @Test 291 public void testPutBinaryFilenameSpecialCharacters() throws Exception { 292 final String id = UUID.randomUUID().toString(); 293 final String filename = "hello world\nof_weird:+\tchar/acters.tx\rt"; 294 final String expectedFilename = "hello world of_weird:+\tchar/acters.tx t"; 295 final String mimetype = "text/plain"; 296 final String bodyContent = "Hello world"; 297 298 final URI createdResourceUri; 299 try (final FcrepoResponse response = 300 client.put(new URI(SERVER_ADDRESS + id)) 301 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 302 .filename(filename) 303 .perform()) { 304 305 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 306 final int status = response.getStatusCode(); 307 createdResourceUri = response.getLocation(); 308 309 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 310 CREATED.getStatusCode(), status); 311 assertEquals("Location did not match slug", SERVER_ADDRESS + id, response.getLocation().toString()); 312 313 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 314 } 315 316 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 317 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 318 assertEquals(expectedFilename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 319 320 assertEquals(mimetype, getResponse.getContentType()); 321 322 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 323 assertEquals(bodyContent, getContent); 324 } 325 } 326 327 @Test 328 public void testPut() throws Exception { 329 try (final FcrepoResponse response = create()) { 330 assertEquals(CREATED.getStatusCode(), response.getStatusCode()); 331 assertEquals(url, response.getLocation()); 332 } 333 } 334 335 @Test 336 public void testPutEtag() throws Exception { 337 // Create object 338 final EntityTag etag; 339 try (final FcrepoResponse response = create()) { 340 // Get the etag of the nearly created object 341 etag = EntityTag.valueOf(response.getHeaderValue(ETAG)); 342 } 343 344 // Retrieve the body of the resource so we can modify it 345 String body = getTurtle(url); 346 body += "\n<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 347 348 // Check that etag is making it through and being rejected 349 try (final FcrepoResponse updateResp = client.put(url) 350 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 351 .ifMatch("\"bad-etag\"") 352 .perform()) { 353 354 assertEquals(PRECONDITION_FAILED.getStatusCode(), updateResp.getStatusCode()); 355 } 356 357 // Verify that etag is retrieved and resubmitted correctly 358 try (final FcrepoResponse validResp = client.put(url) 359 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 360 .ifMatch("\"" + etag.getValue() + "\"") 361 .perform()) { 362 assertEquals(NO_CONTENT.getStatusCode(), validResp.getStatusCode()); 363 } 364 } 365 366 @Test 367 public void testPutUnmodifiedSince() throws Exception { 368 // Create object 369 final String originalModified; 370 try (final FcrepoResponse response = create()) { 371 originalModified = response.getHeaderValue(LAST_MODIFIED); 372 } 373 374 // Retrieve the body of the resource so we can modify it 375 String body = getTurtle(url); 376 body += "\n<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 377 378 // Update the body the first time, which should succeed 379 try (final FcrepoResponse matchResponse = client.put(url) 380 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 381 .ifUnmodifiedSince(originalModified) 382 .perform()) { 383 384 assertEquals(NO_CONTENT.getStatusCode(), matchResponse.getStatusCode()); 385 } 386 387 // Update the triples a second time with old timestamp 388 try (final FcrepoResponse mismatchResponse = client.put(url) 389 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 390 .ifUnmodifiedSince(UNMODIFIED_DATE) 391 .perform()) { 392 393 assertEquals(PRECONDITION_FAILED.getStatusCode(), mismatchResponse.getStatusCode()); 394 } 395 } 396 397 @Test 398 public void testPutLenient() throws Exception { 399 // Create object 400 try (final FcrepoResponse response = create()) { 401 } 402 403 final String body = "<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 404 405 // try to update without lenient header 406 try (final FcrepoResponse strictResponse = client.put(url) 407 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 408 .perform()) { 409 assertEquals(NO_CONTENT.getStatusCode(), strictResponse.getStatusCode()); 410 } 411 412 // try again with lenient header 413 try (final FcrepoResponse lenientResponse = client.put(url) 414 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 415 .preferLenient() 416 .perform()) { 417 assertEquals(NO_CONTENT.getStatusCode(), lenientResponse.getStatusCode()); 418 } 419 } 420 421 @Test 422 public void testPutExternalContent() throws Exception { 423 final String filename = "put.txt"; 424 final String mimetype = "text/plain"; 425 final String fileContent = "Hello put world"; 426 427 final Path contentPath = Files.createTempFile(null, ".txt"); 428 FileUtils.write(contentPath.toFile(), fileContent, "UTF-8"); 429 430 final URI createdResourceUri; 431 try (final FcrepoResponse response = client.put(url) 432 .externalContent(contentPath.toUri(), mimetype, ExternalContentHandling.PROXY) 433 .filename(filename) 434 .perform()) { 435 436 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 437 final int status = response.getStatusCode(); 438 createdResourceUri = response.getLocation(); 439 440 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 441 CREATED.getStatusCode(), status); 442 } 443 444 try (final FcrepoResponse getResponse = client.get(createdResourceUri).perform()) { 445 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 446 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 447 448 assertEquals(mimetype, getResponse.getContentType()); 449 450 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 451 assertEquals(fileContent, getContent); 452 } 453 } 454 455 @Test 456 public void testPutBinaryNullFilename() throws Exception { 457 final String bodyContent = "Hello world"; 458 459 try (final FcrepoResponse response = client.put(url) 460 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 461 .filename(null) 462 .perform()) { 463 assertEquals("Empty filename rejected", CREATED.getStatusCode(), response.getStatusCode()); 464 } 465 } 466 467 @Test 468 public void testPatch() throws Exception { 469 // Create object 470 try (final FcrepoResponse response = create()) { 471 } 472 473 // Update triples with sparql update 474 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 475 try (final FcrepoResponse response = client.patch(url) 476 .body(body) 477 .perform()) { 478 479 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 480 } 481 } 482 483 @Test 484 public void testPatchEtagUpdated() throws Exception { 485 // Create object 486 final EntityTag createdEtag; 487 try (final FcrepoResponse createResp = create()) { 488 createdEtag = EntityTag.valueOf(createResp.getHeaderValue(ETAG)); 489 } 490 491 // Update triples with sparql update 492 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 493 try (final FcrepoResponse response = client.patch(url) 494 .body(body) 495 .ifMatch("\"" + createdEtag.getValue() + "\"") 496 .perform()) { 497 498 final EntityTag updateEtag = EntityTag.valueOf(response.getHeaderValue(ETAG)); 499 500 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 501 assertNotEquals("Etag did not change after patch", createdEtag, updateEtag); 502 } 503 } 504 505 @Test 506 public void testPatchNoBody() throws Exception { 507 try (final FcrepoResponse response = create()) { 508 } 509 510 try (final FcrepoResponse response = client.patch(url) 511 .perform()) { 512 assertEquals(BAD_REQUEST.getStatusCode(), response.getStatusCode()); 513 } 514 } 515 516 @Test 517 public void testDelete() throws Exception { 518 try (final FcrepoResponse response = create()) { 519 } 520 521 try (final FcrepoResponse response = client.delete(url).perform()) { 522 523 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 524 525 assertEquals(GONE.getStatusCode(), client.get(url).perform().getStatusCode()); 526 } 527 } 528 529 @Test 530 public void testGet() throws Exception { 531 try (final FcrepoResponse response = create()) { 532 } 533 534 try (final FcrepoResponse response = client.get(url).perform()) { 535 assertEquals(OK.getStatusCode(), response.getStatusCode()); 536 } 537 } 538 539 @Test 540 public void testGetNotFound() throws Exception { 541 try (final FcrepoResponse response = client.get(url).perform()) { 542 assertEquals(NOT_FOUND.getStatusCode(), response.getStatusCode()); 543 } 544 } 545 546 @Test 547 public void testGetUnmodified() throws Exception { 548 549 final String lastModified; 550 try (final FcrepoResponse response = create()) { 551 lastModified = response.getHeaderValue(LAST_MODIFIED); 552 } 553 554 // Get tomorrows date to provide as the modified-since date 555 final Date modDate = DateUtils.parseDate(lastModified); 556 final Calendar cal = Calendar.getInstance(); 557 cal.setTime(modDate); 558 cal.add(Calendar.DATE, 1); 559 560 // Check that get returns a 304 if the item hasn't changed according to last-modified 561 try (final FcrepoResponse modResp = client.get(url) 562 .ifModifiedSince(DateUtils.formatDate(cal.getTime())) 563 .perform()) { 564 565 assertEquals(NOT_MODIFIED.getStatusCode(), modResp.getStatusCode()); 566 assertNull("Response body should not be returned when unmodified", modResp.getBody()); 567 } 568 } 569 570 @Test 571 public void testGetModified() throws Exception { 572 573 final String lastModified; 574 try (final FcrepoResponse response = create()) { 575 lastModified = response.getHeaderValue(LAST_MODIFIED); 576 } 577 578 // Get yesterdays date to provide as the modified-since date 579 final Date modDate = DateUtils.parseDate(lastModified); 580 final Calendar cal = Calendar.getInstance(); 581 cal.setTime(modDate); 582 cal.add(Calendar.DATE, -1); 583 584 // Check that get returns a 200 if the item has changed according to last-modified 585 try (final FcrepoResponse modResp = client.get(url) 586 .ifModifiedSince(DateUtils.formatDate(cal.getTime())) 587 .perform()) { 588 589 assertEquals(OK.getStatusCode(), modResp.getStatusCode()); 590 assertNotNull("GET response body should be normal when modified", modResp.getBody()); 591 } 592 } 593 594 @Test 595 public void testGetAccept() throws Exception { 596 try (final FcrepoResponse response = create()) { 597 } 598 599 try (final FcrepoResponse response = client.get(url) 600 .accept("application/n-triples") 601 .perform()) { 602 603 assertEquals("application/n-triples", response.getHeaderValue(CONTENT_TYPE)); 604 assertEquals(OK.getStatusCode(), response.getStatusCode()); 605 } 606 } 607 608 @Test 609 public void testGetPrefer() throws Exception { 610 try (final FcrepoResponse response = create()) { 611 } 612 613 try (final FcrepoResponse response = client.get(url) 614 .preferRepresentation(Arrays.asList(URI.create("http://www.w3.org/ns/ldp#PreferMinimalContainer")), 615 Arrays.asList(URI.create("http://fedora.info/definitions/fcrepo#ServerManaged"))).perform()) { 616 617 assertEquals(OK.getStatusCode(), response.getStatusCode()); 618 assertEquals("return=representation; include=\"http://www.w3.org/ns/ldp#PreferMinimalContainer\"; " + 619 "omit=\"http://fedora.info/definitions/fcrepo#ServerManaged\"", 620 response.getHeaderValue("Preference-Applied")); 621 } 622 } 623 624 @Test 625 public void testGetRange() throws Exception { 626 // Creating a binary for retrieval 627 final String mimetype = "text/plain"; 628 final String bodyContent = "Hello world"; 629 final URI createdResourceUri; 630 try (final FcrepoResponse response = client.post(new URI(SERVER_ADDRESS)) 631 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 632 .perform()) { 633 634 createdResourceUri = response.getLocation(); 635 } 636 637 // Get the content of the object after the first 6 bytes 638 try (final FcrepoResponse rangeResp = client.get(createdResourceUri) 639 .range(6L, null) 640 .perform()) { 641 642 final String content = IOUtils.toString(rangeResp.getBody(), "UTF-8"); 643 assertEquals("Body did not contain correct range of original content", "world", content); 644 assertEquals(PARTIAL_CONTENT.getStatusCode(), rangeResp.getStatusCode()); 645 } 646 } 647 648 @Test 649 public void testGetDisableRedirects() throws Exception { 650 final String filename = "example.html"; 651 final String mimetype = "text/plain"; 652 653 final URI externalURI = URI.create("http://example.com/"); 654 final URI resourceLocation; 655 656 try (final FcrepoResponse response = client.post(new URI(SERVER_ADDRESS)) 657 .externalContent(externalURI, mimetype, ExternalContentHandling.REDIRECT) 658 .filename(filename) 659 .perform() 660 ) { 661 resourceLocation = response.getLocation(); 662 } 663 664 try (final FcrepoResponse getResponse = client.get(resourceLocation) 665 .disableRedirects() 666 .perform(); 667 ) { 668 assertEquals("Didn't get a REDIRECT response!", 669 TEMPORARY_REDIRECT.getStatusCode(), getResponse.getStatusCode()); 670 assertEquals(mimetype, getResponse.getContentType()); 671 672 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 673 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 674 675 assertEquals(externalURI, getResponse.getLocation()); 676 } 677 } 678 679 @Test 680 public void testGetWantDigest() throws Exception { 681 // Creating a binary for retrieval 682 final String mimetype = "text/plain"; 683 final String bodyContent = "Hello world"; 684 685 final URI createdResourceUri; 686 try (final FcrepoResponse response = client.post(new URI(SERVER_ADDRESS)) 687 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 688 .perform()) { 689 createdResourceUri = response.getLocation(); 690 } 691 692 // Request md5 digest with caching disabled 693 try (final FcrepoResponse getResp = client.get(createdResourceUri) 694 .wantDigest("md5") 695 .noCache() 696 .perform()) { 697 assertEquals(OK.getStatusCode(), getResp.getStatusCode()); 698 699 final String digest = getResp.getHeaderValue(DIGEST); 700 assertTrue("Did not contain md5", digest.contains("md5=3e25960a79dbc69b674cd4ec67a72c62")); 701 } 702 } 703 704 @Test 705 public void testHead() throws Exception { 706 try (final FcrepoResponse response = create(); 707 final FcrepoResponse headResp = client.head(url).perform()) { 708 709 assertEquals(OK.getStatusCode(), headResp.getStatusCode()); 710 assertEquals(response.getHeaderValue(ETAG), headResp.getHeaderValue(ETAG)); 711 assertNotNull(headResp.getHeaderValue("Allow")); 712 } 713 } 714 715 @Test 716 public void testHeadWantDigest() throws Exception { 717 // Creating a binary for retrieval 718 final String mimetype = "text/plain"; 719 final String bodyContent = "Hello world"; 720 final URI createdResourceUri; 721 try (final FcrepoResponse response = client.post(new URI(SERVER_ADDRESS)) 722 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 723 .perform()) { 724 725 createdResourceUri = response.getLocation(); 726 } 727 728 final Map<String, Double> qualityMap = new HashMap<>(); 729 qualityMap.put("md5", 1.0); 730 qualityMap.put("sha", 1.0); 731 qualityMap.put("sha-256", 0.4); 732 733 final String wantDigest = HeaderHelpers.formatQualityValues(qualityMap); 734 // Request multiple digests 735 try (final FcrepoResponse getResp = client.head(createdResourceUri) 736 .wantDigest(wantDigest) 737 .perform()) { 738 assertEquals(OK.getStatusCode(), getResp.getStatusCode()); 739 740 final String digest = getResp.getHeaderValue(DIGEST); 741 assertTrue("Did not contain md5", digest.contains("md5=3e25960a79dbc69b674cd4ec67a72c62")); 742 assertTrue("Did not contain sha1", digest.contains("sha=7b502c3a1f48c8609ae212cdfb639dee39673f5e")); 743 assertTrue("Did not contain sha256", digest 744 .contains("sha-256=64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c")); 745 } 746 } 747 748 @Test 749 public void testOptions() throws Exception { 750 try (final FcrepoResponse response = create()) { 751 } 752 753 try (final FcrepoResponse headResp = client.options(url).perform()) { 754 755 assertEquals(OK.getStatusCode(), headResp.getStatusCode()); 756 assertNotNull(headResp.getHeaderValue("Allow")); 757 assertNotNull(headResp.getHeaderValue("Accept-Post")); 758 assertNotNull(headResp.getHeaderValue("Accept-Patch")); 759 } 760 } 761 762 @Test 763 public void testStateTokens() throws Exception { 764 try (final FcrepoResponse response = create()) { 765 } 766 767 final String stateToken; 768 try (final FcrepoResponse getResp = client.get(url).perform()) { 769 stateToken = getResp.getHeaderValue(STATE_TOKEN); 770 } 771 772 // Attempt to update triples with an incorrect state token 773 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 774 try (final FcrepoResponse badTokenResp = client.patch(url) 775 .body(body) 776 .ifStateToken("bad_state_token") 777 .perform()) { 778 assertEquals(PRECONDITION_FAILED.getStatusCode(), badTokenResp.getStatusCode()); 779 } 780 781 // Update triples with the correct state token 782 body.reset(); 783 try (final FcrepoResponse goodTokenResp = client.patch(url) 784 .body(body) 785 .ifStateToken(stateToken) 786 .perform()) { 787 assertEquals(NO_CONTENT.getStatusCode(), goodTokenResp.getStatusCode()); 788 } 789 } 790 791 private FcrepoResponse create() throws FcrepoOperationFailedException { 792 return client.put(url).perform(); 793 } 794 795 private String getTurtle(final URI url) throws Exception { 796 try (final FcrepoResponse getResponse = client.get(url) 797 .accept("text/turtle") 798 .preferRepresentation(Arrays.asList(URI.create("http://www.w3.org/ns/ldp#PreferMinimalContainer")), 799 Arrays.asList(URI.create("http://fedora.info/definitions/fcrepo#ServerManaged"))).perform()) { 800 return IOUtils.toString(getResponse.getBody(), "UTF-8"); 801 } 802 } 803}