Skip to content

Commit

Permalink
KG query fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
fvilla committed Dec 4, 2024
1 parent 8d27f71 commit 192d12d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ enum Outcome {
*/
String getDescription();

/**
* Non-null for all activities that manipulate an observation, including those that failed.
*
* @return
*/
String getObservationUrn();

Outcome getOutcome();

String getStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class ActivityImpl extends ProvenanceNodeImpl implements Activity {
private KlabService.Type serviceType;
private String dataflow;
private String urn;
private String observationUrn;

@Override
public long getStart() {
Expand Down Expand Up @@ -94,6 +95,15 @@ public void setId(long id) {
this.id = id;
}

@Override
public String getObservationUrn() {
return this.observationUrn;
}

public void setObservationUrn(String observationUrn) {
this.observationUrn = observationUrn;
}

/**
* Non-API: the ID path through which the activity hierarchy can be reconstructed. When an activity is
* included in a message, the taskId gets in there.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.integratedmodelling.klab.api.digitaltwin.DigitalTwin;
import org.integratedmodelling.klab.api.geometry.Geometry;
import org.integratedmodelling.klab.api.knowledge.Observable;
import org.integratedmodelling.klab.api.knowledge.SemanticType;
import org.integratedmodelling.klab.api.knowledge.observation.Observation;
import org.integratedmodelling.klab.api.knowledge.observation.scale.Scale;
import org.integratedmodelling.klab.api.knowledge.observation.scale.space.Space;
Expand Down Expand Up @@ -183,6 +184,8 @@ private void compile(Actuator actuator) {
}
}

// TODO this should return a list of candidates, to match based on the parameters. For numeric there
// should be a float and double version.
var descriptor = componentRegistry.getFunctionDescriptor(call);
if (descriptor.serviceInfo.getGeometry().isScalar()) {

Expand All @@ -206,12 +209,19 @@ private void compile(Actuator actuator) {
}

var scale = Scale.create(observation.getGeometry());
Storage storage = digitalTwin.stateStorage().getOrCreateStorage(observation,
Storage.class);

// if we're a quality, we need storage at the discretion of the StorageManager.
Storage storage = observation.getObservable().is(SemanticType.QUALITY) ?
digitalTwin.stateStorage().getOrCreateStorage(observation,
Storage.class) :
null;
/*
* Create a runnable with matched parameters and have it set the context observation
* TODO allow multiple methods taking different storage implementations, enabling the
* storage manager to be configured for the wanted precision
* TODO allow multiple methods with same annotation, taking different storage
* implementations, enabling the storage manager to be configured for the wanted precision
*
* Should match arguments, check if they all match, and if not move to the next until
* no available implementations remain.
*/
List<Object> runArguments = new ArrayList<>();
if (descriptor.method != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ protected Map<String, Object> asParameters(Object asset, Object... additionalPar
ret.put("name", activity.getName());
ret.put("id", activity.getId());
ret.put("serviceId", activity.getServiceId());
ret.put("observationUrn", activity.getObservationUrn());
ret.put("serviceName", activity.getServiceName());
ret.put("serviceType", activity.getServiceType() == null ? null : activity.getServiceType().name());
ret.put("dataflow", activity.getDataflow());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ public void close() throws IOException {
for (var asset : assets) {
if (asset instanceof ObservationImpl obs) {
observation = obs;
activity.setObservationUrn(obs.getUrn());
} else if (asset instanceof Throwable t) {
activity.setStackTrace(ExceptionUtils.getStackTrace(t));
}
Expand Down Expand Up @@ -542,6 +543,7 @@ protected <T> List<T> adapt(EagerResult query, Class<T> cls, Scope scope) {
// TODO
instance.setStart(node.get("start").asLong());
instance.setEnd(node.get("end").asLong());
instance.setObservationUrn(node.get("observationUrn").asString());
instance.setName(node.get("name").asString());
instance.setServiceName(node.get("serviceName").isNull() ? null :
node.get("serviceName").asString());
Expand Down Expand Up @@ -761,6 +763,7 @@ protected void link(Transaction transaction, RuntimeAsset source, RuntimeAsset d
}

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;
Expand Down Expand Up @@ -994,30 +997,54 @@ public <T extends RuntimeAsset> List<T> get(ContextScope scope, Class<T> resultC
private List<Activity> getActivity(ContextScope scope, Object... queriables) {

Map<String, Object> queryParameters = new LinkedHashMap<>();
var query = new StringBuilder(getScopeQuery(scope, queryParameters) + "-[:HAS_PROVENANCE]->" +
"(:Provenance)-[:HAS_CHILD]->");

Activity rootActivity = null;
if (queriables != null) {
for (var parameter : queriables) {
if (parameter instanceof Observable observable) {
//
} else if (parameter instanceof Activity rootActivity) {
if (parameter instanceof Activity root) {
rootActivity = root;
} else if (parameter instanceof Long id) {
queryParameters.put("id", id);
query = new StringBuilder("MATCH (a:Activity {id: $id}");
} else if (parameter instanceof Observation observation) {
// define start node as the one with the observation URN
queryParameters.put("observationUrn", observation.getUrn());
} else if (parameter instanceof Activity.Type activityType) {
queryParameters.put("name", activityType.name());
query.append("(a:Activity {name: $name}");
queryParameters.put("type", activityType.name());
}
}
}

var result = query(query.append(") return a").toString(), queryParameters, scope);
var query = assetQuery("a", "Activity", queryParameters.keySet());
if (rootActivity != null) {
query.append("<-[*]-(r:Activity {id: $rootActivityId})");
queryParameters.put("rootActivityId", rootActivity.getId());
} else {
query.append("<-[*]-(p:Provenance {id: $provenanceId})");
queryParameters.put("provenanceId", scope.getId()+".PROVENANCE");
}

var result = query(query.append(" return a").toString(), queryParameters, scope);
return adapt(result, Activity.class, scope);
}

private StringBuilder assetQuery(String variableName, String assetLabel, Collection<String> keys) {

var ret = new StringBuilder("MATCH (").append(variableName).append(":").append(assetLabel);

if (keys.isEmpty()) {
ret.append(")");
} else {
int n = 0;
for (String key : keys) {
ret.append(n == 0 ? " {" : ", ");
ret.append(key).append(": $").append(key);
n++;
}
ret.append("})");
}

return ret;
}

private List<Agent> getAgent(ContextScope scope, Object... queriables) {

Map<String, Object> queryParameters = new LinkedHashMap<>();
Expand Down

0 comments on commit 192d12d

Please sign in to comment.