@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()); } }
@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 void createOrReplace(final Metadata metadata, final Dataset dataset, final OperationType type) { final Instant eventTime = now(); // Set the LDP type dataset.add(PreferServerManaged, metadata.getIdentifier(), RDF.type, metadata.getInteractionModel()); // Relocate some user-managed triples into the server-managed graph metadata.getMembershipResource().ifPresent(member -> { dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.member, getBaseIRI(member)); dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.membershipResource, member); }); metadata.getMemberRelation().ifPresent(relation -> dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.hasMemberRelation, relation)); metadata.getMemberOfRelation().ifPresent(relation -> dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.isMemberOfRelation, relation)); if (asList(LDP.IndirectContainer, LDP.DirectContainer).contains(metadata.getInteractionModel())) { dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.insertedContentRelation, metadata.getInsertedContentRelation().orElse(LDP.MemberSubject)); } // Set the parent relationship metadata.getContainer().ifPresent(parent -> dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.isPartOf, parent)); metadata.getBinary().ifPresent(binary -> { dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.hasPart, binary.getIdentifier()); binary.getMimeType().map(rdf::createLiteral).ifPresent(mimeType -> dataset.add(PreferServerManaged, binary.getIdentifier(), DC.format, mimeType)); }); storeResource(metadata.getIdentifier(), dataset, eventTime, type); }
protected Metadata.Builder metadataBuilder(final IRI identifier, final IRI ixnModel, final TrellisDataset mutable) { final Metadata.Builder builder = Metadata.builder(identifier).interactionModel(ixnModel); mutable.asDataset().getGraph(Trellis.PreferUserManaged).ifPresent(graph -> { graph.stream(identifier, LDP.membershipResource, null).findFirst().map(Triple::getObject) .filter(IRI.class::isInstance).map(IRI.class::cast).ifPresent(builder::membershipResource); graph.stream(identifier, LDP.hasMemberRelation, null).findFirst().map(Triple::getObject) .filter(IRI.class::isInstance).map(IRI.class::cast).ifPresent(builder::memberRelation); graph.stream(identifier, LDP.isMemberOfRelation, null).findFirst().map(Triple::getObject) .filter(IRI.class::isInstance).map(IRI.class::cast).ifPresent(builder::memberOfRelation); graph.stream(identifier, LDP.insertedContentRelation, null).findFirst().map(Triple::getObject) .filter(IRI.class::isInstance).map(IRI.class::cast).ifPresent(builder::insertedContentRelation); }); return builder; }
@Override public CompletionStage<Void> create(final Metadata metadata, final Dataset dataset) { LOGGER.debug("Creating: {}", metadata.getIdentifier()); return runAsync(() -> storeResource(metadata, dataset, now(), OperationType.CREATE)); }
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); }
@Override public CompletionStage<Void> replace(final Metadata metadata, final Dataset dataset) { LOGGER.debug("Updating: {}", metadata.getIdentifier()); return runAsync(() -> storeResource(metadata, dataset, now(), OperationType.REPLACE)); }
private void createOrReplace(final Metadata metadata, final Dataset dataset, final OperationType type) { final Instant eventTime = now(); // Set the LDP type dataset.add(PreferServerManaged, metadata.getIdentifier(), RDF.type, metadata.getInteractionModel()); // Relocate some user-managed triples into the server-managed graph metadata.getMembershipResource().ifPresent(member -> { dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.member, getBaseIRI(member)); dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.membershipResource, member); }); metadata.getMemberRelation().ifPresent(relation -> dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.hasMemberRelation, relation)); metadata.getMemberOfRelation().ifPresent(relation -> dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.isMemberOfRelation, relation)); if (asList(LDP.IndirectContainer, LDP.DirectContainer).contains(metadata.getInteractionModel())) { dataset.add(PreferServerManaged, metadata.getIdentifier(), LDP.insertedContentRelation, metadata.getInsertedContentRelation().orElse(LDP.MemberSubject)); } // Set the parent relationship metadata.getContainer().ifPresent(parent -> dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.isPartOf, parent)); metadata.getBinary().ifPresent(binary -> { dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.hasPart, binary.getIdentifier()); binary.getMimeType().map(rdf::createLiteral).ifPresent(mimeType -> dataset.add(PreferServerManaged, binary.getIdentifier(), DC.format, mimeType)); }); storeResource(metadata.getIdentifier(), dataset, eventTime, type); }
/** * A mutable builder for a {@link Metadata} object. * * @param r the resource * @return a builder for a {@link Metadata} object */ public static Builder builder(final Resource r) { return builder(r.getIdentifier()).interactionModel(r.getInteractionModel()) .container(r.getContainer().orElse(null)) .memberRelation(r.getMemberRelation().orElse(null)) .membershipResource(r.getMembershipResource().orElse(null)) .memberOfRelation(r.getMemberOfRelation().orElse(null)) .insertedContentRelation(r.getInsertedContentRelation().orElse(null)); }
@Override public CompletionStage<Void> replace(final Metadata metadata, final Dataset dataset) { LOGGER.debug("Persisting: {}", metadata.getIdentifier()); return runAsync(() -> createOrReplace(metadata, dataset, OperationType.REPLACE)); }
private static int updateResource(final Handle handle, final Metadata metadata, final Dataset dataset, final Instant time, final boolean isDelete) { handle.execute("DELETE FROM resource WHERE subject = ?", metadata.getIdentifier().getIRIString()); final String query = "INSERT INTO resource (subject, interaction_model, modified, deleted, is_part_of, acl, " + "ldp_member, ldp_membership_resource, ldp_has_member_relation, ldp_is_member_of_relation, " + "ldp_inserted_content_relation, binary_location, binary_format) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // Set ldp:insertedContentRelation only for LDP-IC and LDP-DC resources final String icr = asList(LDP.DirectContainer, LDP.IndirectContainer).contains(metadata.getInteractionModel()) ? metadata.getInsertedContentRelation().orElse(LDP.MemberSubject).getIRIString() : null; try (final Update update = handle.createUpdate(query) .bind(0, metadata.getIdentifier().getIRIString()) .bind(1, metadata.getInteractionModel().getIRIString()) .bind(2, time.toEpochMilli()) .bind(3, isDelete) .bind(4, metadata.getContainer().map(IRI::getIRIString).orElse(null)) .bind(5, dataset.contains(of(PreferAccessControl), null, null, null)) .bind(6, metadata.getMembershipResource().map(IRI::getIRIString) .map(str -> str.split("#")[0]).orElse(null)) .bind(7, metadata.getMembershipResource().map(IRI::getIRIString).orElse(null)) .bind(8, metadata.getMemberRelation().map(IRI::getIRIString).orElse(null)) .bind(9, metadata.getMemberOfRelation().map(IRI::getIRIString).orElse(null)) .bind(10, icr) .bind(11, metadata.getBinary().map(BinaryMetadata::getIdentifier).map(IRI::getIRIString).orElse(null)) .bind(12, metadata.getBinary().flatMap(BinaryMetadata::getMimeType).orElse(null))) { return update.executeAndReturnGeneratedKeys("id").mapTo(Integer.class).findOnly(); } }
/** * A mutable builder for a {@link Metadata} object. * * @param r the resource * @return a builder for a {@link Metadata} object */ public static Builder builder(final Resource r) { return builder(r.getIdentifier()).interactionModel(r.getInteractionModel()) .container(r.getContainer().orElse(null)) .memberRelation(r.getMemberRelation().orElse(null)) .membershipResource(r.getMembershipResource().orElse(null)) .memberOfRelation(r.getMemberOfRelation().orElse(null)) .insertedContentRelation(r.getInsertedContentRelation().orElse(null)); }
@Override public CompletionStage<Void> replace(final Metadata metadata, final Dataset dataset) { LOGGER.debug("Persisting: {}", metadata.getIdentifier()); return runAsync(() -> createOrReplace(metadata, dataset, OperationType.REPLACE)); }
@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 eventTime = now(); dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.type, DeletedResource); dataset.add(PreferServerManaged, metadata.getIdentifier(), RDF.type, LDP.Resource); storeResource(metadata.getIdentifier(), dataset, eventTime, OperationType.DELETE); } catch (final Exception ex) { throw new RuntimeTrellisException("Error deleting resource: " + metadata.getIdentifier(), ex); } }); }
@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()); }
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()); } }
@Override public CompletionStage<Void> delete(final Metadata metadata) { LOGGER.debug("Deleting: {}", metadata.getIdentifier()); return runAsync(() -> { try (final Dataset dataset = rdf.createDataset()) { final Instant eventTime = now(); dataset.add(PreferServerManaged, metadata.getIdentifier(), DC.type, DeletedResource); dataset.add(PreferServerManaged, metadata.getIdentifier(), RDF.type, LDP.Resource); storeResource(metadata.getIdentifier(), dataset, eventTime, OperationType.DELETE); } catch (final Exception ex) { throw new RuntimeTrellisException("Error deleting resource: " + metadata.getIdentifier(), ex); } }); }
@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()); }
/** * 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))); }