return trellis.getResourceService().get(identifier) .thenCombine(trellis.getMementoService().mementos(identifier), (res, mementos) -> { if (MISSING_RESOURCE.equals(res)) { throw new NotFoundException(); return trellis.getMementoService().get(identifier, req.getDatetime().getInstant()) .thenCombine(trellis.getMementoService().mementos(identifier), (res, mementos) -> { if (MISSING_RESOURCE.equals(res)) { throw new NotAcceptableException();
/** * Initialize the response. * @param parent the parent resource * @param child the child resource * @return a response builder */ public ResponseBuilder initialize(final Resource parent, final Resource child) { if (MISSING_RESOURCE.equals(parent)) { // Can't POST to a missing resource throw new NotFoundException(); } else if (DELETED_RESOURCE.equals(parent)) { // Can't POST to a deleted resource throw new ClientErrorException(GONE); } else if (ACL.equals(getRequest().getExt()) || ldpResourceTypes(parent.getInteractionModel()).noneMatch(LDP.Container::equals)) { // Can't POST to an ACL resource or non-Container throw new NotAllowedException(GET, Stream.of(HEAD, OPTIONS, PATCH, PUT, DELETE).toArray(String[]::new)); } else if (!MISSING_RESOURCE.equals(child) && !DELETED_RESOURCE.equals(child)) { throw new ClientErrorException(CONFLICT); } else if (!supportsInteractionModel(ldpType)) { throw new BadRequestException("Unsupported interaction model provided", status(BAD_REQUEST) .link(UnsupportedInteractionModel.getIRIString(), LDP.constrainedBy.getIRIString()).build()); } else if (ldpType.equals(LDP.NonRDFSource) && nonNull(rdfSyntax)) { LOGGER.error("Cannot save {} as a NonRDFSource with RDF syntax", getIdentifier()); throw new BadRequestException("Cannot save resource as a NonRDFSource with RDF syntax"); } setParent(parent); return status(CREATED); }
/** * Initialze the handler with a Trellis resource. * * @param parent the parent resource * @param resource the Trellis resource * @return a response builder */ public ResponseBuilder initialize(final Resource parent, final Resource resource) { // Check that the persistence layer supports LDP-R if (MISSING_RESOURCE.equals(resource)) { // Can't delete a non-existent resources throw new NotFoundException(); } else if (DELETED_RESOURCE.equals(resource)) { // Can't delete a non-existent resources throw new ClientErrorException(GONE); } else if (!supportsInteractionModel(LDP.Resource)) { throw new ClientErrorException(status(BAD_REQUEST) .link(UnsupportedInteractionModel.getIRIString(), LDP.constrainedBy.getIRIString()) .entity("Unsupported interaction model provided").type(TEXT_PLAIN_TYPE).build()); } // Check the cache final EntityTag etag = new EntityTag(buildEtagHash(getIdentifier(), resource.getModified(), null)); checkCache(resource.getModified(), etag); setResource(resource); resource.getContainer().ifPresent(p -> setParent(parent)); return noContent(); }
/** * Initialize the response handler. * @param parent the parent resource * @param resource the resource * @return the response builder */ public ResponseBuilder initialize(final Resource parent, final Resource resource) { setResource(DELETED_RESOURCE.equals(resource) || MISSING_RESOURCE.equals(resource) ? null : resource); // Check the cache if (nonNull(getResource())) { final Instant modified = getResource().getModified(); final EntityTag etag; if (getResource().getBinaryMetadata().isPresent() && !ofNullable(getRequest().getContentType()).flatMap(RDFSyntax::byMediaType).isPresent()) { etag = new EntityTag(buildEtagHash(getIdentifier() + "BINARY", modified, null)); } else { etag = new EntityTag(buildEtagHash(getIdentifier(), modified, getRequest().getPrefer())); } // Check the cache checkRequiredPreconditions(preconditionRequired, getRequest().getHeaders().getFirst(IF_MATCH), getRequest().getHeaders().getFirst(IF_UNMODIFIED_SINCE)); checkCache(modified, etag); } // One cannot put binaries into the ACL graph if (ACL.equals(getRequest().getExt()) && isNull(rdfSyntax)) { throw new NotAcceptableException(); } ofNullable(resource).flatMap(Resource::getContainer).ifPresent(p -> setParent(parent)); return status(NO_CONTENT); }
/** * Test deleting a resource. * @throws Exception if the operation failed */ @Test @DisplayName("Test deleting resource") default void testDeleteResource() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Deletion Test", SUBJECT1); assertEquals(MISSING_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check that the resource doesn't exist"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the resource was successfully created"); assertNotEquals(DELETED_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check that the resource isn't currently 'deleted'"); assertDoesNotThrow(() -> getResourceService().delete(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build()).toCompletableFuture().join(), "Check that the delete operation succeeded"); final Resource resource = getResourceService().get(identifier).toCompletableFuture().join(); assertTrue(DELETED_RESOURCE.equals(resource) || MISSING_RESOURCE.equals(resource), "Verify that the resource is marked as deleted or missing"); }
/** * Test deleting a resource. * @throws Exception if the operation failed */ @Test @DisplayName("Test deleting resource") default void testDeleteResource() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Deletion Test", SUBJECT1); assertEquals(MISSING_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check that the resource doesn't exist"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the resource was successfully created"); assertNotEquals(DELETED_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check that the resource isn't currently 'deleted'"); assertDoesNotThrow(() -> getResourceService().delete(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build()).toCompletableFuture().join(), "Check that the delete operation succeeded"); final Resource resource = getResourceService().get(identifier).toCompletableFuture().join(); assertTrue(DELETED_RESOURCE.equals(resource) || MISSING_RESOURCE.equals(resource), "Verify that the resource is marked as deleted or missing"); }
/** * Initialize the get handler. * @param resource the Trellis resource * @return the response builder */ public ResponseBuilder initialize(final Resource resource) { if (MISSING_RESOURCE.equals(resource)) { throw new NotFoundException(); } else if (DELETED_RESOURCE.equals(resource)) { throw new ClientErrorException(GONE); } LOGGER.debug("Acceptable media types: {}", getRequest().getAcceptableMediaTypes()); this.syntax = getSyntax(getServices().getIOService(), getRequest().getAcceptableMediaTypes(), resource.getBinaryMetadata() .filter(b -> !DESCRIPTION.equals(getRequest().getExt())) .map(b -> b.getMimeType().orElse(APPLICATION_OCTET_STREAM))).orElse(null); if (ACL.equals(getRequest().getExt()) && !resource.hasAcl()) { throw new NotFoundException(); } setResource(resource); return ok(); }
@Override public CompletionStage<Resource> get(final IRI identifier) { return mutableData.get(identifier).thenCombine(immutableData.get(identifier), (mutable, immutable) -> { if (MISSING_RESOURCE.equals(mutable) && MISSING_RESOURCE.equals(immutable)) { return MISSING_RESOURCE; } else if (MISSING_RESOURCE.equals(mutable)) { return immutable; } else if (MISSING_RESOURCE.equals(immutable)) { return mutable; } else { return new RetrievableResource(mutable, immutable); } }); }
private CompletionStage<Void> initialize(final IRI id, final Resource res, final TrellisDataset dataset) { if (MISSING_RESOURCE.equals(res) || DELETED_RESOURCE.equals(res)) { LOGGER.info("Initializing root container: {}", id); return trellis.getResourceService().create(Metadata.builder(id).interactionModel(LDP.BasicContainer) .build(), dataset.asDataset()); } else if (!res.hasAcl()) { LOGGER.info("Initializeing root ACL: {}", id); try (final Stream<Triple> triples = res.stream(Trellis.PreferUserManaged)) { triples.map(toQuad(Trellis.PreferUserManaged)).forEach(dataset::add); } return trellis.getResourceService().replace(Metadata.builder(res).build(), dataset.asDataset()); } return completedFuture(null); }
/** * Initialize the request handler. * @param resource the Trellis resource * @return a response builder */ public ResponseBuilder initialize(final Resource resource) { if (MISSING_RESOURCE.equals(resource)) { throw new NotFoundException(); } else if (DELETED_RESOURCE.equals(resource)) { throw new ClientErrorException(GONE); } setResource(resource); return status(NO_CONTENT); }
@Override public CompletionStage<Resource> get(final IRI identifier) { return mutableData.get(identifier).thenCombine(immutableData.get(identifier), (mutable, immutable) -> { if (MISSING_RESOURCE.equals(mutable) && MISSING_RESOURCE.equals(immutable)) { return MISSING_RESOURCE; } else if (MISSING_RESOURCE.equals(mutable)) { return immutable; } else if (MISSING_RESOURCE.equals(immutable)) { return mutable; } else { return new RetrievableResource(mutable, immutable); } }); }
@Test public void testMissingResource() { assertNull(MISSING_RESOURCE.getIdentifier(), "Missing resource has an identifier!"); assertNull(MISSING_RESOURCE.getInteractionModel(), "Missing resource has an interaction model!"); assertNull(MISSING_RESOURCE.getModified(), "Missing resource has a last modified date!"); assertFalse(MISSING_RESOURCE.getContainer().isPresent(), "Missing resource has a parent resource!"); assertEquals(0L, MISSING_RESOURCE.stream().count(), "Missing resource contains triples!"); assertEquals("A non-existent resource", MISSING_RESOURCE.toString(), "Missing resource has wrong string repr."); }
@Test public void testDeletedResource() { assertNull(DELETED_RESOURCE.getIdentifier(), "Deleted resource has an identifier!"); assertNull(DELETED_RESOURCE.getInteractionModel(), "Deleted resource has an interaction model!"); assertNull(DELETED_RESOURCE.getModified(), "Deleted resource has a modification date!"); assertFalse(DELETED_RESOURCE.getContainer().isPresent(), "Deleted resource has a parent resource!"); assertEquals(0L, DELETED_RESOURCE.stream().count(), "Deleted resource contains triples!"); assertEquals("A deleted resource", DELETED_RESOURCE.toString(), "Deleted resource has wrong string repr."); } }