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 creating a resource. * @throws Exception if the operation failed */ @Test @DisplayName("Test creating resource") default void testCreateResource() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Creation Test", SUBJECT1); 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 resource was successfully created"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check resource stream", res.stream(Trellis.PreferUserManaged).map(toQuad(Trellis.PreferUserManaged)) .map(q -> () -> assertTrue(dataset.contains(q), "Verify that the quad is from the dataset: " + q))); }
/** * Convert triples from an external form to a skolemized form. * * @param svc the resourceService * @param baseUrl the base URL * @return a mapping function */ public static Function<Triple, Triple> skolemizeTriples(final ResourceService svc, final String baseUrl) { return triple -> rdf.createTriple((BlankNodeOrIRI) svc.toInternal(svc.skolemize(triple.getSubject()), baseUrl), triple.getPredicate(), svc.toInternal(svc.skolemize(triple.getObject()), baseUrl)); }
private void setUpResourceService() { when(mockResourceService.get(eq(nonexistentIRI))).thenAnswer(inv -> completedFuture(MISSING_RESOURCE)); when(mockResourceService.supportedInteractionModels()).thenReturn(allModels); when(mockResourceService.get(eq(resourceIRI))).thenAnswer(inv -> completedFuture(mockResource)); when(mockResourceService.get(eq(childIRI))).thenAnswer(inv -> completedFuture(mockChildResource)); when(mockResourceService.get(eq(parentIRI))).thenAnswer(inv -> completedFuture(mockParentResource)); when(mockResourceService.get(eq(rootIRI))).thenAnswer(inv -> completedFuture(mockRootResource)); when(mockResourceService.get(eq(groupIRI))).thenAnswer(inv -> completedFuture(mockGroupResource)); when(mockResourceService.get(eq(memberIRI))).thenAnswer(inv -> completedFuture(mockMemberResource)); }
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 CompletionStage<? extends Resource> getParent(final IRI identifier) { final Optional<IRI> parent = getContainer(identifier); if (parent.isPresent()) { return trellis.getResourceService().get(parent.get()); } return completedFuture(MISSING_RESOURCE); }
assumeTrue(getResourceService().supportedInteractionModels().contains(LDP.DirectContainer)); final String base = TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier(); final IRI identifier = rdf.createIRI(base); final IRI member = rdf.createIRI(base + "/member"); assertEquals(MISSING_RESOURCE, getResourceService().get(identifier).toCompletableFuture().join(), "Check that the DC doesn't exist"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .membershipResource(member).memberOfRelation(DC.isPartOf) .interactionModel(LDP.DirectContainer).container(ROOT_CONTAINER).build(), dataset0) assertEquals(MISSING_RESOURCE, getResourceService().get(child1).toCompletableFuture().join(), "Check that no child resource exists"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(child1).interactionModel(LDP.RDFSource) .container(identifier).build(), dataset1).toCompletableFuture().join(), "Check that the child resource is successfully created"); assertEquals(MISSING_RESOURCE, getResourceService().get(child2).toCompletableFuture().join(), "Check that no child2 resource exists"); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(child2).interactionModel(LDP.RDFSource) .container(identifier).build(), dataset2).toCompletableFuture().join(), "Check that the child2 resource is successfully created"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the resource", checkResource(res, identifier, LDP.DirectContainer, time, dataset0)); assertEquals(of(member), res.getMembershipResource(), "Check for ldp:membershipResource");
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)); } }
/** * 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 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"); }
default void testAddImmutableData() throws Exception { final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset0 = buildDataset(identifier, "Immutable Resource Test", SUBJECT2); assertDoesNotThrow(() -> getResourceService().create(Metadata.builder(identifier) .interactionModel(LDP.RDFSource).container(ROOT_CONTAINER).build(), dataset0) .toCompletableFuture().join(), "Check the successful creation of an LDP-RS"); final IRI audit1 = rdf.createIRI(TRELLIS_BNODE_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset1 = rdf.createDataset(); dataset1.add(Trellis.PreferAudit, identifier, PROV.wasGeneratedBy, audit1); assertDoesNotThrow(() -> getResourceService().add(identifier, dataset1).toCompletableFuture().join(), "Check the successful addition of audit quads"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the audit stream", res.stream(Trellis.PreferAudit).map(toQuad(Trellis.PreferAudit)) .map(q -> () -> assertTrue(dataset1.contains(q), "Check that the audit stream includes: " + q))); assertEquals(4L, res.stream(Trellis.PreferAudit).count(), "Check the audit triple count"); final IRI audit2 = rdf.createIRI(TRELLIS_BNODE_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset2 = rdf.createDataset(); dataset2.add(Trellis.PreferAudit, identifier, PROV.wasGeneratedBy, audit2); assertDoesNotThrow(() -> getResourceService().add(identifier, dataset2).toCompletableFuture().join(), "Check that audit triples are added successfully"); final Resource res2 = getResourceService().get(identifier).toCompletableFuture().join();
@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!"); }
@BeforeEach public void setUp() { initMocks(this); doCallRealMethod().when(mockResourceService).skolemize(any()); doCallRealMethod().when(mockResourceService).unskolemize(any()); doCallRealMethod().when(mockResourceService).toInternal(any(), any()); doCallRealMethod().when(mockResourceService).toExternal(any(), any()); doCallRealMethod().when(mockResourceService).create(any(), any()); when(mockRetrievalService.get(eq(existing))).thenAnswer(inv -> completedFuture(mockResource)); }
@Test public void testMergingBehavior() { final Quad testMutableQuad = createQuad(testResourceId2, testResourceId2, testResourceId1, badId); final Quad testImmutableQuad = createQuad(testResourceId2, testResourceId2, testResourceId1, badId); // store some data in mutable and immutable sides under the same resource ID final Resource testMutableResource = new TestResource(testResourceId2, testMutableQuad); assertNull(testable.create(Metadata.builder(testMutableResource).build(), testMutableResource.dataset()) .toCompletableFuture().join(), "Couldn't create a resource!"); final Resource testImmutableResource = new TestResource(testResourceId2, testImmutableQuad); assertNull(testable.add(testResourceId2, testImmutableResource.dataset()).toCompletableFuture().join(), "Couldn't create an immutable resource!"); final Resource retrieved = testable.get(testResourceId2).toCompletableFuture().join(); assertEquals(testMutableResource.getIdentifier(), retrieved.getIdentifier(), "Resource was retrieved with wrong ID!"); final Dataset quads = retrieved.dataset(); assertTrue(quads.contains(testImmutableQuad), "Resource was retrieved without its immutable data!"); assertTrue(quads.contains(testMutableQuad), "Resource was retrieved without its mutable data!"); quads.remove(testImmutableQuad); quads.remove(testMutableQuad); assertEquals(0, quads.size(), "Resource was retrieved with too much data!"); }
@Test public void testAppendSemantics() { final Quad testFirstQuad = createQuad(testResourceId3, testResourceId2, testResourceId1, badId); final Quad testSecondQuad = createQuad(testResourceId3, testResourceId2, testResourceId1, badId); // store some data in mutable and immutable sides under the same resource ID final Resource testFirstResource = new TestResource(testResourceId3, testFirstQuad); assertNull(testable.add(testResourceId3, testFirstResource.dataset()).toCompletableFuture().join(), "Couldn't create an immutable resource!"); final Resource testSecondResource = new TestResource(testResourceId3, testSecondQuad); assertNull(testable.add(testResourceId3, testSecondResource.dataset()).toCompletableFuture().join(), "Couldn't add to an immutable resource!"); final Resource retrieved = testable.get(testResourceId3).toCompletableFuture().join(); assertEquals(testResourceId3, retrieved.getIdentifier(), "Resource was retrieved with wrong ID!"); final Dataset quads = retrieved.dataset(); assertTrue(quads.contains(testFirstQuad), "Resource was retrieved without its immutable data!"); assertTrue(quads.contains(testSecondQuad), "Resource was retrieved without its mutable data!"); quads.remove(testFirstQuad); quads.remove(testSecondQuad); assertEquals(0, quads.size(), "Resource was retrieved with too much data!"); }
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()); }
/** * Check that the given interaction model is supported by the * underlying persistence layer. * * @param interactionModel the interaction model * @return true if the interaction model is supported; false otherwise */ protected boolean supportsInteractionModel(final IRI interactionModel) { return getServices().getResourceService().supportedInteractionModels().contains(interactionModel); }
private CompletionStage<Void> handleResourceDeletion(final TrellisDataset immutable) { // Collect the audit data getServices().getAuditService().deletion(getResource().getIdentifier(), getSession()).stream() .map(skolemizeQuads(getServices().getResourceService(), getBaseUrl())) .forEachOrdered(immutable::add); // delete the resource return allOf( getServices().getResourceService().delete(Metadata.builder(getResource()).build()).toCompletableFuture(), getServices().getResourceService().add(getResource().getIdentifier(), immutable.asDataset()).toCompletableFuture()); } }
@Test public void testBadAudit() throws IOException { when(mockResource.getInteractionModel()).thenReturn(LDP.BasicContainer); when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.BasicContainer.getIRIString()).rel("type").build()); when(mockTrellisRequest.getContentType()).thenReturn(TEXT_TURTLE); when(mockBundler.getAuditService()).thenReturn(new DefaultAuditService() {}); when(mockResourceService.add(any(IRI.class), any(Dataset.class))).thenReturn(asyncException()); final PostHandler handler = buildPostHandler("/simpleTriple.ttl", null, null); assertThrows(CompletionException.class, () -> unwrapAsyncError(handler.createResource(handler.initialize(mockParent, MISSING_RESOURCE))), "No exception when the backend audit service throws an error!"); }