Skip to content

Commit

Permalink
fix: add dedicated type for body artifacts and isBodyOf relation with…
Browse files Browse the repository at this point in the history
… agent id
  • Loading branch information
cake-lier committed Jan 20, 2024
1 parent 9f796f8 commit fd55462
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 88 deletions.
11 changes: 7 additions & 4 deletions src/test/resources/test_agent_body_sub.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
@prefix js: <https://www.w3.org/2019/wot/json-schema#> .
@prefix saref: <https://w3id.org/saref#> .

<http://localhost:8080/workspaces/sub/agents/test_agent> a td:Thing, hmas:Artifact;
<http://localhost:8080/workspaces/sub/agents/test_agent> a td:Thing, <https://example.org/Body>,
hmas:Artifact;
td:title "test_agent";
td:hasSecurityConfiguration [ a wotsec:NoSecurityScheme
] .

<http://localhost:8080/workspaces/sub/agents/test_agent> hmas:isContainedIn <http://localhost:8080/workspaces/sub> .
];
hmas:isContainedIn <http://localhost:8080/workspaces/sub>;
<https://example.org/isBodyOf> <http://localhost:8080/agents/test_agent> .

<http://localhost:8080/workspaces/sub> a hmas:Workspace .

<http://localhost:8080/agents/test_agent> a hmas:Agent .
11 changes: 7 additions & 4 deletions src/test/resources/test_agent_body_test.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
@prefix js: <https://www.w3.org/2019/wot/json-schema#> .
@prefix saref: <https://w3id.org/saref#> .

<http://localhost:8080/workspaces/test/agents/test_agent> a td:Thing, hmas:Artifact;
<http://localhost:8080/workspaces/test/agents/test_agent> a td:Thing, <https://example.org/Body>,
hmas:Artifact;
td:title "test_agent";
td:hasSecurityConfiguration [ a wotsec:NoSecurityScheme
] .

<http://localhost:8080/workspaces/test/agents/test_agent> hmas:isContainedIn <http://localhost:8080/workspaces/test> .
];
hmas:isContainedIn <http://localhost:8080/workspaces/test>;
<https://example.org/isBodyOf> <http://localhost:8080/agents/test_agent> .

<http://localhost:8080/workspaces/test> a hmas:Workspace .

<http://localhost:8080/agents/test_agent> a hmas:Agent .
3 changes: 2 additions & 1 deletion yggdrasil-cartago/src/test/resources/test_agent_body.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
@prefix js: <https://www.w3.org/2019/wot/json-schema#> .
@prefix hmas: <https://purl.org/hmas/core/> .

