@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)); }
@Override public CompletionStage<Void> delete(final Metadata metadata) { LOGGER.debug("Deleting: {}", metadata.getIdentifier()); return runAsync(() -> { try (final Dataset dataset = rdf.createDataset()) { final Instant time = now(); final Metadata md = Metadata.builder(metadata.getIdentifier()).interactionModel(LDP.Resource).build(); storeResource(md, dataset, time, OperationType.DELETE); } catch (final Exception ex) { throw new RuntimeTrellisException("Error deleting resoruce: " + metadata.getIdentifier(), ex); } }); }
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 testAddAuditTriples() throws Exception { final TriplestoreResourceService svc = new TriplestoreResourceService( connect(wrap(rdf.createDataset().asJenaDatasetGraph()))); svc.initialize(); final Dataset dataset1 = rdf.createDataset(); final Dataset dataset2 = rdf.createDataset(); final BlankNode bnode = rdf.createBlankNode(); dataset1.add(Trellis.PreferUserManaged, resource, DC.title, rdf.createLiteral("resource")); dataset1.add(Trellis.PreferUserManaged, resource, DC.alternative, rdf.createLiteral("alt title")); dataset2.add(Trellis.PreferAudit, resource, PROV.wasGeneratedBy, bnode); dataset2.add(Trellis.PreferAudit, bnode, RDF.type, AS.Create); final Instant later = meanwhile(); assertDoesNotThrow(() -> allOf( svc.create(builder(resource).interactionModel(LDP.Container).container(root).build(), dataset1) .toCompletableFuture(), svc.add(resource, dataset2).toCompletableFuture(), svc.touch(root).toCompletableFuture()).join(), "Unsuccessful create operation!"); allOf( svc.get(resource).thenAccept(checkResource(later, LDP.Container, 2L, 2L, 0L)).toCompletableFuture(), svc.get(root).thenAccept(checkRoot(later, 1L)).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!"); }
@Test public void testPutLdpRs() throws Exception { final TriplestoreResourceService svc = new TriplestoreResourceService( connect(wrap(rdf.createDataset().asJenaDatasetGraph()))); svc.initialize(); final Dataset dataset = rdf.createDataset(); final BlankNode bnode = rdf.createBlankNode(); dataset.add(Trellis.PreferUserManaged, resource, DC.title, rdf.createLiteral("title")); dataset.add(Trellis.PreferAudit, resource, PROV.wasGeneratedBy, bnode); dataset.add(Trellis.PreferAudit, bnode, RDF.type, PROV.Activity); dataset.add(Trellis.PreferAudit, bnode, RDF.type, AS.Create); final Instant later = meanwhile(); assertDoesNotThrow(() -> allOf( svc.create(builder(resource).interactionModel(LDP.RDFSource).container(root).build(), dataset) .toCompletableFuture(), svc.touch(root).toCompletableFuture()).join(), "Unsuccessful create operation!"); allOf( svc.get(resource).thenAccept(checkResource(later, LDP.RDFSource, 1L, 3L, 0L)).toCompletableFuture(), svc.get(root).thenAccept(checkRoot(later, 1L)).toCompletableFuture()).join(); }
@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 testRDFConnectionError() throws Exception { final TriplestoreResourceService svc = new TriplestoreResourceService(mockRdfConnection); svc.initialize(); doThrow(new RuntimeException("Expected exception")).when(mockRdfConnection).update(any(UpdateRequest.class)); doThrow(new RuntimeException("Expected exception")).when(mockRdfConnection) .loadDataset(any(org.apache.jena.query.Dataset.class)); assertThrows(ExecutionException.class, () -> svc.create(builder(resource).interactionModel(LDP.RDFSource).container(root).build(), rdf.createDataset()).toCompletableFuture().get(), "No (create) exception with dropped backend connection!"); assertThrows(ExecutionException.class, () -> svc.add(resource, rdf.createDataset()).toCompletableFuture().get(), "No (add) exception with dropped backend connection!"); assertThrows(ExecutionException.class, () -> svc.delete(builder(resource).interactionModel(LDP.RDFSource).container(root).build()) .toCompletableFuture().get(), "No (delete) exception with dropped backend connection!"); assertThrows(ExecutionException.class, () -> svc.touch(resource).toCompletableFuture().get(), "No (touch) exception with dropped backend connection!"); }
/** * Test an LDP:RDFSource. * @throws Exception if the create operation fails */ @Test @DisplayName("Test LDP-RS") default void testLdpRs() throws Exception { final Instant time = now(); final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Create LDP-RS 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 the creation of an LDP-RS"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the LDP-RS resource", checkResource(res, identifier, LDP.RDFSource, time, dataset)); assertEquals(3L, res.stream(Trellis.PreferUserManaged).count(), "Check the user triple count"); }
/** * 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))); }
/** * Test an LDP:RDFSource. * @throws Exception if the create operation fails */ @Test @DisplayName("Test LDP-RS") default void testLdpRs() throws Exception { final Instant time = now(); final RDF rdf = getInstance(); final IRI identifier = rdf.createIRI(TRELLIS_DATA_PREFIX + getResourceService().generateIdentifier()); final Dataset dataset = buildDataset(identifier, "Create LDP-RS 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 the creation of an LDP-RS"); final Resource res = getResourceService().get(identifier).toCompletableFuture().join(); assertAll("Check the LDP-RS resource", checkResource(res, identifier, LDP.RDFSource, time, dataset)); assertEquals(3L, res.stream(Trellis.PreferUserManaged).count(), "Check the user triple count"); }
/** * 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))); }
@Test public void testMetadataResource() { final Resource mockResource = mock(Resource.class); when(mockResource.getContainer()).thenReturn(of(root)); when(mockResource.getInteractionModel()).thenReturn(LDP.RDFSource); when(mockResource.getIdentifier()).thenReturn(identifier); final Metadata metadata = Metadata.builder(mockResource).build(); assertEquals(identifier, metadata.getIdentifier()); assertEquals(LDP.RDFSource, metadata.getInteractionModel()); assertEquals(of(root), metadata.getContainer()); assertFalse(metadata.getBinary().isPresent()); assertFalse(metadata.getMembershipResource().isPresent()); assertFalse(metadata.getMemberOfRelation().isPresent()); assertFalse(metadata.getInsertedContentRelation().isPresent()); assertFalse(metadata.getMemberRelation().isPresent()); } }
@Test public void testMetadataIndirectContainer() { final Metadata metadata = Metadata.builder(identifier) .interactionModel(LDP.IndirectContainer) .container(root).memberRelation(LDP.member) .membershipResource(member) .insertedContentRelation(FOAF.primaryTopic).build(); assertEquals(identifier, metadata.getIdentifier()); assertEquals(LDP.IndirectContainer, metadata.getInteractionModel()); assertEquals(of(root), metadata.getContainer()); assertEquals(of(member), metadata.getMembershipResource()); assertEquals(of(LDP.member), metadata.getMemberRelation()); assertEquals(of(FOAF.primaryTopic), metadata.getInsertedContentRelation()); assertFalse(metadata.getMemberOfRelation().isPresent()); assertFalse(metadata.getBinary().isPresent()); }
@Test public void testPutLdpRsWithoutBaseUrl() throws Exception { final TriplestoreResourceService svc = new TriplestoreResourceService( connect(wrap(rdf.createDataset().asJenaDatasetGraph()))); svc.initialize(); final Dataset dataset = rdf.createDataset(); dataset.add(Trellis.PreferUserManaged, resource, DC.title, rdf.createLiteral("title")); dataset.add(Trellis.PreferAudit, rdf.createBlankNode(), RDF.type, AS.Create); final Instant later = meanwhile(); assertDoesNotThrow(() -> allOf( svc.create(builder(resource).interactionModel(LDP.RDFSource).container(root).build(), dataset) .toCompletableFuture(), svc.touch(root).toCompletableFuture()).join(), "Unsuccessful create operation!"); allOf( svc.get(resource).thenAccept(checkResource(later, LDP.RDFSource, 1L, 1L, 0L)).toCompletableFuture(), svc.get(root).thenAccept(checkRoot(later, 1L)).toCompletableFuture()).join(); }
@Test public void testMetadataDirectContainer() { final Metadata metadata = Metadata.builder(identifier) .interactionModel(LDP.DirectContainer) .container(root).memberOfRelation(DC.isPartOf) .membershipResource(member).build(); assertEquals(identifier, metadata.getIdentifier()); assertEquals(LDP.DirectContainer, metadata.getInteractionModel()); assertEquals(of(root), metadata.getContainer()); assertEquals(of(member), metadata.getMembershipResource()); assertEquals(of(DC.isPartOf), metadata.getMemberOfRelation()); assertFalse(metadata.getInsertedContentRelation().isPresent()); assertFalse(metadata.getMemberRelation().isPresent()); assertFalse(metadata.getBinary().isPresent()); }
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 testMetadataBinary() { final BinaryMetadata binary = BinaryMetadata.builder(rdf.createIRI("http://example.com/binary")).build(); final Metadata metadata = Metadata.builder(identifier) .interactionModel(LDP.NonRDFSource) .container(root).binary(binary).build(); assertEquals(identifier, metadata.getIdentifier()); assertEquals(LDP.NonRDFSource, metadata.getInteractionModel()); assertEquals(of(root), metadata.getContainer()); assertEquals(of(binary), metadata.getBinary()); assertFalse(metadata.getMembershipResource().isPresent()); assertFalse(metadata.getMemberOfRelation().isPresent()); assertFalse(metadata.getInsertedContentRelation().isPresent()); assertFalse(metadata.getMemberRelation().isPresent()); }
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 testBadPersist() { final Quad testQuad = createQuad(badId, testResourceId1, testResourceId1, badId); final Resource testResource = new TestResource(badId, testQuad); assertThrows(CompletionException.class, () -> testable.create(Metadata.builder(testResource).build(), testResource.dataset()).toCompletableFuture() .join(), "Could create a resource when underlying services should reject it!"); }