From 59f09b0eeb95f53edef5ba78bf4a696e9df9fe0d Mon Sep 17 00:00:00 2001 From: Ferdinando Villa Date: Sun, 24 Nov 2024 15:04:59 +0100 Subject: [PATCH] Dataflow stored more or less OK --- .../klab/api/digitaltwin/DigitalTwin.java | 4 +- .../common/runtime/ActuatorImpl.java | 32 ++-- .../services/resolver/ResolverService.java | 28 +--- .../services/runtime/ExecutionSequence.java | 136 +++++++++++++--- .../klab/services/runtime/RuntimeService.java | 138 +++-------------- .../runtime/neo4j/KnowledgeGraphNeo4j.java | 145 ++++-------------- 6 files changed, 193 insertions(+), 290 deletions(-) diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/digitaltwin/DigitalTwin.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/digitaltwin/DigitalTwin.java index d49881d78..17b0f1911 100644 --- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/digitaltwin/DigitalTwin.java +++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/digitaltwin/DigitalTwin.java @@ -37,14 +37,14 @@ enum Relationship { EMERGED_FROM, HAS_OBSERVER, HAS_PLAN, - RESOLVED_BY, BY_AGENT, CREATED, HAS_DATAFLOW, HAS_PROVENANCE, HAS_ACTIVITY, HAS_CHILD, - TRIGGERED; + TRIGGERED, + CONTEXTUALIZED; } /** diff --git a/klab.core.common/src/main/java/org/integratedmodelling/common/runtime/ActuatorImpl.java b/klab.core.common/src/main/java/org/integratedmodelling/common/runtime/ActuatorImpl.java index 175f15d4e..a5dedde99 100644 --- a/klab.core.common/src/main/java/org/integratedmodelling/common/runtime/ActuatorImpl.java +++ b/klab.core.common/src/main/java/org/integratedmodelling/common/runtime/ActuatorImpl.java @@ -29,8 +29,8 @@ public class ActuatorImpl implements Actuator { private Actuator.Type actuatorType; private long internalId; // ID within the graph, can't be the same as the observation private double resolvedCoverage; - - private transient KnowledgeGraph.Operation operation; +// +// private transient KnowledgeGraph.Operation operation; @Override public long getId() { @@ -137,20 +137,20 @@ public void setResolvedCoverage(double resolvedCoverage) { public void setInternalId(long internalId) { this.internalId = internalId; } - - /** - * Non-API: the actuator carries the activity it represents, which it transfers to the scope of execution - * so that provenance can be reconstructed. - * - * @return - */ - public KnowledgeGraph.Operation getOperation() { - return operation; - } - - public void setOperation(KnowledgeGraph.Operation operation) { - this.operation = operation; - } +// +// /** +// * Non-API: the actuator carries the activity it represents, which it transfers to the scope of execution +// * so that provenance can be reconstructed. +// * +// * @return +// */ +// public KnowledgeGraph.Operation getOperation() { +// return operation; +// } +// +// public void setOperation(KnowledgeGraph.Operation operation) { +// this.operation = operation; +// } @Override public String toString() { diff --git a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java index b0f996378..5d7be8aac 100644 --- a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java +++ b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java @@ -47,34 +47,17 @@ public class ResolverService extends BaseService implements Resolver { */ private static double MINIMUM_WORTHWHILE_CONTRIBUTION = 0.15; - /* - * The knowledge repository. Models and instances are built and kept in the resolver upon input - * from the resource services. For now we keep everything in memory. - * - * FIXME the URNs should include the version number after @ to ensure version matching instead - * of only storing the latest version - * - * Version of the latest loaded object is kept for everything, including namespaces - */ - // Map urnToVersion = Collections.synchronizedMap(new HashMap<>()); - // Map models = Collections.synchronizedMap(new HashMap<>()); - // Map instances = Collections.synchronizedMap(new HashMap<>()); - // Parameters defines = Parameters.createSynchronized(); - private String hardwareSignature = Utils.Names.getHardwareId(); + private final String hardwareSignature = Utils.Names.getHardwareId(); private ResolverConfiguration configuration; - - // OBVIOUSLY temporary - when all done, merge its methods with this and remove the porker and the old - // dirt. - private ResolutionCompiler resolutionCompiler = new ResolutionCompiler(); + private final ResolutionCompiler resolutionCompiler = new ResolutionCompiler(); public ResolverService(AbstractServiceDelegatingScope scope, ServiceStartupOptions options) { super(scope, Type.RESOLVER, options); // setProvideScopesAutomatically(true); ServiceConfiguration.INSTANCE.setMainService(this); readConfiguration(options); - KnowledgeRepository.INSTANCE.setProcessor(KlabAsset.KnowledgeClass.NAMESPACE, (ns) -> { - return loadNamespace((KimNamespace) ns, scope); - }); + KnowledgeRepository.INSTANCE.setProcessor(KlabAsset.KnowledgeClass.NAMESPACE, + (ns) -> loadNamespace((KimNamespace) ns, scope)); } private void readConfiguration(ServiceStartupOptions options) { @@ -172,7 +155,8 @@ private Model loadModel(KimModel statement, Scope scope) { // TODO any literal value must be added first for (var resourceUrn : statement.getResourceUrns()) { - // FIXME this should be one multi-resource contextualizable + // FIXME when >1 this should be one multi-resource contextualizable + // TODO use static builders instead of polymorphic constructors model.getComputation().add(new ContextualizableImpl(resourceUrn)); } model.getComputation().addAll(statement.getContextualization()); diff --git a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/ExecutionSequence.java b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/ExecutionSequence.java index 251da3cc6..14bfbfaa1 100644 --- a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/ExecutionSequence.java +++ b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/ExecutionSequence.java @@ -1,6 +1,8 @@ package org.integratedmodelling.klab.services.runtime; +import com.google.common.collect.ImmutableList; import org.integratedmodelling.common.runtime.ActuatorImpl; +import org.integratedmodelling.common.runtime.DataflowImpl; import org.integratedmodelling.klab.api.Klab; import org.integratedmodelling.klab.api.collections.Pair; import org.integratedmodelling.klab.api.collections.Parameters; @@ -14,11 +16,13 @@ import org.integratedmodelling.klab.api.knowledge.observation.scale.space.Space; import org.integratedmodelling.klab.api.knowledge.observation.scale.time.Time; import org.integratedmodelling.klab.api.lang.ServiceCall; +import org.integratedmodelling.klab.api.provenance.Activity; import org.integratedmodelling.klab.api.scope.ContextScope; import org.integratedmodelling.klab.api.scope.Scope; import org.integratedmodelling.klab.api.services.Language; import org.integratedmodelling.klab.api.services.RuntimeService; import org.integratedmodelling.klab.api.services.runtime.Actuator; +import org.integratedmodelling.klab.api.services.runtime.Dataflow; import org.integratedmodelling.klab.components.ComponentRegistry; import org.integratedmodelling.klab.configuration.ServiceConfiguration; import org.integratedmodelling.klab.runtime.storage.BooleanStorage; @@ -26,10 +30,13 @@ import org.integratedmodelling.klab.runtime.storage.FloatStorage; import org.integratedmodelling.klab.runtime.storage.KeyedStorage; import org.integratedmodelling.klab.services.scopes.ServiceContextScope; +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultDirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.traverse.TopologicalOrderIterator; import org.ojalgo.concurrent.Parallelism; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -43,9 +50,10 @@ public class ExecutionSequence { private final ServiceContextScope scope; private final DigitalTwin digitalTwin; - private final Language languageService; private final ComponentRegistry componentRegistry; private final double resolvedCoverage; + private final KnowledgeGraph.Operation contextualization; + private final Dataflow dataflow; private List> sequence = new ArrayList<>(); private boolean empty; // the context for the next operation. Starts at the observation and doesn't normally change but @@ -53,16 +61,22 @@ public class ExecutionSequence { // may change it when they return a non-null, non-POD object. // TODO check if this should be a RuntimeAsset or even an Observation. private Object currentExecutionContext; + private Map operations = new HashMap<>(); - private ExecutionSequence(List> pairs, double resolvedCoverage, - ServiceContextScope contextScope, - DigitalTwin digitalTwin, ComponentRegistry componentRegistry) { - + public ExecutionSequence(KnowledgeGraph.Operation contextualization, Dataflow dataflow, + ComponentRegistry componentRegistry, ServiceContextScope contextScope) { this.scope = contextScope; - this.digitalTwin = digitalTwin; - this.languageService = ServiceConfiguration.INSTANCE.getService(Language.class); + this.contextualization = contextualization; + this.resolvedCoverage = dataflow instanceof DataflowImpl dataflow1 ? + dataflow1.getResolvedCoverage() : 1.0; this.componentRegistry = componentRegistry; - this.resolvedCoverage = resolvedCoverage; + this.dataflow = dataflow; + this.digitalTwin = contextScope.getDigitalTwin(); + } + + public boolean compile(Actuator rootActuator) { + + var pairs = sortComputation(rootActuator); List current = null; int currentGroup = -1; for (var pair : pairs) { @@ -78,15 +92,10 @@ private ExecutionSequence(List> pairs, double resolvedCo if (current != null) { sequence.add(current); + return true; } - } - - public static ExecutionSequence compile(List> pairs, - double resolvedCoverage, ServiceContextScope contextScope, - DigitalTwin digitalTwin, - ComponentRegistry componentRegistry) { - return new ExecutionSequence(pairs, resolvedCoverage, contextScope, digitalTwin, componentRegistry); + return false; } public boolean run() { @@ -142,11 +151,7 @@ class ExecutorOperation { public ExecutorOperation(Actuator actuator) { this.id = actuator.getId(); - if (actuator instanceof ActuatorImpl actuator1) { - this.operation = actuator1.getOperation(); - // remove to avoid leaks after using the actuator as a shuttle - actuator1.setOperation(null); - } + this.operation = operations.get(actuator); this.observation = scope.getObservation(this.id); compile(actuator); } @@ -345,4 +350,91 @@ public ExecutionSequence runActuator(Actuator actuator) { return this; } + + /** + * Establish the order of execution and the possible parallelism. Each root actuator should be sorted by + * dependency and appended in order to the result list along with its order of execution. Successive roots + * can refer to the previous roots but they must be executed sequentially. + *