<http://localhost:8080/workspaces/test/agents/test> a td:Thing, hmas:Artifact;
<http://localhost:8080/workspaces/test/agents/test> a td:Thing, <https://example.org/Body>,
hmas:Artifact;
td:title "test";
td:hasSecurityConfiguration [ a wotsec:NoSecurityScheme
] .
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ public void handleJoinWorkspace(final RoutingContext routingContext) {
))
.compose(response ->
this.rdfStoreMessagebox
.sendMessage(new RdfStoreMessage.CreateArtifact(
this.httpConfig.getAgentBodiesUri(workspaceName) + "/",
.sendMessage(new RdfStoreMessage.CreateBody(
workspaceName,
this.getAgentNameFromId(agentId),
response.body()
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.apache.commons.lang3.function.Failable;
import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.hyperagents.yggdrasil.eventbus.messageboxes.HttpNotificationDispatcherMessagebox;
Expand All @@ -25,6 +25,7 @@
import org.hyperagents.yggdrasil.eventbus.messages.HttpNotificationDispatcherMessage;
import org.hyperagents.yggdrasil.eventbus.messages.RdfStoreMessage;
import org.hyperagents.yggdrasil.store.impl.RdfStoreFactory;
import org.hyperagents.yggdrasil.utils.HttpInterfaceConfig;
import org.hyperagents.yggdrasil.utils.JsonObjectUtils;
import org.hyperagents.yggdrasil.utils.RdfModelUtils;
import org.hyperagents.yggdrasil.utils.impl.HttpInterfaceConfigImpl;
Expand All @@ -39,12 +40,13 @@ public class RdfStoreVerticle extends AbstractVerticle {
private static final String CONTAINS_HMAS_IRI = "https://purl.org/hmas/core/contains";

private Messagebox<HttpNotificationDispatcherMessage> dispatcherMessagebox;
private HttpInterfaceConfig httpConfig;
private RdfStore store;

@SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault")
@Override
public void start(final Promise<Void> startPromise) {
final var httpConfig = new HttpInterfaceConfigImpl(this.config());
this.httpConfig = new HttpInterfaceConfigImpl(this.config());
this.dispatcherMessagebox = new HttpNotificationDispatcherMessagebox(this.vertx.eventBus());
final var ownMessagebox = new RdfStoreMessagebox(this.vertx.eventBus());
ownMessagebox.init();
Expand Down Expand Up @@ -80,6 +82,7 @@ public void start(final Promise<Void> startPromise) {
String responseContentType
) ->
this.handleQuery(query, defaultGraphUris, namedGraphUris, responseContentType, message);
case RdfStoreMessage.CreateBody content -> this.handleCreateBody(content, message);
}
} catch (final IllegalArgumentException e) {
LOGGER.error(e);
Expand Down Expand Up @@ -111,11 +114,11 @@ public void start(final Promise<Void> startPromise) {
}
}))
.orElse(RdfStoreFactory.createInMemoryStore());
final var platformIri = RdfModelUtils.createIri(httpConfig.getBaseUri() + "/");
final var platformIri = RdfModelUtils.createIri(this.httpConfig.getBaseUri() + "/");
this.store.addEntityModel(
platformIri,
RdfModelUtils.stringToModel(
new RepresentationFactoryImpl(httpConfig).createPlatformRepresentation(),
new RepresentationFactoryImpl(this.httpConfig).createPlatformRepresentation(),
platformIri,
RDFFormat.TURTLE
)
Expand Down Expand Up @@ -147,70 +150,80 @@ private void handleGetEntity(
}
}

/**
* Creates a body artifact and adds it to the store.
*/
private void handleCreateBody(
final RdfStoreMessage.CreateBody content,
final Message<RdfStoreMessage> message
) throws IOException {
final var bodyIri = this.httpConfig.getAgentBodyUri(
content.workspaceName(),
content.agentName()
);
final var entityIri = RdfModelUtils.createIri(bodyIri);
Optional
.ofNullable(content.bodyRepresentation())
.filter(s -> !s.isEmpty())
// Replace all null relative IRIs with the IRI generated for this entity
.map(s -> s.replaceAll("<>", "<" + bodyIri + ">"))
.ifPresentOrElse(
Failable.asConsumer(s -> {
final var entityModel = RdfModelUtils.stringToModel(s, entityIri, RDFFormat.TURTLE);
final var workspaceIri =
RdfModelUtils.createIri(this.httpConfig.getWorkspaceUri(content.workspaceName()));
this.enrichArtifactGraphWithWorkspace(entityIri, entityModel, workspaceIri);
final var agentIri =
RdfModelUtils.createIri(this.httpConfig.getAgentUri(content.agentName()));
entityModel.add(
entityIri,
RdfModelUtils.createIri("https://example.org/isBodyOf"),
agentIri
);
entityModel.add(
agentIri,
RDF.TYPE,
RdfModelUtils.createIri("https://purl.org/hmas/core/Agent")
);
this.store.addEntityModel(entityIri, entityModel);
final var stringGraphResult =
RdfModelUtils.modelToString(entityModel, RDFFormat.TURTLE);
this.dispatcherMessagebox.sendMessage(
new HttpNotificationDispatcherMessage.EntityCreated(
this.httpConfig.getAgentBodiesUri(content.workspaceName()) + "/",
stringGraphResult
)
);
this.replyWithPayload(message, stringGraphResult);
}),
() -> this.replyFailed(message)
);
}

/**
* Creates an artifact and adds it to the store.
*
* @param requestIri IRI where the request originated from
* @param message Request
*/
private void handleCreateArtifact(
final IRI requestIri,
final RdfStoreMessage.CreateArtifact content,
final Message<RdfStoreMessage> message
) throws IOException {
// Create IRI for new entity
final var entityIriString =
final var artifactIri =
this.generateEntityIri(requestIri.toString(), content.artifactName());
final var entityIri = RdfModelUtils.createIri(entityIriString);
final var entityIri = RdfModelUtils.createIri(artifactIri);
Optional
.ofNullable(content.artifactRepresentation())
.filter(s -> !s.isEmpty())
// Replace all null relative IRIs with the IRI generated for this entity
.map(s -> s.replaceAll("<>", "<" + entityIriString + ">"))
.map(s -> s.replaceAll("<>", "<" + artifactIri + ">"))
.ifPresentOrElse(
Failable.asConsumer(s -> {
final var entityModel = RdfModelUtils.stringToModel(s, entityIri, RDFFormat.TURTLE);
final var artifactIri = entityIri.toString();
final var workspaceIri =
RdfModelUtils.createIri(
Pattern.compile("^(https?://.*?:[0-9]+/workspaces/.*?)/(?:artifacts|agents)/.*?$")
.matcher(artifactIri)
.results()
.findFirst()
.orElseThrow()
.group(1)
);
entityModel.add(
entityIri,
RdfModelUtils.createIri("https://purl.org/hmas/core/isContainedIn"),
workspaceIri
final var workspaceIri = RdfModelUtils.createIri(
artifactIri.substring(0, artifactIri.indexOf("/artifacts/"))
);
entityModel.add(
workspaceIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store
.getEntityModel(workspaceIri)
.ifPresent(Failable.asConsumer(workspaceModel -> {
workspaceModel.add(
workspaceIri,
RdfModelUtils.createIri(CONTAINS_HMAS_IRI),
entityIri
);
workspaceModel.add(
entityIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RdfModelUtils.createIri("https://purl.org/hmas/core/Artifact")
);
this.store.replaceEntityModel(workspaceIri, workspaceModel);
this.dispatcherMessagebox.sendMessage(
new HttpNotificationDispatcherMessage.EntityChanged(
workspaceIri.toString(),
RdfModelUtils.modelToString(workspaceModel, RDFFormat.TURTLE)
)
);
}));
this.enrichArtifactGraphWithWorkspace(entityIri, entityModel, workspaceIri);
this.store.addEntityModel(entityIri, entityModel);
final var stringGraphResult =
RdfModelUtils.modelToString(entityModel, RDFFormat.TURTLE);
Expand All @@ -226,6 +239,44 @@ private void handleCreateArtifact(
);
}

private void enrichArtifactGraphWithWorkspace(
final IRI entityIri,
final Model entityModel,
final IRI workspaceIri
) throws IOException {
entityModel.add(
entityIri,
RdfModelUtils.createIri("https://purl.org/hmas/core/isContainedIn"),
workspaceIri
);
entityModel.add(
workspaceIri,
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store
.getEntityModel(workspaceIri)
.ifPresent(Failable.asConsumer(workspaceModel -> {
workspaceModel.add(
workspaceIri,
RdfModelUtils.createIri(CONTAINS_HMAS_IRI),
entityIri
);
workspaceModel.add(
entityIri,
RDF.TYPE,
RdfModelUtils.createIri("https://purl.org/hmas/core/Artifact")
);
this.store.replaceEntityModel(workspaceIri, workspaceModel);
this.dispatcherMessagebox.sendMessage(
new HttpNotificationDispatcherMessage.EntityChanged(
workspaceIri.toString(),
RdfModelUtils.modelToString(workspaceModel, RDFFormat.TURTLE)
)
);
}));
}

/**
* Creates an entity and adds it to the store.
*
Expand All @@ -238,14 +289,14 @@ private void handleCreateWorkspace(
final Message<RdfStoreMessage> message
) throws IllegalArgumentException, IOException {
// Create IRI for new entity
final var entityIriString =
final var workspaceIri =
this.generateEntityIri(requestIri.toString(), content.workspaceName());
final var entityIri = RdfModelUtils.createIri(entityIriString);
final var entityIri = RdfModelUtils.createIri(workspaceIri);
Optional
.ofNullable(content.workspaceRepresentation())
.filter(s -> !s.isEmpty())
// Replace all null relative IRIs with the IRI generated for this entity
.map(s -> s.replaceAll("<>", "<" + entityIriString + ">"))
.map(s -> s.replaceAll("<>", "<" + workspaceIri + ">"))
.ifPresentOrElse(
Failable.asConsumer(s -> {
final var entityModel = RdfModelUtils.stringToModel(s, entityIri, RDFFormat.TURTLE);
Expand All @@ -258,7 +309,7 @@ private void handleCreateWorkspace(
);
entityModel.add(
parentIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store
Expand All @@ -271,7 +322,7 @@ private void handleCreateWorkspace(
);
parentModel.add(
entityIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store.replaceEntityModel(parentIri, parentModel);
Expand All @@ -283,7 +334,6 @@ private void handleCreateWorkspace(
);
}));
} else {
final var workspaceIri = entityIri.toString();
final var platformIri = RdfModelUtils.createIri(
workspaceIri.substring(0, workspaceIri.indexOf("workspaces"))
);
Expand All @@ -294,7 +344,7 @@ private void handleCreateWorkspace(
);
entityModel.add(
platformIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri("https://purl.org/hmas/core/HypermediaMASPlatform")
);
this.store
Expand All @@ -307,7 +357,7 @@ private void handleCreateWorkspace(
);
platformModel.add(
entityIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store.replaceEntityModel(platformIri, platformModel);
Expand Down Expand Up @@ -388,7 +438,7 @@ private void handleDeleteEntity(final IRI requestIri, final Message<RdfStoreMess
);
workspaceModel.remove(
requestIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri("https://purl.org/hmas/core/Artifact")
);
this.store.replaceEntityModel(workspaceIri, workspaceModel);
Expand Down Expand Up @@ -430,7 +480,7 @@ private void handleDeleteEntity(final IRI requestIri, final Message<RdfStoreMess
);
platformModel.remove(
requestIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store.replaceEntityModel(platformIri, platformModel);
Expand Down Expand Up @@ -464,7 +514,7 @@ private void handleDeleteEntity(final IRI requestIri, final Message<RdfStoreMess
);
parentModel.remove(
requestIri,
RdfModelUtils.createIri(RDF.TYPE.toString()),
RDF.TYPE,
RdfModelUtils.createIri(WORKSPACE_HMAS_IRI)
);
this.store.replaceEntityModel(parentIri, parentModel);
Expand Down
Loading

0 comments on commit fd55462

Please sign in to comment.