private CompletionStage<Void> createOrReplace(final Metadata metadata, final TrellisDataset ds) { if (isNull(getResource())) { LOGGER.debug("Creating new resource {}", internalId); return getServices().getResourceService().create(metadata, ds.asDataset()); } else { LOGGER.debug("Replacing old resource {}", internalId); return getServices().getResourceService().replace(metadata, ds.asDataset()); } }
private Stream<Executable> verifyInteractions(final ResourceService svc) { return of( () -> verify(svc, never().description("Don't re-initialize the root if it already exists")) .create(any(Metadata.class), any(Dataset.class)), () -> verify(svc, never().description("Don't re-initialize the root if it already exists")) .replace(any(Metadata.class), any(Dataset.class)), () -> verify(svc, description("Verify that the root resource is fetched only once")).get(root)); } }
private void setUpResourceService() { when(mockResourceService.supportedInteractionModels()).thenReturn(allInteractionModels); when(mockResourceService.get(any(IRI.class))).thenAnswer(inv -> completedFuture(mockResource)); when(mockResourceService.create(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.delete(any(Metadata.class))).thenReturn(completedFuture(null)); when(mockResourceService.add(any(IRI.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.skolemize(any(Literal.class))).then(returnsFirstArg()); when(mockResourceService.skolemize(any(IRI.class))).then(returnsFirstArg()); when(mockResourceService.skolemize(any(BlankNode.class))).thenAnswer(inv -> rdf.createIRI(TRELLIS_BNODE_PREFIX + ((BlankNode) inv.getArgument(0)).uniqueReference())); when(mockResourceService.toInternal(any(RDFTerm.class), any())).thenCallRealMethod(); when(mockResourceService.toExternal(any(RDFTerm.class), any())).thenCallRealMethod(); when(mockResourceService.touch(any(IRI.class))).thenReturn(completedFuture(null)); }
@Test public void testInitializeExistingLdpResourceWithNoACL() throws Exception { final ResourceService mockService = mock(ResourceService.class); when(mockBundler.getResourceService()).thenReturn(mockService); when(mockService.get(eq(root))).thenAnswer(inv -> completedFuture(mockRootResource)); when(mockRootResource.hasAcl()).thenReturn(false); when(mockService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); final TrellisHttpResource matcher = new TrellisHttpResource(mockBundler); matcher.initialize(); verify(mockService, never().description("When re-initializing the root ACL, create should not be called")) .create(any(Metadata.class), any(Dataset.class)); verify(mockService, description("Use replace when re-initializing the root ACL")) .replace(any(Metadata.class), any(Dataset.class)); verify(mockService, description("Verify that the root resource is fetched only once")).get(root); }
@Test public void testDefaultCreate() { final IRI root = rdf.createIRI("trellis:data/"); final Dataset dataset = rdf.createDataset(); final Metadata metadata = Metadata.builder(existing).container(root).interactionModel(LDP.RDFSource).build(); when(mockResourceService.replace(eq(metadata), eq(dataset))).thenReturn(completedFuture(null)); assertDoesNotThrow(() -> mockResourceService.create(metadata, dataset).toCompletableFuture().join()); verify(mockResourceService).replace(eq(metadata), eq(dataset)); }
@Test public void testEntity() { final Triple triple = rdf.createTriple(identifier, RDFS.label, rdf.createLiteral("A label")); when(mockTrellisRequest.getContentType()).thenReturn(APPLICATION_SPARQL_UPDATE); when(mockResource.stream(eq(PreferUserManaged))).thenAnswer(x -> of(triple)); when(mockTrellisRequest.getPath()).thenReturn("resource"); final PatchHandler patchHandler = new PatchHandler(mockTrellisRequest, insert, mockBundler, null, null); final Response res = patchHandler.updateResource(patchHandler.initialize(mockParent, mockResource)) .toCompletableFuture().join().build(); assertEquals(NO_CONTENT, res.getStatusInfo(), "Incorrect response code!"); verify(mockIoService).update(any(Graph.class), eq(insert), eq(SPARQL_UPDATE), eq(identifier.getIRIString())); verify(mockResourceService).replace(any(Metadata.class), any(Dataset.class)); }
@Test public void testInitializeoNoLdpResource() throws Exception { final ResourceService mockService = mock(ResourceService.class); when(mockBundler.getResourceService()).thenReturn(mockService); when(mockService.get(eq(root))).thenAnswer(inv -> completedFuture(MISSING_RESOURCE)); when(mockService.create(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); final TrellisHttpResource matcher = new TrellisHttpResource(mockBundler); matcher.initialize(); verify(mockService, description("Re-create a missing root resource on initialization")) .create(any(Metadata.class), any(Dataset.class)); verify(mockService, never().description("Don't try to replace a non-existent root on initialization")) .replace(any(Metadata.class), any(Dataset.class)); verify(mockService, description("Verify that the root resource is fetched only once")).get(root); }
@Test public void testInitializeoDeletedLdpResource() throws Exception { final ResourceService mockService = mock(ResourceService.class); when(mockBundler.getResourceService()).thenReturn(mockService); when(mockService.get(eq(root))).thenAnswer(inv -> completedFuture(DELETED_RESOURCE)); when(mockService.create(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); final TrellisHttpResource matcher = new TrellisHttpResource(mockBundler); matcher.initialize(); verify(mockService, description("A previously deleted root resource should be re-created upon initialization")) .create(any(Metadata.class), any(Dataset.class)); verify(mockService, never().description("replace shouldn't be called when re-initializing a deleted root")) .replace(any(Metadata.class), any(Dataset.class)); verify(mockService, description("Verify that the root resource is fetched only once")).get(root); }
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); }
@Test public void testDeleteACLAuditError() { when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.add(any(IRI.class), any(Dataset.class))).thenReturn(asyncException()); when(mockTrellisRequest.getExt()).thenReturn(ACL); final DeleteHandler handler = new DeleteHandler(mockTrellisRequest, mockBundler, baseUrl); assertThrows(CompletionException.class, () -> unwrapAsyncError(handler.deleteResource(handler.initialize(mockParent, mockResource))), "No exception thrown when an ACL audit stream couldn't be written!"); } }
protected CompletionStage<Void> handleResourceReplacement(final TrellisDataset mutable, final TrellisDataset immutable) { final Metadata.Builder metadata = metadataBuilder(getResource().getIdentifier(), getResource().getInteractionModel(), mutable); getResource().getContainer().ifPresent(metadata::container); getResource().getBinaryMetadata().ifPresent(metadata::binary); // update the resource return allOf( getServices().getResourceService().replace(metadata.build(), mutable.asDataset()).toCompletableFuture(), getServices().getResourceService().add(getResource().getIdentifier(), immutable.asDataset()).toCompletableFuture()); }
@Test public void testError() { when(mockTrellisRequest.getContentType()).thenReturn(APPLICATION_SPARQL_UPDATE); when(mockTrellisRequest.getPath()).thenReturn("resource"); when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(asyncException()); final PatchHandler patchHandler = new PatchHandler(mockTrellisRequest, insert, mockBundler, null, null); assertThrows(CompletionException.class, () -> unwrapAsyncError(patchHandler.updateResource(patchHandler.initialize(mockParent, mockResource))), "No exception thrown when the backend triggers an exception!"); }
@Test public void testDeleteACLError() { when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(asyncException()); when(mockTrellisRequest.getExt()).thenReturn(ACL); final DeleteHandler handler = new DeleteHandler(mockTrellisRequest, mockBundler, baseUrl); assertThrows(CompletionException.class, () -> unwrapAsyncError(handler.deleteResource(handler.initialize(mockParent, mockResource))), "No exception thrown when an ACL couldn't be deleted!"); }
@Test public void testError() { when(mockResource.getInteractionModel()).thenReturn(LDP.NonRDFSource); when(mockTrellisRequest.getPath()).thenReturn("resource"); when(mockTrellisRequest.getContentType()).thenReturn(TEXT_PLAIN); when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.NonRDFSource.getIRIString()).rel("type").build()); when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(asyncException()); final PutHandler handler = buildPutHandler("/simpleData.txt", null); assertThrows(CompletionException.class, () -> unwrapAsyncError(handler.setResource(handler.initialize(mockParent, mockResource))), "No exception when there's a problem with the backend!"); }
when(mockResourceService.add(any(IRI.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.delete(any(Metadata.class))).thenReturn(completedFuture(null)); when(mockResourceService.replace(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.create(any(Metadata.class), any(Dataset.class))).thenReturn(completedFuture(null)); when(mockResourceService.unskolemize(any(Literal.class))).then(returnsFirstArg());
/** * Test replacing a resource. * @throws Exception if the operation failed */ @Test @DisplayName("Test replacing resource") default void testReplaceResource() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Replacement Test", SUBJECT2); assertEquals(MISSING_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check for no pre-existing LDP-RS"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the LDP-RS was successfully created"); dataset.clear(); dataset.add(Trellis.PreferUserManaged, identifier, SKOS.prefLabel, rdf.createLiteral("preferred label")); dataset.add(Trellis.PreferUserManaged, identifier, SKOS.altLabel, rdf.createLiteral("alternate label")); dataset.add(Trellis.PreferUserManaged, identifier, type, SKOS.Concept); assertDoesNotThrow(() -> getResourceService().replace(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the LDP-RS was successfully replaced"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the replaced LDP-RS stream", res.stream(Trellis.PreferUserManaged) .map(toQuad(Trellis.PreferUserManaged)) .map(q -> () -> assertTrue(dataset.contains(q), "Check that the quad comes from the dataset: " + q))); assertEquals(3L, res.stream(Trellis.PreferUserManaged).count(), "Check the total user-managed triple count"); }
/** * Test replacing a resource. * @throws Exception if the operation failed */ @Test @DisplayName("Test replacing resource") default void testReplaceResource() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Replacement Test", SUBJECT2); assertEquals(MISSING_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check for no pre-existing LDP-RS"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the LDP-RS was successfully created"); dataset.clear(); dataset.add(Trellis.PreferUserManaged, identifier, SKOS.prefLabel, rdf.createLiteral("preferred label")); dataset.add(Trellis.PreferUserManaged, identifier, SKOS.altLabel, rdf.createLiteral("alternate label")); dataset.add(Trellis.PreferUserManaged, identifier, type, SKOS.Concept); assertDoesNotThrow(() -> getResourceService().replace(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset) .toCompletableFuture().join(), "Check that the LDP-RS was successfully replaced"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the replaced LDP-RS stream", res.stream(Trellis.PreferUserManaged) .map(toQuad(Trellis.PreferUserManaged)) .map(q -> () -> assertTrue(dataset.contains(q), "Check that the quad comes from the dataset: " + q))); assertEquals(3L, res.stream(Trellis.PreferUserManaged).count(), "Check the total user-managed triple count"); }
@Test public void testRoundtripping() { final Quad testQuad = createQuad(testResourceId1, testResourceId1, testResourceId1, badId); final Resource testResource = new TestResource(testResourceId1, testQuad); assertNull(testable.create(Metadata.builder(testResourceId1).interactionModel(LDP.RDFSource).build(), testResource.dataset()).toCompletableFuture().join(), "Couldn't create a resource!"); Resource retrieved = testable.get(testResourceId1).toCompletableFuture().join(); assertEquals(testResource.getIdentifier(), retrieved.getIdentifier(), "Resource was retrieved with wrong ID!"); assertEquals(testResource.stream().findFirst().get(), retrieved.stream().findFirst().get(), "Resource was retrieved with wrong data!"); final Quad testQuad2 = createQuad(testResourceId1, badId, testResourceId1, badId); final Resource testResource2 = new TestResource(testResourceId1, testQuad2); assertNull(testable.replace(Metadata.builder(testResource2).interactionModel(LDP.RDFSource).build(), testResource2.dataset()).toCompletableFuture().join(), "Couldn't replace resource!"); retrieved = testable.get(testResourceId1).toCompletableFuture().join(); assertEquals(testResource2.getIdentifier(), retrieved.getIdentifier(), "Resource was retrieved with wrong ID!"); assertEquals(testResource2.stream().findFirst().get(), retrieved.stream().findFirst().get(), "Resource was retrieved with wrong data!"); assertNull(testable.delete(Metadata.builder(testResourceId1).interactionModel(LDP.RDFSource).build()) .toCompletableFuture().join(), "Couldn't delete resource!"); assertEquals(MISSING_RESOURCE, testable.get(testResourceId1).toCompletableFuture().join(), "Found resource after deleting it!"); }