+ * The DigitalTwin is asked to register the actuator in the scope and prepare the environment and state + * for its execution, including defining its contextualization scale in context. + * + * @return + */ + private List> sortComputation(Actuator rootActuator) { + List> ret = new ArrayList<>(); + int executionOrder = 0; + Map branch = new HashMap<>(); + Set group = new HashSet<>(); + var dependencyGraph = computeActuatorOrder(rootActuator); + for (var nextActuator : ImmutableList.copyOf(new TopologicalOrderIterator<>(dependencyGraph))) { + if (nextActuator.getActuatorType() != Actuator.Type.REFERENCE) { + ret.add(Pair.of(nextActuator, (executionOrder = checkExecutionOrder + (executionOrder, nextActuator, dependencyGraph, group)))); + } + } + return ret; + } + + /** + * If the actuator depends on any in the currentGroup, empty the group and increment the order; otherwise, + * add it to the group and return the same order. + * + * @param executionOrder + * @param current + * @param dependencyGraph + * @param currentGroup + * @return + */ + private int checkExecutionOrder(int executionOrder, Actuator current, + Graph dependencyGraph, + Set currentGroup) { + boolean dependency = false; + for (Actuator previous : currentGroup) { + for (var edge : dependencyGraph.incomingEdgesOf(current)) { + if (currentGroup.contains(dependencyGraph.getEdgeSource(edge))) { + dependency = true; + break; + } + } + } + + if (dependency) { + currentGroup.clear(); + return executionOrder + 1; + } + + currentGroup.add(current); + + return executionOrder; + } + + + private Graph computeActuatorOrder(Actuator rootActuator) { + Graph dependencyGraph = new DefaultDirectedGraph<>(DefaultEdge.class); + Map cache = new HashMap<>(); + loadGraph(rootActuator, dependencyGraph, cache, this.contextualization); + // keep the actuators that do nothing so we can tag their observation as resolved + return dependencyGraph; + } + + + private void loadGraph(Actuator rootActuator, Graph dependencyGraph, Map cache, KnowledgeGraph.Operation contextualization) { + + var childContextualization = contextualization.createChild(rootActuator, + "Contextualization of " + rootActuator, Activity.Type.CONTEXTUALIZATION); + operations.put(rootActuator, childContextualization); + + cache.put(rootActuator.getId(), rootActuator); + dependencyGraph.addVertex(rootActuator); + for (Actuator child : rootActuator.getChildren()) { + if (child.getActuatorType() == Actuator.Type.REFERENCE) { + dependencyGraph.addEdge(cache.get(child.getId()), rootActuator); + } else { + loadGraph(child, dependencyGraph, cache, childContextualization); + dependencyGraph.addEdge(child, rootActuator); + } + } + } } diff --git a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java index bde18b8f9..aa18adc9a 100644 --- a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java +++ b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java @@ -13,6 +13,7 @@ import org.integratedmodelling.klab.api.exceptions.KlabIllegalArgumentException; import org.integratedmodelling.klab.api.exceptions.KlabIllegalStateException; import org.integratedmodelling.klab.api.exceptions.KlabInternalErrorException; +import org.integratedmodelling.klab.api.exceptions.KlabResourceAccessException; import org.integratedmodelling.klab.api.knowledge.observation.Observation; import org.integratedmodelling.klab.api.knowledge.observation.impl.ObservationImpl; import org.integratedmodelling.klab.api.lang.Contextualizable; @@ -385,9 +386,10 @@ This will commit or rollback at close() "Resolution of observation _" + observation.getUrn() + "_ of **" + observation.getObservable().getUrn() + "**"); scope.send(Message.MessageClass.ObservationLifecycle, Message.MessageType.ResolutionSuccessful, result); + resolutionActivity = resolution.getActivity(); } else { resolution.fail(scope, observation); - ret.completeExceptionally(null /* TODO */); + ret.completeExceptionally(new KlabResourceAccessException("Resolution of " + observation.getUrn() + " failed")); } } catch (Throwable t) { ret.completeExceptionally(t); @@ -401,7 +403,7 @@ This will commit or rollback at close() ret.completeExceptionally(t); } - if (!dataflow.isEmpty()) { + if (!ret.isCompletedExceptionally() && dataflow != null && !dataflow.isEmpty()) { /* this will commit all resources at close() @@ -439,8 +441,6 @@ public Observation runDataflow(Dataflow dataflow, ContextScope cont public Observation runDataflow(Dataflow dataflow, ContextScope contextScope, KnowledgeGraph.Operation contextualization) { - var digitalTwin = getDigitalTwin(contextScope); - /* Load or confirm availability of all needed resources and create any non-existing observations */ @@ -450,33 +450,35 @@ public Observation runDataflow(Dataflow dataflow, ContextScope cont find contextualization scale and hook point into the DT from the scope */ - /** - * Run each actuator set in order - */ - for (var rootActuator : dataflow.getComputation()) { - ExecutionSequence executionSequence = ExecutionSequence.compile(sortComputation(rootActuator, - dataflow, - contextScope, contextualization), (dataflow instanceof DataflowImpl dataflow1 ? - dataflow1.getResolvedCoverage() : 1.0), - (ServiceContextScope) contextScope, digitalTwin, getComponentRegistry()); - if (!executionSequence.isEmpty()) { - if (!executionSequence.run()) { - contextualization.fail(contextScope, dataflow.getTarget()); - return Observation.empty(); + + if (contextScope instanceof ServiceContextScope serviceContextScope) { + /** + * Run each actuator set in order + */ + for (var rootActuator : dataflow.getComputation()) { + var executionSequence = new ExecutionSequence(contextualization, dataflow, + getComponentRegistry(), serviceContextScope); + executionSequence.compile(rootActuator); + if (!executionSequence.isEmpty()) { + if (!executionSequence.run()) { + contextualization.fail(contextScope, dataflow.getTarget()); + return Observation.empty(); + } } } - } /* intersect coverage from dataflow with contextualization scale */ - if (dataflow instanceof DataflowImpl df && dataflow.getTarget() instanceof ObservationImpl obs) { - obs.setResolved(true); - obs.setResolvedCoverage(df.getResolvedCoverage()); - } + if (dataflow instanceof DataflowImpl df && dataflow.getTarget() instanceof ObservationImpl obs) { + obs.setResolved(true); + obs.setResolvedCoverage(df.getResolvedCoverage()); + } + + contextualization.success(contextScope, dataflow.getTarget(), dataflow); - contextualization.success(contextScope, dataflow.getTarget(), dataflow); + } return dataflow.getTarget(); } @@ -489,33 +491,6 @@ private DigitalTwin getDigitalTwin(ContextScope contextScope) { "implementation"); } - private Graph computeActuatorOrder(Actuator rootActuator, ContextScope scope, - KnowledgeGraph.Operation contextualization) { - Graph dependencyGraph = new DefaultDirectedGraph<>(DefaultEdge.class); - Map cache = new HashMap<>(); - loadGraph(rootActuator, dependencyGraph, cache, contextualization); - // keep the actuators that do nothing so we can tag their observation as resolved - return dependencyGraph; - } - - private void loadGraph(Actuator rootActuator, Graph dependencyGraph, Map cache, KnowledgeGraph.Operation contextualization) { - - var childContextualization = contextualization.createChild(rootActuator, - "Contextualization of " + rootActuator); - - cache.put(rootActuator.getId(), rootActuator); - dependencyGraph.addVertex(rootActuator); - for (Actuator child : rootActuator.getChildren()) { - if (child.getActuatorType() == Actuator.Type.REFERENCE) { - dependencyGraph.addEdge(cache.get(child.getId()), rootActuator); - } else { - loadGraph(child, dependencyGraph, cache, childContextualization); - dependencyGraph.addEdge(child, rootActuator); - } - } - } - @Override public List retrieveAssets(ContextScope contextScope, Class assetClass, Object... queryParameters) { @@ -569,67 +544,4 @@ public List getSessionInfo(Scope scope) { return knowledgeGraph.getSessionInfo(scope); } - /** - * Establish the order of execution and the possible parallelism. Each root actuator should be sorted by - * dependency and appended in order to the result list along with its order of execution. Successive roots - * can refer to the previous roots but they must be executed sequentially. - *

- * The DigitalTwin is asked to register the actuator in the scope and prepare the environment and state - * for its execution, including defining its contextualization scale in context. - * - * @param dataflow - * @return - */ - private List> sortComputation(Actuator rootActuator, - Dataflow dataflow, - ContextScope scope, - KnowledgeGraph.Operation contextualization) { - List> ret = new ArrayList<>(); - int executionOrder = 0; - Map branch = new HashMap<>(); - Set group = new HashSet<>(); - var dependencyGraph = computeActuatorOrder(rootActuator, scope, contextualization); - for (var nextActuator : ImmutableList.copyOf(new TopologicalOrderIterator<>(dependencyGraph))) { - if (nextActuator.getActuatorType() != Actuator.Type.REFERENCE) { - ret.add(Pair.of(nextActuator, (executionOrder = checkExecutionOrder - (executionOrder, nextActuator, - dependencyGraph, group)))); - } - } - return ret; - } - - /** - * If the actuator depends on any in the currentGroup, empty the group and increment the order; otherwise, - * add it to the group and return the same order. - * - * @param executionOrder - * @param current - * @param dependencyGraph - * @param currentGroup - * @return - */ - private int checkExecutionOrder(int executionOrder, Actuator current, - Graph dependencyGraph, - Set currentGroup) { - boolean dependency = false; - for (Actuator previous : currentGroup) { - for (var edge : dependencyGraph.incomingEdgesOf(current)) { - if (currentGroup.contains(dependencyGraph.getEdgeSource(edge))) { - dependency = true; - break; - } - } - } - - if (dependency) { - currentGroup.clear(); - return executionOrder + 1; - } - - currentGroup.add(current); - - return executionOrder; - } - } diff --git a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/neo4j/KnowledgeGraphNeo4j.java b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/neo4j/KnowledgeGraphNeo4j.java index 60c93ec8e..09a2e1084 100644 --- a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/neo4j/KnowledgeGraphNeo4j.java +++ b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/neo4j/KnowledgeGraphNeo4j.java @@ -101,6 +101,7 @@ public class OperationImpl implements Operation { private Throwable exception; private Object[] assets; private OperationImpl parent; + private List children = new ArrayList<>(); private Actuator actuator; @Override @@ -135,16 +136,18 @@ public Operation createChild(Object... activityData) { ret.agent = agent; } else if (o instanceof ActuatorImpl actuator) { ret.actuator = actuator; - actuator.setOperation(ret); } } } store(activity); - link(this.activity, ret.activity, DigitalTwin.Relationship.TRIGGERED); + link(this.activity, activity, DigitalTwin.Relationship.TRIGGERED); + link(activity, agent, DigitalTwin.Relationship.BY_AGENT); ret.activity = activity; + this.children.add(ret); + return ret; } @@ -192,6 +195,10 @@ public Operation fail(ContextScope scope, Object... assets) { @Override public void close() throws IOException { + for (var child : children) { + child.close(); + } + this.activity.setEnd(System.currentTimeMillis()); this.activity.setOutcome(outcome == null ? Activity.Outcome.INTERNAL_FAILURE : (outcome == Scope.Status.FINISHED ? Activity.Outcome.SUCCESS : @@ -202,6 +209,20 @@ public void close() throws IOException { ObservationImpl observation = null; double coverage = 1.0; + if (assets != null) { + for (var asset : assets) { + if (asset instanceof ObservationImpl obs) { + observation = obs; + } else if (asset instanceof Double d) { + coverage = d; + } + } + } + + if (this.actuator != null) { + store(actuator); + link(this.activity, this.actuator, DigitalTwin.Relationship.HAS_PLAN); + } if (parent == null) { @@ -209,30 +230,18 @@ public void close() throws IOException { // Log an internal failure (no success or failure, should not happen) transaction.rollback(); } else if (outcome == Scope.Status.FINISHED) { - transaction.commit(); - - if (assets != null) { - for (var asset : assets) { - if (asset instanceof ObservationImpl obs) { - observation = obs; - } else if (asset instanceof Double d) { - coverage = d; - } - } + if (observation != null) { + // TODO add state and histogram + link(this.activity, observation, DigitalTwin.Relationship.CONTEXTUALIZED); } - + transaction.commit(); } else if (outcome == Scope.Status.ABORTED) { transaction.rollback(); } } - if (this.actuator != null) { - store(actuator); - link(this.activity, this.actuator, DigitalTwin.Relationship.HAS_PLAN); - } - - if (observation != null) { - if (activity.getType() == Activity.Type.RESOLUTION) { + if (observation != null && outcome == Scope.Status.FINISHED) { + if (this.activity.getType() == Activity.Type.CONTEXTUALIZATION) { observation.setResolved(true); observation.setResolvedCoverage(coverage); } @@ -358,43 +367,10 @@ protected void initializeContext() { } - // /* - // establish IDs for the main nodes and create the respective RuntimeAssets - // */ - // final var contextNodeId = getInternalId("MATCH (n:Context {id: $contextId}) return n.id", - // Map.of( - // "contextId", scope.getId()), scope); - // final var dataflowNodeId = getInternalId("MATCH (n:Dataflow {id: $contextId}) return n - // .id", Map.of( - // "contextId", scope.getId() + ".DATAFLOW"), scope); - // final var provenanceNodeId = getInternalId("MATCH (n:Provenance {id: $contextId}) return - // id(n)", - // Map.of( - // "contextId", scope.getId() + ".PROVENANCE"), scope); - // - // if (contextNodeId == Observation.UNASSIGNED_ID || provenanceNodeId == Observation - // .UNASSIGNED_ID || dataflowNodeId == Observation.UNASSIGNED_ID) { - // throw new KlabInternalErrorException("knowledge graph: contextual nodes are not - // present"); - // } - final var dataflowNodeId = nextKey(); final var provenanceNodeId = nextKey(); final var contextNodeId = nextKey(); - // this.contextNode = new RuntimeAsset() { - // @Override - // public long getId() { - // return contextNodeId; - // } - // - // @Override - // public Type classify() { - // // check - scope isn't a runtime asset - // return Type.ARTIFACT; - // } - // }; - this.dataflowNode = new RuntimeAsset() { @Override public long getId() { @@ -450,22 +426,6 @@ public void deleteContext() { query(Queries.REMOVE_CONTEXT, Map.of("contextId", scope.getId()), scope); } - // /** - // * Return the internal long ID corresponding to the single result of a query - // * - // * @param query - // * @param parameters - // * @param scope - // * @return - // */ - // protected Object getId(String query, Map parameters, Scope scope) { - // var result = query(query, parameters, scope); - // if (result != null && result.records().size() == 1) { - // return result.records().getFirst().get(result.keys().getFirst()).asLong(); - // } - // return Observation.UNASSIGNED_ID; - // } - /** * @param query * @param cls @@ -741,7 +701,7 @@ private String matchAsset(RuntimeAsset asset, String name, String queryVariable) var ret = switch (asset) { case Activity activity -> name + ".id = $" + queryVariable; case Observation observation -> name + ".id = $" + queryVariable; - case Actuator actuator -> name + ".internalId = $" + queryVariable; + case Actuator actuator -> name + ".id = $" + queryVariable; case Agent agent -> name + ".name = $" + queryVariable; default -> null; }; @@ -893,51 +853,6 @@ protected synchronized long nextKey() { return ret; } - // private void storeDataflow(Dataflow dataflow, ContextScope scope, Activity activity) { - // - // // /** - // // * Add the resolution activity with its end time - // // */ - // // store(activity, scope, "description", activityDescription, "end", System - // // .currentTimeMillis()); - // // link(getProvenanceNode(), activity, DigitalTwin.Relationship.HAS_CHILD, scope); - // // link(agent, activity, DigitalTwin.Relationship.BY_AGENT, scope); - // - // // rebuild the actuator structure; each actuator with the source code of its contextualizers - // // link the root actuators to this activity as plan with an order parameter in the link - // // link each actuator to the observation it contextualized - // for (var actuator : dataflow.getComputation()) { - // storeActuator(actuator, dataflow, scope, activity, null); - // } - // } - - private void storeActuator(Actuator actuator, Dataflow dataflow, ContextScope scope, - Activity activity, Actuator parent) { - - store(actuator, scope); - - var observation = retrieve(actuator.getId(), Observation.class, scope); - link(observation, activity, DigitalTwin.Relationship.RESOLVED_BY, scope); - - /* - TODO if parent == null, find the actual parent in case the actuator for the parent observation is - there. - */ - if (parent == null) { - link(getDataflowNode(), actuator, DigitalTwin.Relationship.HAS_CHILD, scope); - link(activity, actuator, DigitalTwin.Relationship.HAS_PLAN, scope, "resolvedObservable", - observation.getObservable().getUrn(), "resolvedObservation", observation.getUrn()); - } else { - link(parent, actuator, DigitalTwin.Relationship.HAS_CHILD, scope, "resolvedObservable", - observation.getObservable().getUrn(), "resolvedObservation", observation.getUrn()); - } - - for (var child : actuator.getChildren()) { - storeActuator(child, dataflow, scope, activity, actuator); - } - - } - @Override public List get(ContextScope scope, Class resultClass, Object... queriables) {