diff --git a/README.md b/README.md index 1907fb15a..280cb1901 100644 --- a/README.md +++ b/README.md @@ -258,4 +258,8 @@ By default, a Smart Connector waits `10` seconds max for a reply from another Sm *Increasing the HTTP timeouts* -By default, a KER waits `5` seconds max for a HTTP connection response from another KER when sending a message via the inter-KER protocol. The time is configurable via the `ke.http.timeout` property +By default, a KER waits `5` seconds max for a HTTP connection response from another KER when sending a message via the inter-KER protocol. The time is configurable via the `ke.http.timeout` property. + +*Configure the reasoner level* + +By default, the reasoner level is set to `2`, but can be overridden as described above. The reasoner level (1-5) determines how advanced the reasoner mechanism will be. Every Smart Connector within the Knowledge Engine Runtime will use the configured reasoning level unless specified otherwise. The level can be configured via the `ke.reasoner.level` property. \ No newline at end of file diff --git a/docs/docs/reasoning.md b/docs/docs/reasoning.md index 8afbcacc6..3a4427b79 100644 --- a/docs/docs/reasoning.md +++ b/docs/docs/reasoning.md @@ -12,8 +12,7 @@ We can distinguish between two types of reasoning as it happens within the knowl 1. reasoning to infer new data, and 2. reasoning for orchestration of data -It is optional to use the reasoner, and you have to specifically opt in to enable it. -If you don't opt in, the *matcher* is used, which simply only facilitates data exchange when graph patterns match exactly (except for order of triples and variable names). +The reasoner is always enabled, but you can configure the reasoner level with a number between 1 and 5, inclusive. The lower reasoner level facilitates data exchange when graph patterns match exactly (except for order of triples and variable names) and will not combine multiple actors to satisfy the interaction. ## Reasoning to infer new data @@ -184,32 +183,34 @@ In `examples/reasoner/` in the Knowledge Engine repository, you can find a compl That example is a variant on the unit conversion orchestration. -## Enabling the reasoner +## Setting the reasoner level + +You can configure the default reasoner level via the `ke.reasoner.level` configuration option. See [configuration](https://github.com/TNO/knowledge-engine?tab=readme-ov-file#configuration) section for more info. ```java -smartConnector.setReasonerEnabled(true); +smartConnector.setReasonerLevel(4); ``` -When using the REST API, you can enable the reasoner in your smart connector by adding the `reasonerEnabled` property during knowledge base registration: +When using the REST API, you can enable the reasoner in your smart connector by adding the `reasonerLevel` property during knowledge base registration: ```json { "knowledgeBaseId": "http://example.org/kb-with-reasoner-enabled", "knowledgeBaseName": "My reasonable knowledge base", "knowledgeBaseDescription": "This is an example knowledge base with the reasoner turned on.", - "reasonerEnabled": true + "reasonerLevel": 4 } ``` -When reasoning is enabled, any **proactive** Knowledge Interaction (i.e. ASK and POST) that you trigger in the smart connector will use the reasoner. +Any **proactive** Knowledge Interaction (i.e. ASK and POST) that you trigger in the smart connector will use the specified reasoner level. ## Performance warning diff --git a/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/MatchStrategy.java b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/MatchStrategy.java index 7a3c65f2b..33fc7f994 100644 --- a/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/MatchStrategy.java +++ b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/MatchStrategy.java @@ -12,7 +12,43 @@ * extremely slow and often throws out of memory exceptions. */ public enum MatchStrategy { - SUPREME_LEVEL, ULTRA_LEVEL, ADVANCED_LEVEL, NORMAL_LEVEL, ENTRY_LEVEL; + /** + * Fastest but finds least matches between rules. Matches cannot consist of + * multiple rules and should also fully cover the target graph pattern. + */ + ENTRY_LEVEL, + + /** + * Faster but finds only limited matches between rules. Matches can consist of + * multiple rules, but should still fully cover the target graph pattern which + * means detecting knowledge gaps is not supported. + */ + NORMAL_LEVEL, + + /** + * Slower but finds more matches between rules. Matches can consist of multiple + * rules and transitive rules (that refer to themselves) are supported as well, + * but matches should still fully cover the target graph pattern which means + * detecting knowledge gaps is not supported. + */ + ADVANCED_LEVEL, + + /** + * Even slower but finds almost all matches between rules. Matches can consist + * of multiple rules and transitive rules (that refer to themselves) are + * supported as well and matches do not need to fully cover the target graph + * pattern and this means knowledge gap detection is supported. + */ + ULTRA_LEVEL, + + /** + * Slowest, but finds all possible matches between rules. Matches can consist of + * multiple rules and transitive rules (that refer to themselves) are supported. + * Matches do not need to fully cover the target graph pattern and this means + * knowledge gap detection is supported. This level also finds matches that are + * already encompassed by other matches. + */ + SUPREME_LEVEL; public EnumSet toConfig(boolean antecedentOfTarget) { EnumSet config; diff --git a/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnector.java b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnector.java index 59428557d..3ec73335f 100644 --- a/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnector.java +++ b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnector.java @@ -271,20 +271,22 @@ CompletableFuture post(PostKnowledgeInteraction aPKI, RecipientSelec void setDomainKnowledge(Set someDomainKnowledge); /** - * Sets the reasoner enabled property of this Smart Connector to true or false. - * Enabling the reasoner causes the data exchange to become more flexible, but - * also causes the data exchange to be slower. + * Sets the default reasoner level of this Smart Connector between 1-5. + * Increasing the level of the reasoner causes the data exchange to become more + * flexible, but also causes the data exchange to be slower. * - * @param aReasonerEnabled {@code true} if the reasoner should be enabled, - * {@code false} otherwise. + * @param aReasonerLevel The default level of the reasoner. For details on the + * different reasoner levels, see + * {@link SmartConnectorConfig#CONF_KEY_KE_REASONER_LEVEL}. */ - void setReasonerEnabled(boolean aReasonerEnabled); + void setReasonerLevel(int aReasonerLevel); /** - * @return {@code true} if this smart connector uses the reasoner for data - * exchange, {@code false} otherwise. + * @return The default reasoner level of this smart connector for data exchange. + * For details on the different reasoner levels, see + * {@link SmartConnectorConfig#CONF_KEY_KE_REASONER_LEVEL} */ - boolean isReasonerEnabled(); + int getReasonerLevel(); /** * Stops the current {@link SmartConnector}. Note that this methods is diff --git a/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnectorConfig.java b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnectorConfig.java new file mode 100644 index 000000000..8abaffae7 --- /dev/null +++ b/smart-connector-api/src/main/java/eu/knowledge/engine/smartconnector/api/SmartConnectorConfig.java @@ -0,0 +1,117 @@ +package eu.knowledge.engine.smartconnector.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SmartConnectorConfig { + + /** + * The log facility of this class. + */ + public static final Logger LOG = LoggerFactory.getLogger(SmartConnectorConfig.class); + + /** + * Key to set whether this KER should strictly validate whether outgoing + * bindings are compatible with incoming bindings. + */ + public static final String CONF_KEY_VALIDATE_OUTGOING_BINDINGS_WRT_INCOMING_BINDINGS = "sc.validate.outgoing.bindings.wrt.incoming.bindings"; + + /** + * Key to configure the hostname of the machine this Knowledge Engine Runtime + * (KER) runs on. + * + * @deprecated Replaced by + * {@link SmartConnectorConfig#CONF_KEY_KE_RUNTIME_EXPOSED_URL} + */ + @Deprecated + public static final String CONF_KEY_KE_RUNTIME_HOSTNAME = "ke.runtime.hostname"; + + /** + * Key to configure the URL of the Knowledge Directory where this KER can find + * other KERs in the network. Note that overriding this configuration property + * will run this KER in distributed mode. + */ + public static final String CONF_KEY_KD_URL = "kd.url"; + + /** + * Key to configure the time in seconds the SCs in this KER wait for a HTTP + * connection response from another KER. Only used in distributed mode. + */ + public static final String CONF_KEY_KE_HTTP_TIMEOUT = "ke.http.timeout"; + + /** + * Key to configure the how many seconds the MessageRouter should wait for + * ANSWER/REACT Message when sending a ASK/POST Message? 0 means wait forever + * (useful when working with a human KB). + */ + public static final String CONF_KEY_KE_KB_WAIT_TIMEOUT = "ke.kb.wait.timeout"; + + /** + * Key to configure the URL that is advertised to other KERs. Other KERs can use + * this URL to reach this KER. Note that this configuration property is only + * used in distributed mode. + */ + public static final String CONF_KEY_KE_RUNTIME_EXPOSED_URL = "ke.runtime.exposed.url"; + + /** + * Key to configure the port at which the KER's peer-to-peer communication + * should happen. Only used in distributed mode. + */ + public static final String CONF_KEY_KE_RUNTIME_PORT = "ke.runtime.port"; + + /** + * Key to configure the default reasoner level (1-5) that is used in the current + * KER when no reasoner level is provided by the user. The meaning of each + * levels is: + *
    + *
  • 1: Fastest but least thorough level. Configures the matching + * algorithm to {@link MatchStrategy#ENTRY_LEVEL}.
  • + *
  • 2: Faster but not very thorough level. Configures the matching + * algorithm to {@link MatchStrategy#NORMAL_LEVEL}.
  • + *
  • 3: Slower but more thorough level. Configures the matching + * algorithm to {@link MatchStrategy#ADVANCED_LEVEL}.
  • + *
  • 4: Even slower but even more thorough level. Configures the + * matching algorithm to {@link MatchStrategy#ULTRA_LEVEL}.
  • + *
  • 5: Slowest but most thorough level. Configures the matching + * algorithm to {@link MatchStrategy#SUPREME_LEVEL}.
  • + *
+ */ + public static final String CONF_KEY_KE_REASONER_LEVEL = "ke.reasoner.level"; + + /** + * Convert the configuration reasoner levels to matching strategies used in the + * reasoner code. + * + * @param aReasonerLevel The reasoner level configured in a configuration file. + * @return The corresponding matching strategy belonging to the given reasoner + * level. + */ + public static MatchStrategy toMatchStrategy(int aReasonerLevel) { + MatchStrategy m = null; + + switch (aReasonerLevel) { + case 1: + m = MatchStrategy.ENTRY_LEVEL; + break; + case 2: + m = MatchStrategy.NORMAL_LEVEL; + break; + case 3: + m = MatchStrategy.ADVANCED_LEVEL; + break; + case 4: + m = MatchStrategy.ULTRA_LEVEL; + break; + case 5: + m = MatchStrategy.SUPREME_LEVEL; + break; + default: + LOG.warn( + "The configured reasoner level should lie between 1 and 5, inclusive and should not be '{}'. Falling back to reasoner level 1.", + aReasonerLevel); + m = MatchStrategy.ENTRY_LEVEL; + } + + return m; + } +} diff --git a/smart-connector-rest-dist/src/test/java/eu/knowledge/engine/rest/api/TestReasonerLevel.java b/smart-connector-rest-dist/src/test/java/eu/knowledge/engine/rest/api/TestReasonerLevel.java new file mode 100644 index 000000000..261e31402 --- /dev/null +++ b/smart-connector-rest-dist/src/test/java/eu/knowledge/engine/rest/api/TestReasonerLevel.java @@ -0,0 +1,63 @@ +package eu.knowledge.engine.rest.api; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import eu.knowledge.engine.rest.RestServerHelper; +import eu.knowledge.engine.test_utils.HttpTester; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class TestReasonerLevel { + private final RestServerHelper rsh = new RestServerHelper(); + private static int PORT = 8280; + + @BeforeAll + public void setUpServer() { + rsh.start(PORT); + } + + @Test + public void testReasonerLevel() throws IOException, InterruptedException { + + URL url = new URL("http://localhost:" + PORT + "/rest"); + + // register the AskKB with out of range reasoner level + var registerKb = new HttpTester(new URL(url + "/sc"), "POST", + "{\"knowledgeBaseId\": \"https://www.tno.nl/example/relationAsker\", \"knowledgeBaseName\": \"RelationAsker\", \"knowledgeBaseDescription\": \"A KB that asks for relations between people\", \"reasonerLevel\" : 0}", + Map.of("Content-Type", "application/json", "Accept", "*/*")); + registerKb.expectStatus(400); + + // register the AskKB with out of range reasoner level + registerKb = new HttpTester(new URL(url + "/sc"), "POST", + "{\"knowledgeBaseId\": \"https://www.tno.nl/example/relationAsker\", \"knowledgeBaseName\": \"RelationAsker\", \"knowledgeBaseDescription\": \"A KB that asks for relations between people\", \"reasonerLevel\" : 6}", + Map.of("Content-Type", "application/json", "Accept", "*/*")); + registerKb.expectStatus(400); + + // register the AskKB with correct reasoner level + registerKb = new HttpTester(new URL(url + "/sc"), "POST", + "{\"knowledgeBaseId\": \"https://www.tno.nl/example/relationAsker\", \"knowledgeBaseName\": \"RelationAsker\", \"knowledgeBaseDescription\": \"A KB that asks for relations between people\", \"reasonerLevel\" : 2}", + Map.of("Content-Type", "application/json", "Accept", "*/*")); + registerKb.expectStatus(200); + + // register the AskKB without reasoner level + var registerKb2 = new HttpTester(new URL(url + "/sc"), "POST", + "{\"knowledgeBaseId\": \"https://www.tno.nl/example/relationAsker2\", \"knowledgeBaseName\": \"RelationAsker\", \"knowledgeBaseDescription\": \"A KB that asks for relations between people\"}", + Map.of("Content-Type", "application/json", "Accept", "*/*")); + registerKb.expectStatus(200); + } + + @AfterAll + public void cleanUp() throws MalformedURLException { + + TestUtil.unregisterAllKBs("http://localhost:" + PORT + "/rest"); + rsh.cleanUp(); + } + +} diff --git a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBase.java b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBase.java index be97ce11f..4e01e78c6 100644 --- a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBase.java +++ b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBase.java @@ -251,8 +251,8 @@ protected boolean removeEldestEntry(Map.Entry eldest) { } this.sc = smartConnectorProvider.create(this); - if (scModel.getReasonerEnabled() != null) - this.sc.setReasonerEnabled(scModel.getReasonerEnabled()); + if (scModel.getReasonerLevel() != null) + this.sc.setReasonerLevel(scModel.getReasonerLevel()); } protected void tryProcessHandleRequestElseEnqueue(HandleRequest handleRequest) { @@ -396,10 +396,6 @@ public String register(KnowledgeInteractionBase ki) { } boolean knowledgeGapsEnabled = ki.getKnowledgeGapsEnabled() == null ? false : ki.getKnowledgeGapsEnabled(); - if (knowledgeGapsEnabled && !this.sc.isReasonerEnabled()) { - throw new IllegalArgumentException( - "You can only set knowledgeGapsEnabled when the Knowledge Base is reasonerEnabled."); - } String type = ki.getKnowledgeInteractionType(); URI kiId; @@ -414,6 +410,9 @@ public String register(KnowledgeInteractionBase ki) { MatchStrategy strategy = null; if (aki.getKnowledgeGapsEnabled() != null && aki.getKnowledgeGapsEnabled()) { strategy = MatchStrategy.SUPREME_LEVEL; + LOG.info( + "The MatchStrategy should be '{}' when Knowledge Gaps are enabled. Overriding default.", + MatchStrategy.SUPREME_LEVEL); } var askKI = new AskKnowledgeInteraction(ca, new GraphPattern(prefixMapping, aki.getGraphPattern()), @@ -512,8 +511,7 @@ public KnowledgeInteractionWithId getKnowledgeInteraction(String knowledgeIntera return kiToModelKiWithId(kiId, this.knowledgeInteractions.get(kiId)); } catch (URISyntaxException e) { - assert false - : "There should never occur an invalid URI here because it should have been checked in the service implementation."; + assert false : "There should never occur an invalid URI here because it should have been checked in the service implementation."; } return null; @@ -864,7 +862,7 @@ public boolean isSuspended() { return this.suspended; } - public Boolean getReasonerEnabled() { - return this.sc.isReasonerEnabled(); + public int getReasonerLevel() { + return this.sc.getReasonerLevel(); } } diff --git a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBaseManager.java b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBaseManager.java index b8bbf8a83..5b4f70065 100644 --- a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBaseManager.java +++ b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/RestKnowledgeBaseManager.java @@ -86,9 +86,9 @@ public CompletableFuture createKB(eu.knowledge.engine.rest.model.SmartConn this.restKnowledgeBases.put(scModel.getKnowledgeBaseId(), new RestKnowledgeBase(scModel, () -> { f.complete(null); })); + LOG.info("Added KB {}", scModel.getKnowledgeBaseId()); return f.handle((r, e) -> { - if (r == null && e != null) { LOG.error("An exception has occured while creating KB ", e); return null; diff --git a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/SmartConnectorLifeCycleApiServiceImpl.java b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/SmartConnectorLifeCycleApiServiceImpl.java index 8fcb8f3ae..4942c0b6a 100644 --- a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/SmartConnectorLifeCycleApiServiceImpl.java +++ b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/impl/SmartConnectorLifeCycleApiServiceImpl.java @@ -143,15 +143,23 @@ public void scPost(@Parameter(description = "", required = true) @NotNull @Valid return; } - final boolean reasonerEnabled = smartConnector.getReasonerEnabled() == null ? false - : smartConnector.getReasonerEnabled(); - - LOG.info("Creating smart connector with ID {} and reasoner enabled '{}'.", kbId, reasonerEnabled); - + Integer lvl = smartConnector.getReasonerLevel(); + + if (lvl != null && (lvl < 1 || lvl > 5)) { + var response = new ResponseMessage(); + response.setMessageType("error"); + response.setMessage("The reasoner level should be between 1 and 5, inclusive and not " + lvl); + asyncResponse.resume(Response.status(400).entity(response).build()); + return; + } + + LOG.info("Creating smart connector with ID {} and {}reasoner level{}.", kbId, lvl != null ? "" : "default ", + lvl != null ? " " + lvl : ""); + // Tell the manager to create a KB, store it, and have it set up a SC etc. this.manager.createKB(new SmartConnector().knowledgeBaseId(kbId.toString()).knowledgeBaseName(kbName) .knowledgeBaseDescription(kbDescription).leaseRenewalTime(smartConnector.getLeaseRenewalTime()) - .reasonerEnabled(reasonerEnabled)).thenRun(() -> { + .reasonerLevel(smartConnector.getReasonerLevel())).thenRun(() -> { LOG.info("Returning response for smart connector with ID {}", kbId); asyncResponse.resume(Response.ok().build()); }); @@ -220,7 +228,7 @@ private eu.knowledge.engine.rest.model.SmartConnector[] convertToModel(Set varMapping = new HashMap(); - - // convert graphs - GraphInfo from = new GraphInfo(fromVarNameGP); - GraphInfo to = new GraphInfo(toVarNameGP); - - TypedVF2IsomorphismTester tester = new TypedVF2IsomorphismTester(); - Map mapping = tester.findIsomorphism(from.getGraph(), to.getGraph()); - - if (!mapping.isEmpty()) { - - // store the mapping between variable node vertices. - for (Integer fromVertexIdx : from.getGraph().vertices()) { - - Node fromNode = from.getIntToNodeMap().get(fromVertexIdx); - Integer toVertexIdx = mapping.get(fromVertexIdx); - Node toNode = to.getIntToNodeMap().get(toVertexIdx); - - if (fromNode.isVariable() && toNode.isVariable()) { - varMapping.put(fromNode.getName(), toNode.getName()); - } - - LOG.trace("Node: {} - {}", fromNode, toNode); - } - - // now store the mapping between variable node edges. Look at JGraphTs - // implementation of the getEdgeCorrespondence method. - for (DirectedTypedEdge fromEdge : from.getGraph().edges()) { - - Integer fromEdgeSource = fromEdge.from(); - Integer fromEdgeTarget = fromEdge.to(); - Map fromIntToNodeMap = from.getIntToNodeMap(); - - if (fromEdge.edgeType().getNode().isVariable()) { - - Set fromEdgeNodes = getEdgeNodesBetween(fromVarNameGP, fromIntToNodeMap.get(fromEdgeSource), - fromIntToNodeMap.get(fromEdgeTarget)); - - LOG.trace("Found {} number of nodes for from edge {} ({}).", fromEdgeNodes.size(), fromEdgeNodes, - fromEdge); - - Node fromEdgeNode = null; - for (Node node : fromEdgeNodes) { - if (node.isVariable() && fromEdgeNode == null) { - - // check if the current candidate is not already mapped to another edge. - if (!varMapping.containsKey(node.getName())) { - fromEdgeNode = node; - } else { - LOG.trace("Predicate variable {} is already mapped, so we skip this one.", - node.getName()); - } - } - } - - Integer toEdgeSource = mapping.get(fromEdgeSource); - Integer toEdgeTarget = mapping.get(fromEdgeTarget); - - /* - * Unfortunately, S-Space keeps a *static* collection of edgetypes for - * performance reasons and this means we cannot retrieve the exact Node from the - * toGraph (because it was replaced by the same variable node of the from - * graph). So, how do we get to the edges between the two nodes? Probably using - * the Graph Patterns themselves. - */ -// Set> toEdgeSet = to.getGraph().getEdges(toEdgeSource, toEdgeTarget, -// edgeSet); - - Map toIntToNodeMap = to.getIntToNodeMap(); - Set toEdgeNodes = getEdgeNodesBetween(toVarNameGP, toIntToNodeMap.get(toEdgeSource), - toIntToNodeMap.get(toEdgeTarget)); - - LOG.trace("Found {} number of nodes for to edge {}.", toEdgeNodes.size(), toEdgeNodes); - - assert !toEdgeNodes.isEmpty() : "If the source " + fromEdgeSource + ", " + toEdgeSource - + " and target " + fromEdgeSource + ", " + toEdgeSource - + " of an edge are isomorph, the mapped source and target should have at least a single edge between them."; - - Node toEdge = null; - for (Node node : toEdgeNodes) { - if (node.isVariable() && toEdge == null) { - - // check if the current candidate is not already mapped to another edge. - if (!varMapping.containsValue(node.getName())) { - toEdge = node; - } else { - LOG.trace("Predicate variable {} is already mapped, so we skip this one.", - node.getName()); - } - } - } - - if (toEdge != null && fromEdgeNode != null) { - varMapping.put(fromEdgeNode.getName(), toEdge.getName()); - - LOG.trace("Edge: {} - {}", fromEdgeNode, toEdge); - } else { - assert false : "The two graph patterns " + fromVarNameGP + " and " + toVarNameGP - + " match, so the variable edge " + fromEdge - + " should be mappable to another variable edge."; - } - } - } - - LOG.trace("Isomorphism {} gave rise to variable mapping: {}", mapping, varMapping); - - } else { - LOG.trace("No isomorphisms found."); - } - - // now transform the from bindingset to the to bindingset using the variable - // mapping. - BindingSet toBindingSet = new BindingSet(); - - Binding toBinding; - for (Binding fromBinding : fromBindingSet) { - toBinding = new Binding(); - for (Map.Entry twoVars : varMapping.entrySet()) { - if (fromBinding.containsKey(twoVars.getKey())) { - toBinding.put(twoVars.getValue(), fromBinding.get(twoVars.getKey())); - } else { - // the binding could be partial, so not every mapped variable should be - // available in the binding. - } - } - toBindingSet.add(toBinding); - } - - LOG.trace("Transformed bindingset size {} into size {} or {} into {}.", fromBindingSet.size(), toBindingSet.size(), - fromBindingSet, toBindingSet); - - return toBindingSet; - - } - - private static Set getEdgeNodesBetween(GraphPattern gp, Node source, Node target) { - ElementPathBlock epb; - Set nodeSet = new HashSet<>(); - epb = gp.getGraphPattern(); - List triples = epb.getPattern().getList(); - for (TriplePath t : triples) { - - Node subject = t.getSubject(); - Node predicate = t.getPredicate(); - Node object = t.getObject(); - - if (subject.equals(source) && object.equals(target)) { - nodeSet.add(predicate); - } - - } - return nodeSet; - } - - private static class NodeEdge { - - private Node n; - - public NodeEdge(Node n) { - this.n = n; - } - - @Override - public boolean equals(Object obj) { - - NodeEdge otherN = (NodeEdge) obj; - - if ((otherN.n.isVariable() && this.n.isVariable())) { - return true; - } else { - return otherN.n.equals(this.n); - } - } - - @Override - public int hashCode() { - if (this.n.isVariable()) { - return 31; // TODO this is not good performance wise - } else { - return this.n.hashCode(); - } - } - - @Override - public String toString() { - if (this.n.isVariable()) { - - return n.getName(); - } else { - return this.n.toString(); - } - } - - public Node getNode() { - return n; - } - - } - - private static DirectedMultigraph convertToSSpace(ElementPathBlock epb) { - - DirectedMultigraph g = new DirectedMultigraph<>(); - - Map intToNodeMap = new HashMap<>(); - Map nodeToIntMap = new HashMap<>(); - - List triples = epb.getPattern().getList(); - - int vertexCounter = 1; - int missedEdges = 0; - - for (TriplePath t : triples) { - - Node subject = t.getSubject(); - Node predicate = t.getPredicate(); - Node object = t.getObject(); - - boolean success; - if (!intToNodeMap.containsValue(subject)) { - intToNodeMap.put(vertexCounter, subject); - nodeToIntMap.put(subject, vertexCounter); - success = g.add(vertexCounter); - } - - vertexCounter++; - if (!intToNodeMap.containsValue(object)) { - intToNodeMap.put(vertexCounter, object); - nodeToIntMap.put(object, vertexCounter); - success = g.add(vertexCounter); - } - - SimpleDirectedTypedEdge e = new SimpleDirectedTypedEdge(new NodeEdge(predicate), - nodeToIntMap.get(subject), nodeToIntMap.get(object)); - - success = g.add(e); - - if (!success) { - missedEdges += 1; - LOG.debug("Adding edge with type {} between {} and {} to the graph should succeed.", e, subject, object); - } - - - vertexCounter++; - } - - if (missedEdges > 0) { - LOG.warn("Could not add all edges. Are there duplicate edges in the graph?"); - LOG.debug("Missing edge: {}", missedEdges); - } - - return g; - } - - public static Map getIsomorphisms(GraphPattern gp1, GraphPattern gp2) throws ParseException { - - GraphInfo g1 = new GraphInfo(gp1); - GraphInfo g2 = new GraphInfo(gp2); - LOG.trace("are isomorph? g1: {}, g2: {}", g1, g2); - - // first retrieve the isomorphisms - TypedVF2IsomorphismTester tester = new TypedVF2IsomorphismTester(); - Map mapping = tester.findIsomorphism(g1.getGraph(), g2.getGraph()); - - // because nodes are translated into integers, the algorithm cannot distinguish - // between different concrete nodes. This means that every concrete node is - // similar to any other concrete node, but this is of course not the case. - for (Map.Entry entry : mapping.entrySet()) { - - var g1map = g1.getIntToNodeMap(); - var g2map = g2.getIntToNodeMap(); - - Node n1 = g1map.get(entry.getKey()); - Node n2 = g2map.get(entry.getValue()); - - // if we find two isomorph concrete nodes that are not equal, the whole mapping - // is invalid. - if (n1.isConcrete() && n2.isConcrete() && !n1.equals(n2)) { - return new HashMap(); - } - } - - return mapping; - } - - public static boolean areIsomorphic(GraphPattern gp1, GraphPattern gp2) throws ParseException { - return !getIsomorphisms(gp1, gp2).isEmpty(); - } - - private static class GraphInfo { - - private DirectedMultigraph graph; - private Map intToNodeMap; - - public GraphInfo(GraphPattern gp) { - ElementPathBlock epb = gp.getGraphPattern(); - - // initialize and convert fromGraph - this.graph = new DirectedMultigraph<>(); - - this.intToNodeMap = new HashMap<>(); - Map nodeToIntMap = new HashMap<>(); - List triples = epb.getPattern().getList(); - - int fromVertexCounter = 1; - - for (TriplePath t : triples) { - - Node subject = t.getSubject(); - Node predicate = t.getPredicate(); - Node object = t.getObject(); - - boolean success; - if (!intToNodeMap.containsValue(subject)) { - intToNodeMap.put(fromVertexCounter, subject); - nodeToIntMap.put(subject, fromVertexCounter); - success = this.graph.add(fromVertexCounter); - } - - fromVertexCounter++; - if (!intToNodeMap.containsValue(object)) { - intToNodeMap.put(fromVertexCounter, object); - nodeToIntMap.put(object, fromVertexCounter); - success = this.graph.add(fromVertexCounter); - } - - SimpleDirectedTypedEdge e = new SimpleDirectedTypedEdge(new NodeEdge(predicate), - nodeToIntMap.get(subject), nodeToIntMap.get(object)); - - success = this.graph.add(e); - - if (!success) - LOG.warn("Adding edge to the graph should succeed."); - LOG.debug("Adding edge with type {} between {} and {} to the graph should succeed.", e, subject, - object); - - fromVertexCounter++; - } - } - - public DirectedMultigraph getGraph() { - return graph; - } - - public Map getIntToNodeMap() { - return intToNodeMap; - } - } - -} diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessor.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessor.java index 59cd6b1b3..959e52fe9 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessor.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessor.java @@ -123,18 +123,18 @@ public interface InteractionProcessor { void setDomainKnowledge(Set someRules); /** - * Whether the InteractionProcessor should use reasoning to orchestrate the data - * exchange, or should use a matcher instead. Enabling the reasoner increases - * the flexibility of the data exchange, but decreases the performance. + * Which reasoner level the InteractionProcessor should use to orchestrate the + * data exchange. Different levels increases the flexibility of the data + * exchange, but decreases the performance. * - * @param aReasonerEnabled {@code true} if this interaction processor should use - * reasoning, {@code false} otherwise. + * @param aReasonerLevel The reasoner level to use if no specific level is + * configured. */ - void setReasonerEnabled(boolean aReasonerEnabled); + void setReasonerLevel(int aReasonerLevel); /** - * @return {@code true} if the reasoner for this interaction processor is - * enabled, {@code false} otherwise. + * @return The reasoner level that is being used by this interaction processor + * when no specific level is given by the user. */ - boolean isReasonerEnabled(); + int getReasonerLevel(); } diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImpl.java index f48dde3a7..b4686e652 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImpl.java @@ -40,11 +40,11 @@ import eu.knowledge.engine.smartconnector.api.BindingValidator; import eu.knowledge.engine.smartconnector.api.CommunicativeAct; import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.MatchStrategy; import eu.knowledge.engine.smartconnector.api.PostPlan; import eu.knowledge.engine.smartconnector.api.ReactExchangeInfo; import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; import eu.knowledge.engine.smartconnector.api.RecipientSelector; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.api.Vocab; import eu.knowledge.engine.smartconnector.messaging.AnswerMessage; import eu.knowledge.engine.smartconnector.messaging.AskMessage; @@ -72,10 +72,11 @@ public class InteractionProcessorImpl implements InteractionProcessor { private final LoggerProvider loggerProvider; /** - * Whether this interaction processor should use reasoning to orchestrate the - * data exchange. + * The default reasoner level of this smart connector is retrieved from the + * configuration. */ - private boolean reasonerEnabled = false; + private int reasonerLevel = ConfigProvider.getConfig().getValue(SmartConnectorConfig.CONF_KEY_KE_REASONER_LEVEL, + Integer.class); private static final Query query = QueryFactory.create( "ASK WHERE { ?req ?someClass . FILTER NOT EXISTS {?sat ?someClass .} VALUES (?req ?sat) {} }"); @@ -84,7 +85,7 @@ public InteractionProcessorImpl(LoggerProvider loggerProvider, OtherKnowledgeBas KnowledgeBaseStore myKnowledgeBaseStore) { super(); this.loggerProvider = loggerProvider; - this.LOG = loggerProvider.getLogger(this.getClass()); + this.LOG = this.loggerProvider.getLogger(this.getClass()); this.otherKnowledgeBaseStore = otherKnowledgeBaseStore; this.myKnowledgeBaseStore = myKnowledgeBaseStore; @@ -102,8 +103,6 @@ public AskPlan planAskFromKnowledgeBase(MyKnowledgeInteractionInfo anAKI, Recipi assert anAKI != null : "the knowledge interaction should be non-null"; assert aSelector != null : "the selector should be non-null"; - var myKnowledgeInteraction = anAKI.getKnowledgeInteraction(); - // retrieve other knowledge bases Set otherKnowledgeBases = this.otherKnowledgeBaseStore.getOtherKnowledgeBases(); @@ -127,16 +126,10 @@ public AskPlan planAskFromKnowledgeBase(MyKnowledgeInteractionInfo anAKI, Recipi // But filter on the communicative act. These have to match! filterWithCommunicativeActMatcher(anAKI, otherKnowledgeInteractions); - // create a new SingleInteractionProcessor to handle this ask. - SingleInteractionProcessor processor; - if (this.reasonerEnabled) { - processor = new ReasonerProcessor(otherKnowledgeInteractions, messageRouter, - this.additionalDomainKnowledge); - } else { - processor = new ReasonerProcessor(otherKnowledgeInteractions, messageRouter, - this.additionalDomainKnowledge); - ((ReasonerProcessor) processor).setMatchStrategy(MatchStrategy.ENTRY_LEVEL); - } + // create a new ReasonerProcessor to handle this ask. + ReasonerProcessor processor = new ReasonerProcessor(otherKnowledgeInteractions, messageRouter, + this.additionalDomainKnowledge); + processor.setMatchStrategy(SmartConnectorConfig.toMatchStrategy(this.reasonerLevel)); // give the caller something to chew on while it waits. This method starts the // interaction process as far as it can until it is blocked because it waits for @@ -273,8 +266,6 @@ public PostPlan planPostFromKnowledgeBase(MyKnowledgeInteractionInfo aPKI, Recip assert aPKI != null : "the knowledge interaction should be non-null"; assert aSelector != null : "the selector should be non-null"; - var myKnowledgeInteraction = aPKI.getKnowledgeInteraction(); - // retrieve other knowledge bases Set otherKnowledgeBases = this.otherKnowledgeBaseStore.getOtherKnowledgeBases(); @@ -297,16 +288,11 @@ public PostPlan planPostFromKnowledgeBase(MyKnowledgeInteractionInfo aPKI, Recip // But filter on the communicative act. These have to match! filterWithCommunicativeActMatcher(aPKI, otherKnowledgeInteractions); - // create a new SingleInteractionProcessor to handle this ask. - SingleInteractionProcessor processor; - if (this.reasonerEnabled) { - processor = new ReasonerProcessor(otherKnowledgeInteractions, this.messageRouter, - this.additionalDomainKnowledge); - } else { - processor = new ReasonerProcessor(otherKnowledgeInteractions, this.messageRouter, - this.additionalDomainKnowledge); - ((ReasonerProcessor) processor).setMatchStrategy(MatchStrategy.ENTRY_LEVEL); - } + // create a new ReasonerProcessor to handle this ask. + ReasonerProcessor processor = new ReasonerProcessor(otherKnowledgeInteractions, this.messageRouter, + this.additionalDomainKnowledge); + processor.setMatchStrategy(SmartConnectorConfig.toMatchStrategy(this.reasonerLevel)); + // give the caller something to chew on while it waits. This method starts the // interaction process as far as it can until it is blocked because it waits for // outstanding message replies. Then it returns the future. Threads from the @@ -513,13 +499,13 @@ public void setDomainKnowledge(Set someRules) { } @Override - public void setReasonerEnabled(boolean aReasonerEnabled) { - this.reasonerEnabled = aReasonerEnabled; + public void setReasonerLevel(int aReasonerLevel) { + this.reasonerLevel = aReasonerLevel; } @Override - public boolean isReasonerEnabled() { - return this.reasonerEnabled; + public int getReasonerLevel() { + return this.reasonerLevel; } } diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/KnowledgeBaseStoreImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/KnowledgeBaseStoreImpl.java index 41fde020c..0a44d968a 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/KnowledgeBaseStoreImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/KnowledgeBaseStoreImpl.java @@ -322,6 +322,7 @@ public Resource getPurpose(URI knowledgeBaseId, URI knowledgeInteractionId) { @Override public void stop() { + this.LOG.trace("Stopping KnowledgeBaseStoreImpl"); this.listeners.forEach(l -> l.smartConnectorStopping()); } } diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MessageRouterImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MessageRouterImpl.java index 5422e5b02..47ce4b927 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MessageRouterImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MessageRouterImpl.java @@ -13,6 +13,7 @@ import org.eclipse.microprofile.config.ConfigProvider; import org.slf4j.Logger; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.messaging.AnswerMessage; import eu.knowledge.engine.smartconnector.messaging.AskMessage; import eu.knowledge.engine.smartconnector.messaging.ErrorMessage; diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MetaKnowledgeBaseImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MetaKnowledgeBaseImpl.java index 332cdd798..71c5b89e5 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MetaKnowledgeBaseImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/MetaKnowledgeBaseImpl.java @@ -294,8 +294,6 @@ private BindingSet fillMetaBindings(BindingSet incoming) { LOG.trace("BindingSet: {}", bindings); - String val = bindings.iterator().next().get("isMeta"); - if (incoming != null) { Util.removeRedundantBindingsAnswer(incoming, bindings); } diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/OtherKnowledgeBase.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/OtherKnowledgeBase.java index 6f1d1ab90..f3f009078 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/OtherKnowledgeBase.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/OtherKnowledgeBase.java @@ -5,11 +5,6 @@ import java.util.Iterator; import java.util.List; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.ResultSet; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Resource; @@ -23,7 +18,6 @@ import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.BindingSet; import eu.knowledge.engine.smartconnector.api.GraphPattern; import eu.knowledge.engine.smartconnector.api.PostKnowledgeInteraction; import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java index 8b7fc579d..6ec813737 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java @@ -2,19 +2,20 @@ import java.io.IOException; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import eu.knowledge.engine.reasoner.api.TripleNode; import org.apache.jena.graph.Node; -import org.apache.jena.sparql.core.TriplePath; import org.apache.jena.sparql.core.Var; -import org.apache.jena.sparql.graph.PrefixMappingZero; import org.apache.jena.sparql.serializer.SerializationContext; -import org.apache.jena.sparql.syntax.ElementPathBlock; import org.apache.jena.sparql.util.FmtUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +30,7 @@ import eu.knowledge.engine.reasoner.SinkBindingSetHandler; import eu.knowledge.engine.reasoner.TaskBoard; import eu.knowledge.engine.reasoner.TransformBindingSetHandler; +import eu.knowledge.engine.reasoner.api.TripleNode; import eu.knowledge.engine.reasoner.api.TriplePattern; import eu.knowledge.engine.reasoner.rulenode.RuleNode; import eu.knowledge.engine.reasoner.rulestore.RuleStore; @@ -113,7 +115,7 @@ public ReasonerProcessor(Set knowledgeInteractions, Me if (kii.getType().equals(Type.ANSWER)) { AnswerKnowledgeInteraction aki = (AnswerKnowledgeInteraction) ki; GraphPattern gp = aki.getPattern(); - Rule aRule = new Rule(ruleName, new HashSet<>(translateGraphPatternTo(gp)), + Rule aRule = new Rule(ruleName, new HashSet<>(Util.translateGraphPatternTo(gp)), new AnswerBindingSetHandler(kii)); store.addRule(aRule); LOG.debug("Adding ANSWER to store: {}", aRule); @@ -125,10 +127,11 @@ public ReasonerProcessor(Set knowledgeInteractions, Me Set resPattern; Rule aRule; if (resGp == null) { - aRule = new Rule(ruleName, translateGraphPatternTo(argGp), new ReactVoidBindingSetHandler(kii)); + aRule = new Rule(ruleName, Util.translateGraphPatternTo(argGp), + new ReactVoidBindingSetHandler(kii)); } else { - resPattern = new HashSet<>(translateGraphPatternTo(resGp)); - aRule = new Rule(ruleName, translateGraphPatternTo(argGp), resPattern, + resPattern = new HashSet<>(Util.translateGraphPatternTo(resGp)); + aRule = new Rule(ruleName, Util.translateGraphPatternTo(argGp), resPattern, new ReactBindingSetHandler(kii)); } @@ -151,7 +154,7 @@ public void planAskInteraction(MyKnowledgeInteractionInfo aAKI) { ? aAKI.getKnowledgeInteraction().getName() : aAKI.getId().toString(); - ProactiveRule aRule = new ProactiveRule(ruleName, translateGraphPatternTo(aki.getPattern()), + ProactiveRule aRule = new ProactiveRule(ruleName, Util.translateGraphPatternTo(aki.getPattern()), new HashSet<>()); this.store.addRule(aRule); MatchStrategy aStrategy; @@ -193,11 +196,11 @@ public CompletableFuture executeAskInteraction(BindingSet someBinding return this.finalBindingSetFuture.thenApply((bs) -> { if (myKnowledgeInteraction.getKnowledgeInteraction().knowledgeGapsEnabled()) { - this.knowledgeGaps = bs.isEmpty() - ? getKnowledgeGaps(this.reasonerPlan.getStartNode()) - : new HashSet(); + this.knowledgeGaps = bs.isEmpty() ? getKnowledgeGaps(this.reasonerPlan.getStartNode()) + : new HashSet(); } - return new AskResult(translateBindingSetFrom(bs), this.askExchangeInfos, this.reasonerPlan, this.knowledgeGaps); + return new AskResult(translateBindingSetFrom(bs), this.askExchangeInfos, this.reasonerPlan, + this.knowledgeGaps); }); } @@ -238,11 +241,11 @@ public void planPostInteraction(MyKnowledgeInteractionInfo aPKI) { if (pki.getResult() != null) { this.captureResultBindingSetHandler = new CaptureBindingSetHandler(); - store.addRule(new Rule(ruleName, translateGraphPatternTo(pki.getResult()), + store.addRule(new Rule(ruleName, Util.translateGraphPatternTo(pki.getResult()), this.captureResultBindingSetHandler)); } - Set translatedGraphPattern = translateGraphPatternTo(pki.getArgument()); + Set translatedGraphPattern = Util.translateGraphPatternTo(pki.getArgument()); ProactiveRule aRule = new ProactiveRule(ruleName, new HashSet<>(), new HashSet<>(translatedGraphPattern)); store.addRule(aRule); @@ -349,29 +352,6 @@ protected eu.knowledge.engine.reasoner.api.BindingSet translateBindingSetTo(Bind return newBindingSet; } - private Set translateGraphPatternTo(GraphPattern pattern) { - - TriplePattern tp; - TriplePath triplePath; - String triple; - ElementPathBlock epb = pattern.getGraphPattern(); - Iterator iter = epb.patternElts(); - - Set triplePatterns = new HashSet(); - - while (iter.hasNext()) { - - triplePath = iter.next(); - - triple = FmtUtils.stringForTriple(triplePath.asTriple(), new PrefixMappingZero()); - - tp = new TriplePattern(triple); - triplePatterns.add(tp); - } - - return triplePatterns; - } - public static class CaptureBindingSetHandler implements SinkBindingSetHandler { private eu.knowledge.engine.reasoner.api.BindingSet bs; @@ -709,7 +689,8 @@ public Set getKnowledgeGaps(RuleNode plan) { } LOG.debug("Found a neighbor without gaps is {}", foundNeighborWithoutGap); - if (foundNeighborWithoutGap) continue; + if (foundNeighborWithoutGap) + continue; // there is a gap here, either in the current node or in a neighbor @@ -727,11 +708,13 @@ public Set getKnowledgeGaps(RuleNode plan) { } /** - * Given two triples, decides how they should be combined into a (single) knowledge gap + * Given two triples, decides how they should be combined into a (single) + * knowledge gap * * @param existingTriple First triple - * @param newTriple Second triple - * @return Action that should be taken when merging these two triples in a knowledge gap + * @param newTriple Second triple + * @return Action that should be taken when merging these two triples in a + * knowledge gap */ private static TripleMatchType getTripleMatchType(TriplePattern existingTriple, TriplePattern newTriple) { Map matches = existingTriple.findMatches(newTriple); @@ -761,11 +744,14 @@ private static TripleMatchType getTripleMatchType(TriplePattern existingTriple, /** * Merges two Knowledge Gaps into one Knowledge Gap - * @param gap First knowledge gap - * @param gapToAdd Knowledge gap that should be added/merged into the first knowledge gap - * @return one Knowledge Gap containing triples from both provided knowledge gaps, ignoring triples that - * are duplicates or more generic (e.g. {@code ?id hasCountry ?c} is ignored if there is already - * {@code ?id hasCountry Ireland}) + * + * @param gap First knowledge gap + * @param gapToAdd Knowledge gap that should be added/merged into the first + * knowledge gap + * @return one Knowledge Gap containing triples from both provided knowledge + * gaps, ignoring triples that are duplicates or more generic (e.g. + * {@code ?id hasCountry ?c} is ignored if there is already + * {@code ?id hasCountry Ireland}) */ private static KnowledgeGap mergeGap(KnowledgeGap gap, KnowledgeGap gapToAdd) { KnowledgeGap result = new KnowledgeGap(gap); @@ -775,8 +761,9 @@ private static KnowledgeGap mergeGap(KnowledgeGap gap, KnowledgeGap gapToAdd) { TripleMatchType tripleAction = getTripleMatchType(existingTriple, tripleToAdd); tripleActions.put(existingTriple, tripleAction); } - Set replaces = tripleActions.entrySet().stream().filter(t -> - t.getValue() == TripleMatchType.REPLACE_TRIPLE).map(Map.Entry::getKey).collect(Collectors.toSet()); + Set replaces = tripleActions.entrySet().stream() + .filter(t -> t.getValue() == TripleMatchType.REPLACE_TRIPLE).map(Map.Entry::getKey) + .collect(Collectors.toSet()); if (replaces.size() == 1) { TriplePattern toReplace = replaces.iterator().next(); @@ -790,10 +777,15 @@ private static KnowledgeGap mergeGap(KnowledgeGap gap, KnowledgeGap gapToAdd) { } /** - * Given multiple knowledge gaps, adds the gaps in gapstoAdd to all knowledge gaps in listOfGaps - * @param listOfGaps list of knowledge gaps to which new knowledge gaps should be added - * @param gapsToAdd knowledge gaps that should be added to the gaps in listOfGaps - * @return Set of KnowledgeGaps where knowledge gaps in gapsToAdd have been merged/added to the gaps in listOfGaps + * Given multiple knowledge gaps, adds the gaps in gapstoAdd to all knowledge + * gaps in listOfGaps + * + * @param listOfGaps list of knowledge gaps to which new knowledge gaps should + * be added + * @param gapsToAdd knowledge gaps that should be added to the gaps in + * listOfGaps + * @return Set of KnowledgeGaps where knowledge gaps in gapsToAdd have been + * merged/added to the gaps in listOfGaps */ private static Set mergeGaps(Set listOfGaps, Set gapsToAdd) { if (listOfGaps.isEmpty()) { @@ -835,9 +827,10 @@ public void setMatchStrategy(MatchStrategy aStrategy) { } /** - * Enum that represents which action to take for a triple when merging two knowledge gaps - * Given a triple, compared to another triple, the first triple can either be - * (1) Added to the Knowledge Gap, (2) Ignored, or (3) Replace the other triple + * Enum that represents which action to take for a triple when merging two + * knowledge gaps Given a triple, compared to another triple, the first triple + * can either be (1) Added to the Knowledge Gap, (2) Ignored, or (3) Replace the + * other triple */ private enum TripleMatchType { ADD_TRIPLE, IGNORE_TRIPLE, REPLACE_TRIPLE diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorConfig.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorConfig.java deleted file mode 100644 index 7f18b2a2e..000000000 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -package eu.knowledge.engine.smartconnector.impl; - -public class SmartConnectorConfig { - - /** - * Key to set whether this KER should strictly validate whether outgoing - * bindings are compatible with incoming bindings. - */ - public static final String CONF_KEY_VALIDATE_OUTGOING_BINDINGS_WRT_INCOMING_BINDINGS = "sc.validate.outgoing.bindings.wrt.incoming.bindings"; - - /** - * Key to configure the hostname of the machine this Knowledge Engine Runtime - * (KER) runs on. - * - * @deprecated Replaced by - * {@link SmartConnectorConfig#CONF_KEY_KE_RUNTIME_EXPOSED_URL} - */ - @Deprecated - public static final String CONF_KEY_KE_RUNTIME_HOSTNAME = "ke.runtime.hostname"; - - /** - * Key to configure the URL of the Knowledge Directory where this KER can find - * other KERs in the network. Note that overriding this configuration property - * will run this KER in distributed mode. - */ - public static final String CONF_KEY_KD_URL = "kd.url"; - - /** - * Key to configure the time in seconds the SCs in this KER wait for a HTTP - * connection response from another KER. Only used in distributed mode. - */ - public static final String CONF_KEY_KE_HTTP_TIMEOUT = "ke.http.timeout"; - - /** - * Key to configure the how many seconds the MessageRouter should wait for - * ANSWER/REACT Message when sending a ASK/POST Message? 0 means wait forever - * (useful when working with a human KB). - */ - public static final String CONF_KEY_KE_KB_WAIT_TIMEOUT = "ke.kb.wait.timeout"; - - /** - * Key to configure the URL that is advertised to other KERs. Other KERs can use - * this URL to reach this KER. Note that this configuration property is only - * used in distributed mode. - */ - public static final String CONF_KEY_KE_RUNTIME_EXPOSED_URL = "ke.runtime.exposed.url"; - - /** - * Key to configure the port at which the KER's peer-to-peer communication - * should happen. Only used in distributed mode. - */ - public static final String CONF_KEY_KE_RUNTIME_PORT = "ke.runtime.port"; -} diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorImpl.java index d905f5cc8..0de0aaddd 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/SmartConnectorImpl.java @@ -17,7 +17,6 @@ import eu.knowledge.engine.smartconnector.api.AskPlan; import eu.knowledge.engine.smartconnector.api.AskResult; import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.BindingValidator; import eu.knowledge.engine.smartconnector.api.GraphPattern; import eu.knowledge.engine.smartconnector.api.KnowledgeBase; import eu.knowledge.engine.smartconnector.api.KnowledgeInteraction; @@ -56,7 +55,6 @@ public class SmartConnectorImpl implements RuntimeSmartConnector, LoggerProvider private final MessageRouterImpl messageRouter; private boolean isStopped = false; private final ExecutorService knowledgeBaseExecutorService; - private final BindingValidator bindingValidator = new BindingValidator(); private CompletableFuture constructorFinished = new CompletableFuture(); private Instant started; @@ -543,13 +541,17 @@ public void setDomainKnowledge(Set someDomainKnowledge) { } @Override - public void setReasonerEnabled(boolean aReasonerEnabled) { - this.interactionProcessor.setReasonerEnabled(aReasonerEnabled); + public void setReasonerLevel(int aReasonerLevel) { + if (aReasonerLevel < 1 || aReasonerLevel > 5) + throw new IllegalArgumentException( + "The reasoner level should lie between 1 and 5, inclusive and should not be '" + aReasonerLevel + + "'"); + this.interactionProcessor.setReasonerLevel(aReasonerLevel); } @Override - public boolean isReasonerEnabled() { - return this.interactionProcessor.isReasonerEnabled(); + public int getReasonerLevel() { + return this.interactionProcessor.getReasonerLevel(); } } diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/Util.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/Util.java index 7dcdc7cc6..35ff00ea4 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/Util.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/Util.java @@ -1,11 +1,9 @@ package eu.knowledge.engine.smartconnector.impl; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; +import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import javax.cache.Cache; @@ -21,11 +19,15 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.sparql.core.TriplePath; +import org.apache.jena.sparql.graph.PrefixMappingZero; import org.apache.jena.sparql.lang.arq.ParseException; import org.apache.jena.sparql.sse.SSE; +import org.apache.jena.sparql.syntax.ElementPathBlock; +import org.apache.jena.sparql.util.FmtUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import eu.knowledge.engine.reasoner.api.TriplePattern; import eu.knowledge.engine.smartconnector.api.Binding; import eu.knowledge.engine.smartconnector.api.BindingSet; import eu.knowledge.engine.smartconnector.api.GraphPattern; @@ -98,6 +100,29 @@ public static Model generateModel(GraphPattern graphPattern, BindingSet variable } return m; } + + public static Set translateGraphPatternTo(GraphPattern pattern) { + + TriplePattern tp; + TriplePath triplePath; + String triple; + ElementPathBlock epb = pattern.getGraphPattern(); + Iterator iter = epb.patternElts(); + + Set triplePatterns = new HashSet(); + + while (iter.hasNext()) { + + triplePath = iter.next(); + + triple = FmtUtils.stringForTriple(triplePath.asTriple(), new PrefixMappingZero()); + + tp = new TriplePattern(triple); + triplePatterns.add(tp); + } + + return triplePatterns; + } public static void removeRedundantBindingsAnswer(BindingSet incoming, BindingSet outgoing) { if (incoming.isEmpty()) { diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/KeRuntime.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/KeRuntime.java index 1eec0ea60..06d823444 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/KeRuntime.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/KeRuntime.java @@ -14,7 +14,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.impl.SmartConnectorConfig; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.runtime.messaging.MessageDispatcher; /** diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/messaging/RemoteKerConnection.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/messaging/RemoteKerConnection.java index a8da339bc..ef821eeb4 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/messaging/RemoteKerConnection.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/runtime/messaging/RemoteKerConnection.java @@ -27,7 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import eu.knowledge.engine.smartconnector.impl.SmartConnectorConfig; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.messaging.AnswerMessage; import eu.knowledge.engine.smartconnector.messaging.AskMessage; import eu.knowledge.engine.smartconnector.messaging.ErrorMessage; diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/util/KnowledgeBaseImpl.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/util/KnowledgeBaseImpl.java index c3c9a8a26..ca073364c 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/util/KnowledgeBaseImpl.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/util/KnowledgeBaseImpl.java @@ -22,6 +22,7 @@ import org.apache.jena.sparql.util.FmtUtils; import org.apache.jena.util.iterator.ExtendedIterator; import org.apache.jena.vocabulary.RDF; +import org.eclipse.microprofile.config.ConfigProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,6 +43,7 @@ import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; import eu.knowledge.engine.smartconnector.api.RecipientSelector; import eu.knowledge.engine.smartconnector.api.SmartConnector; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.api.Vocab; import eu.knowledge.engine.smartconnector.impl.SmartConnectorBuilder; import eu.knowledge.engine.smartconnector.impl.Util; @@ -77,14 +79,10 @@ public class KnowledgeBaseImpl implements KnowledgeBase { private CompletableFuture stoppedFuture = new CompletableFuture(); /** - * Enable the reasoner. Off by default (for now). + * Using the default reasoner level from the configuration. */ - private boolean reasonerEnabled = false; - - /** - * Whether the Knowledge Base is threadsafe. - */ - private boolean isThreadSafe = false; + private int reasonerLevel = ConfigProvider.getConfig().getValue(SmartConnectorConfig.CONF_KEY_KE_REASONER_LEVEL, + Integer.class); public KnowledgeBaseImpl(String aName) { this(null, aName, null); @@ -494,7 +492,7 @@ private String convertToPattern(GraphPattern gp) { public void start() { if (!isStarted()) { this.sc = SmartConnectorBuilder.newSmartConnector(this).create(); - this.sc.setReasonerEnabled(this.reasonerEnabled); + this.sc.setReasonerLevel(this.reasonerLevel); } } @@ -558,17 +556,18 @@ public void syncKIs() { this.unregisteredReactKIs.clear(); this.getSC().setDomainKnowledge(this.domainKnowledge); - this.getSC().setReasonerEnabled(this.reasonerEnabled); + this.getSC().setReasonerLevel(this.reasonerLevel); } - public void setReasonerEnabled(boolean aReasonerEnabled) { - this.reasonerEnabled = aReasonerEnabled; + /** {@link SmartConnectorConfig#CONF_KEY_KE_REASONER_LEVEL} */ + public void setReasonerLevel(int aReasonerLevel) { + this.reasonerLevel = aReasonerLevel; } - public boolean isReasonerEnabled() { - return this.reasonerEnabled; + public int getReasonerLevel() { + return this.reasonerLevel; } public AskPlan planAsk(AskKnowledgeInteraction anAKI, RecipientSelector aSelector) { @@ -579,10 +578,6 @@ public PostPlan planPost(PostKnowledgeInteraction aPKI, RecipientSelector aSelec return this.getSC().planPost(aPKI, aSelector); } - public void setIsThreadSafe(boolean aIsThreadSafe) { - this.isThreadSafe = aIsThreadSafe; - } - public boolean isStarted() { return this.getSC() != null; } diff --git a/smart-connector/src/main/resources/META-INF/microprofile-config.properties b/smart-connector/src/main/resources/META-INF/microprofile-config.properties index ecb1cea5d..3a1b15123 100644 --- a/smart-connector/src/main/resources/META-INF/microprofile-config.properties +++ b/smart-connector/src/main/resources/META-INF/microprofile-config.properties @@ -5,4 +5,5 @@ ke.kb.wait.timeout = 10 ke.http.timeout = 5 kd.url = http://localhost:8080 sc.validate.outgoing.bindings.wrt.incoming.bindings = true -ke.runtime.hostname = localhost \ No newline at end of file +ke.runtime.hostname = localhost +ke.reasoner.level = 2 \ No newline at end of file diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/AdditionForAudienceTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/AdditionForAudienceTest.java index cccb7d2a3..06449f6df 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/AdditionForAudienceTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/AdditionForAudienceTest.java @@ -1,18 +1,22 @@ package eu.knowledge.engine.smartconnector.api; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; +@Disabled //it works, but takes about 230 seconds @Tag("Long") public class AdditionForAudienceTest { @@ -87,7 +91,7 @@ public void beforeAll() { // kb1 kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); + kb1.setReasonerLevel(4); kn.addKB(kb1); var reactKI = new ReactKnowledgeInteraction(new CommunicativeAct(), new GraphPattern( @@ -98,7 +102,7 @@ public void beforeAll() { // kb10 kb10 = new KnowledgeBaseImpl("kb10"); - kb10.setReasonerEnabled(true); + kb10.setReasonerLevel(4); kn.addKB(kb10); reactKI = new ReactKnowledgeInteraction(new CommunicativeAct(), new GraphPattern( "?e . ?e ?n1 . ?e ?n2 . ?n1 . ?n1 ?d1 . ?d1 \"2\" . ?d1 ?ad1 . ?n2 . ?n2 ?d2 . ?d2 \"2\" . ?d2 ?ad2 ."), @@ -107,7 +111,7 @@ public void beforeAll() { kb10.register(reactKI, new MyReactHandler(2)); kb100 = new KnowledgeBaseImpl("kb100"); - kb100.setReasonerEnabled(true); + kb100.setReasonerLevel(4); kn.addKB(kb100); reactKI = new ReactKnowledgeInteraction(new CommunicativeAct(), new GraphPattern( "?e . ?e ?n1 . ?e ?n2 . ?n1 . ?n1 ?d1 . ?d1 \"3\" . ?d1 ?ad1 . ?n2 . ?n2 ?d2 . ?d2 \"3\" . ?d2 ?ad2 ."), @@ -116,7 +120,7 @@ public void beforeAll() { kb100.register(reactKI, new MyReactHandler(3)); kbSum = new KnowledgeBaseImpl("kbSum"); - kbSum.setReasonerEnabled(true); + kbSum.setReasonerLevel(4); kn.addKB(kbSum); var answerKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), new GraphPattern( @@ -188,7 +192,7 @@ public void beforeAll() { }); kbNum = new KnowledgeBaseImpl("kbNum"); - kbNum.setReasonerEnabled(true); + kbNum.setReasonerLevel(4); kn.addKB(kbNum); this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), new GraphPattern( @@ -219,6 +223,31 @@ public void test() throws InterruptedException, ExecutionException { System.out.println("Result: " + ar.getBindings()); + BindingSet bs = new BindingSet(); + Binding b1 = new Binding(); + b1.put("p", "\"2\""); + b1.put("n1", "<123/456>"); + b1.put("e", ""); + b1.put("d1", "<123/456/digit/2>"); + b1.put("ad1", "\"7\""); + bs.add(b1); + Binding b2 = new Binding(); + b2.put("p", "\"1\""); + b2.put("n1", "<123/456>"); + b2.put("e", ""); + b2.put("d1", "<123/456/digit/1>"); + b2.put("ad1", "\"5\""); + bs.add(b2); + Binding b3 = new Binding(); + b3.put("p", "\"3\""); + b3.put("n1", "<123/456>"); + b3.put("e", ""); + b3.put("d1", "<123/456/digit/3>"); + b3.put("ad1", "\"9\""); + bs.add(b3); + + assertEquals(bs, ar.getBindings()); + } @AfterAll diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java index 38ea10f85..d06b54ab2 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java @@ -47,7 +47,7 @@ public class GeneralizeIfNecessaryTest { public void test() throws InterruptedException, ExecutionException { kn.addKB(appKb); - this.appKb.setReasonerEnabled(true); + this.appKb.setReasonerLevel(2); kn.addKB(sensor1Kb); kn.addKB(sensor2Kb); kn.addKB(floorplanKb); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/MultiThreadingPerformanceTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/MultiThreadingPerformanceTest.java index 474d42728..6f06befd3 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/MultiThreadingPerformanceTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/MultiThreadingPerformanceTest.java @@ -152,10 +152,8 @@ public void test() throws InterruptedException { kn = new KnowledgeNetwork(); poster = new KnowledgeBaseImpl("poster"); - poster.setIsThreadSafe(true); kn.addKB(poster); reacter = new KnowledgeBaseImpl("reacter"); - reacter.setIsThreadSafe(true); kn.addKB(reacter); // add KIs diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/NotDesignedToWorkTogetherTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/NotDesignedToWorkTogetherTest.java index b12bc52be..682cb1e87 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/NotDesignedToWorkTogetherTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/NotDesignedToWorkTogetherTest.java @@ -48,7 +48,6 @@ public class NotDesignedToWorkTogetherTest { public void test() throws InterruptedException { kn.addKB(appKb); - this.appKb.setReasonerEnabled(true); kn.addKB(lamp1Kb); kn.addKB(lamp2Kb); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/SingleLargeVsMultipleSmallGraphPatternTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/SingleLargeVsMultipleSmallGraphPatternTest.java index 029e31c6d..6d20b923d 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/SingleLargeVsMultipleSmallGraphPatternTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/SingleLargeVsMultipleSmallGraphPatternTest.java @@ -1,5 +1,7 @@ package eu.knowledge.engine.smartconnector.api; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.concurrent.ExecutionException; import org.apache.jena.shared.PrefixMapping; @@ -39,11 +41,8 @@ public void testSingleLargeGP() throws InterruptedException, ExecutionException // creating SCs KnowledgeBaseImpl kb1 = new KnowledgeBaseImpl("KB1"); kn1.addKB(kb1); - kb1.setReasonerEnabled(true); KnowledgeBaseImpl kb2 = new KnowledgeBaseImpl("KB2"); kn1.addKB(kb2); - kb2.setReasonerEnabled(true); - // prepare large binding final BindingSet bs = new BindingSet(); Binding b1; @@ -89,6 +88,8 @@ public void testSingleLargeGP() throws InterruptedException, ExecutionException kn1.stop().get(); + assertTrue(ar.getBindings().size() > 0); + } @Test @@ -97,10 +98,8 @@ public void testMultipleSmallGPs() throws InterruptedException, ExecutionExcepti // creating SCs KnowledgeBaseImpl kb1 = new KnowledgeBaseImpl("KB1"); kn2.addKB(kb1); - kb1.setReasonerEnabled(true); KnowledgeBaseImpl kb2 = new KnowledgeBaseImpl("KB2"); kn2.addKB(kb2); - kb2.setReasonerEnabled(true); // prepare large binding final BindingSet bs1 = new BindingSet(); @@ -159,6 +158,8 @@ public void testMultipleSmallGPs() throws InterruptedException, ExecutionExcepti LOG.info("Bindings: {}", ar.getBindings()); + assertTrue(ar.getBindings().size() > 0); + kn2.stop().get(); } diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAddingDeletingManySmartConnectors.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAddingDeletingManySmartConnectors.java index 36dfcc50a..66a7c8047 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAddingDeletingManySmartConnectors.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAddingDeletingManySmartConnectors.java @@ -8,8 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.KnowledgeBase; -import eu.knowledge.engine.smartconnector.api.SmartConnector; import eu.knowledge.engine.smartconnector.impl.SmartConnectorBuilder; public class TestAddingDeletingManySmartConnectors { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer.java index 669ed1c56..6f7b429cb 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer.java @@ -14,7 +14,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.apache.jena.rdf.model.Resource; import org.apache.jena.shared.PrefixMapping; import org.apache.jena.sparql.graph.PrefixMappingMem; import org.junit.jupiter.api.AfterAll; @@ -23,8 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswer { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer3.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer3.java index 8bab526d2..064cd7fa6 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer3.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer3.java @@ -21,17 +21,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskExchangeInfo; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswer3 { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java index 1642d88b2..32e4482a8 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java @@ -41,10 +41,8 @@ public void testAskAnswer() throws InterruptedException { var kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kn.addKB(kb1); kb2 = new KnowledgeBaseImpl("kb2"); - kb1.setReasonerEnabled(true); kn.addKB(kb2); GraphPattern gp1 = new GraphPattern(prefixes, "?a ?c ."); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer5.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer5.java index c091bee5d..9ca5e76cc 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer5.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer5.java @@ -21,8 +21,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswer5 { @@ -43,16 +43,12 @@ public void testAskAnswer() throws InterruptedException { this.kn = new KnowledgeNetwork(); KnowledgeBaseImpl kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kn.addKB(kb1); KnowledgeBaseImpl kb2 = new KnowledgeBaseImpl("kb2"); - kb2.setReasonerEnabled(true); kn.addKB(kb2); KnowledgeBaseImpl kb3 = new KnowledgeBaseImpl("kb3"); - kb3.setReasonerEnabled(true); kn.addKB(kb3); KnowledgeBaseImpl kb4 = new KnowledgeBaseImpl("kb4"); - kb4.setReasonerEnabled(true); kn.addKB(kb4); GraphPattern gp1 = new GraphPattern(prefixes, """ diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerRealistic.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerRealistic.java index 33a9b9585..86f879a61 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerRealistic.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerRealistic.java @@ -22,8 +22,8 @@ import eu.knowledge.engine.reasoner.Rule; import eu.knowledge.engine.reasoner.api.TriplePattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; @Disabled public class TestAskAnswerRealistic { @@ -52,25 +52,15 @@ public void testAskAnswer() throws InterruptedException { var kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kb2 = new KnowledgeBaseImpl("kb2"); - kb2.setReasonerEnabled(true); kb3 = new KnowledgeBaseImpl("kb3"); - kb3.setReasonerEnabled(true); kb4 = new KnowledgeBaseImpl("kb4"); - kb4.setReasonerEnabled(true); kb5 = new KnowledgeBaseImpl("kb5"); - kb5.setReasonerEnabled(true); kb6 = new KnowledgeBaseImpl("kb6"); - kb6.setReasonerEnabled(true); kb7 = new KnowledgeBaseImpl("kb7"); - kb7.setReasonerEnabled(true); kb8 = new KnowledgeBaseImpl("kb8"); - kb8.setReasonerEnabled(true); kb9 = new KnowledgeBaseImpl("kb9"); - kb9.setReasonerEnabled(true); kb10 = new KnowledgeBaseImpl("kb10"); - kb10.setReasonerEnabled(true); var rules = new HashSet(); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerSingleKBMultipleMatchingKIs.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerSingleKBMultipleMatchingKIs.java index f6513d8b2..4030376ce 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerSingleKBMultipleMatchingKIs.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerSingleKBMultipleMatchingKIs.java @@ -5,10 +5,7 @@ import static org.junit.jupiter.api.Assertions.fail; import java.net.URI; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -22,17 +19,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskExchangeInfo; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswerSingleKBMultipleMatchingKIs { @@ -54,10 +42,8 @@ public void testAskAnswer() throws InterruptedException { var kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kn.addKB(kb1); kb2 = new KnowledgeBaseImpl("kb2"); - kb2.setReasonerEnabled(true); kn.addKB(kb2); GraphPattern gp = new GraphPattern(prefixes, "?a ?c."); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerUnregister.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerUnregister.java index 769b25c97..9399e1422 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerUnregister.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerUnregister.java @@ -18,16 +18,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswerUnregister { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled1.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled1.java index f49501bfd..e6c3186e3 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled1.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled1.java @@ -28,7 +28,7 @@ public class TestAskAnswerWithGapsEnabled1 { private static final Logger LOG = LoggerFactory.getLogger(TestAskAnswerWithGapsEnabled1.class); private static KnowledgeBaseImpl kbRelationAsker; - + private static KnowledgeNetwork kn; private static PrefixMappingMem prefixes; @@ -46,20 +46,20 @@ public static void setup() throws InterruptedException, BrokenBarrierException, @Test public void testAskAnswerWithGapsEnabled() throws InterruptedException, URISyntaxException { - + // In this test there will be only 1 KB with a single AskKI. // The test will execute the AskKI with knowledge gaps enabled. // As a result, the set of knowledge gaps should contain a single gap. setupNetwork(); - + // Perform the ASK try { AskResult result = kbRelationAsker.ask(askKIGaps, new BindingSet()).get(); // check whether set of knowledge gaps contains a single gap - Set gaps = result.getKnowledgeGaps(); + Set gaps = result.getKnowledgeGaps(); LOG.info("Found gaps: " + gaps); - assertFalse(gaps.isEmpty(),"The set of knowledge gaps should be empty"); + assertFalse(gaps.isEmpty(), "The set of knowledge gaps should be empty"); assertEquals(1, gaps.size(), "Number of gaps should be 1"); Iterator iter = gaps.iterator(); while (iter.hasNext()) { @@ -68,11 +68,11 @@ public void testAskAnswerWithGapsEnabled() throws InterruptedException, URISynta } BindingSet bindings = result.getBindings(); LOG.info("Resulting binding set is: " + bindings); - assertTrue(bindings.isEmpty(),"The resulting bindingset should be empty"); + assertTrue(bindings.isEmpty(), "The resulting bindingset should be empty"); } catch (InterruptedException | ExecutionException e) { fail(); } - + } private void setupNetwork() { @@ -90,11 +90,12 @@ private void setupNetwork() { public void instantiateAskRelationsKB() { // start a knowledge base with the behavior "I am interested in related people" kbRelationAsker = new KnowledgeBaseImpl("RelationAsker"); - kbRelationAsker.setReasonerEnabled(true); - + kbRelationAsker.setReasonerLevel(4); + // Register an Ask pattern for relations with knowledge gaps enabled GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo ?b ."); - this.askKIGaps = new AskKnowledgeInteraction(new CommunicativeAct(), gp1, "askRelations", false, true, true, MatchStrategy.SUPREME_LEVEL); + this.askKIGaps = new AskKnowledgeInteraction(new CommunicativeAct(), gp1, "askRelations", false, true, true, + MatchStrategy.SUPREME_LEVEL); kbRelationAsker.register(this.askKIGaps); } diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled2.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled2.java index 56b18acfb..5a2087510 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled2.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled2.java @@ -107,7 +107,7 @@ private void setupNetwork() { public void instantiateAskRelationsKB() { // start a knowledge base with the behavior "I am interested in related people" kbRelationAsker = new KnowledgeBaseImpl("RelationAsker"); - kbRelationAsker.setReasonerEnabled(true); + kbRelationAsker.setReasonerLevel(4); // Register an Ask pattern for relations with knowledge gaps enabled GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo ?b . ?a ex:isFatherOf ?c ."); @@ -120,7 +120,7 @@ public void instantiateAskRelationsKB() { public void instantiateAnswerRelationsKB() { // start a knowledge base with the behavior "I can supply related people" kbRelationProvider = new KnowledgeBaseImpl("RelationProvider"); - kbRelationProvider.setReasonerEnabled(true); + kbRelationProvider.setReasonerLevel(4); // Patterns for the RelationProvider: an Answer pattern for relations GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo ?b ."); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled3.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled3.java index c32e4d717..c0426e460 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled3.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsEnabled3.java @@ -33,7 +33,7 @@ public class TestAskAnswerWithGapsEnabled3 { private static KnowledgeBaseImpl kbRelationAsker; private static KnowledgeBaseImpl kbRelationProvider; private static KnowledgeBaseImpl kbRelationReactor; - + private static KnowledgeNetwork kn; private static PrefixMappingMem prefixes; @@ -51,22 +51,23 @@ public static void setup() throws InterruptedException, BrokenBarrierException, @Test public void testAskAnswerReactWithGapsEnabled() throws InterruptedException, URISyntaxException { - + // In this test there will be an Ask KB with an AskKI with 2 triplepatterns, - // an AnswerKB with a single AnswerKI that answers only the first triplepattern of the Ask pattern, and + // an AnswerKB with a single AnswerKI that answers only the first triplepattern + // of the Ask pattern, and // a ReactKB that can answer the , but needs another pattern to be satisfied. // The test will execute the AskKI with knowledge gaps enabled. // As a result, the set of knowledge gaps should contain a single gap. setupNetwork(); - + // Perform the ASK try { AskResult result = kbRelationAsker.ask(askKIGaps, new BindingSet()).get(); // check whether set of knowledge gaps contains a single gap - Set gaps = result.getKnowledgeGaps(); + Set gaps = result.getKnowledgeGaps(); LOG.info("Found gaps: " + gaps); - assertFalse(gaps.isEmpty(),"The set of knowledge gaps should not be empty"); + assertFalse(gaps.isEmpty(), "The set of knowledge gaps should not be empty"); assertEquals(1, gaps.size(), "Number of gaps should be 1"); Iterator iter = gaps.iterator(); while (iter.hasNext()) { @@ -80,11 +81,11 @@ public void testAskAnswerReactWithGapsEnabled() throws InterruptedException, URI } BindingSet bindings = result.getBindings(); LOG.info("Resulting binding set is: " + bindings); - assertTrue(bindings.isEmpty(),"The resulting bindingset should be empty"); + assertTrue(bindings.isEmpty(), "The resulting bindingset should be empty"); } catch (InterruptedException | ExecutionException e) { fail(); } - + } private void setupNetwork() { @@ -106,11 +107,12 @@ private void setupNetwork() { public void instantiateAskRelationsKB() { // start a knowledge base with the behavior "I am interested in related people" kbRelationAsker = new KnowledgeBaseImpl("RelationAsker"); - kbRelationAsker.setReasonerEnabled(true); - + kbRelationAsker.setReasonerLevel(4); + // Register an Ask pattern for relations with knowledge gaps enabled GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo ?b . ?a ex:isFatherOf ?c ."); - this.askKIGaps = new AskKnowledgeInteraction(new CommunicativeAct(), gp1, "askRelations", false, true, true, MatchStrategy.SUPREME_LEVEL); + this.askKIGaps = new AskKnowledgeInteraction(new CommunicativeAct(), gp1, "askRelations", false, true, true, + MatchStrategy.SUPREME_LEVEL); kbRelationAsker.register(this.askKIGaps); } @@ -118,7 +120,7 @@ public void instantiateAskRelationsKB() { public void instantiateAnswerRelationsKB() { // start a knowledge base with the behavior "I can supply related people" kbRelationProvider = new KnowledgeBaseImpl("RelationProvider"); - kbRelationProvider.setReasonerEnabled(true); + kbRelationProvider.setReasonerLevel(4); // Patterns for the RelationProvider: an Answer pattern for relations GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo1 ?b ."); @@ -142,10 +144,11 @@ public void instantiateAnswerRelationsKB() { public void instantiateReactRelationsKB() { - // start a knowledge base with the behavior "I can react to supply related people" + // start a knowledge base with the behavior "I can react to supply related + // people" // when I get couples of "people that live in the same house". kbRelationReactor = new KnowledgeBaseImpl("relationReactor"); - kbRelationReactor.setReasonerEnabled(true); + kbRelationReactor.setReasonerLevel(4); // Patterns for the relationReactor: an React pattern to supply relations GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:liveInTheSameHouse ?b ."); @@ -160,7 +163,7 @@ public void instantiateReactRelationsKB() { while (iter.hasNext()) { Binding b = iter.next(); LOG.info("Incoming tuple of people living in the same house is {}", b); - Binding binding1 = new Binding(); + Binding binding1 = new Binding(); binding1.put("a", b.get("a")); binding1.put("b", b.get("b")); bindingSet.add(binding1); @@ -168,7 +171,7 @@ public void instantiateReactRelationsKB() { return bindingSet; }); - + } @AfterAll diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsNotEnabled.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsNotEnabled.java index ca3efae0c..3bb055368 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsNotEnabled.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithGapsNotEnabled.java @@ -82,7 +82,7 @@ private void setupNetwork() { public void instantiateAskRelationsKB() { // start a knowledge base with the behavior "I am interested in related people" kbRelationAsker = new KnowledgeBaseImpl("RelationAsker"); - kbRelationAsker.setReasonerEnabled(true); + kbRelationAsker.setReasonerLevel(4); // Register an Ask pattern for relations without knowledge gaps enabled GraphPattern gp1 = new GraphPattern(prefixes, "?a ex:isRelatedTo ?b ."); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithPartialBindings.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithPartialBindings.java index 163863916..9d7028efd 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithPartialBindings.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswerWithPartialBindings.java @@ -15,16 +15,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskAnswerWithPartialBindings { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskPartialMetadata.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskPartialMetadata.java index 261fd2883..22fa80c9e 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskPartialMetadata.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskPartialMetadata.java @@ -1,15 +1,11 @@ package eu.knowledge.engine.smartconnector.api; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.util.Iterator; import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.jena.shared.PrefixMapping; @@ -20,16 +16,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskPartialMetadata { @@ -52,13 +40,10 @@ public void testAskAnswer() throws InterruptedException { var kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kn.addKB(kb1); kb2 = new KnowledgeBaseImpl("kb2"); - kb2.setReasonerEnabled(true); kn.addKB(kb2); kb3 = new KnowledgeBaseImpl("kb3"); - kb3.setReasonerEnabled(true); kn.addKB(kb3); GraphPattern gp2 = new GraphPattern(prefixes, diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskRecipientSelector.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskRecipientSelector.java index 36bd316fb..e4b780355 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskRecipientSelector.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskRecipientSelector.java @@ -22,18 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskExchangeInfo; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.RecipientSelector; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestAskRecipientSelector { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestComplexGraphPatternMatching.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestComplexGraphPatternMatching.java index 6987e243a..64b48e87c 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestComplexGraphPatternMatching.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestComplexGraphPatternMatching.java @@ -22,7 +22,6 @@ import org.apache.jena.sparql.util.FmtUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,10 +31,9 @@ import eu.knowledge.engine.reasoner.api.TripleNode; import eu.knowledge.engine.reasoner.api.TriplePattern; import eu.knowledge.engine.reasoner.api.TripleVarBinding; -import eu.knowledge.engine.reasoner.api.TripleVarBindingSet; import eu.knowledge.engine.smartconnector.impl.Util; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestComplexGraphPatternMatching { @@ -134,7 +132,6 @@ public void findMissingVars(Set gp, TripleVarBinding tvb) { private AskKnowledgeInteraction createDashboardKB(PrefixMappingMem prefixes, KnowledgeNetwork kn) { dashboardKB = new KnowledgeBaseImpl("dashboardKB"); - dashboardKB.setReasonerEnabled(true); kn.addKB(dashboardKB); String gp = """ @@ -270,7 +267,6 @@ public float convert(float fahrenheit) { private void createDevicesKB(PrefixMappingMem prefixes, KnowledgeNetwork kn) { devicesKB = new KnowledgeBaseImpl("devicesKB"); - devicesKB.setReasonerEnabled(true); kn.addKB(devicesKB); GraphPattern gp1 = new GraphPattern(prefixes, TestUtils.convertGP(""" ?d rdf:type ?type . @@ -384,7 +380,6 @@ private void createDevicesKB(PrefixMappingMem prefixes, KnowledgeNetwork kn) { private void createObservationsKB(PrefixMappingMem prefixes, KnowledgeNetwork kn) { observationsKB = new KnowledgeBaseImpl("observationsKB"); - observationsKB.setReasonerEnabled(true); kn.addKB(observationsKB); GraphPattern gp12 = new GraphPattern(prefixes, TestUtils.convertGP(""" diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDuplicateBindings.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDuplicateBindings.java index 8cf82aebf..2dcd9d94a 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDuplicateBindings.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDuplicateBindings.java @@ -22,22 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.AnswerHandler; -import eu.knowledge.engine.smartconnector.api.AnswerKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskExchangeInfo; -import eu.knowledge.engine.smartconnector.api.AskKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.AskResult; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.PostExchangeInfo; -import eu.knowledge.engine.smartconnector.api.PostKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.PostResult; -import eu.knowledge.engine.smartconnector.api.ReactHandler; -import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestDuplicateBindings { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDynamicSemanticComposition.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDynamicSemanticComposition.java index 6783f3837..9d98907e3 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDynamicSemanticComposition.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestDynamicSemanticComposition.java @@ -102,11 +102,12 @@ public void testAskAnswer() throws InterruptedException, URISyntaxException { setupNetwork(); - // perform an ASK that should produce gaps and if found update network to fix gaps + // perform an ASK that should produce gaps and if found update network to fix + // gaps try { AskResult resultWithGaps = kbHVTSearcher.ask(askKI, new BindingSet()).get(); // check for knowledge gaps - Set gaps = resultWithGaps.getKnowledgeGaps(); + Set gaps = resultWithGaps.getKnowledgeGaps(); LOG.info("Found gaps: " + gaps); // add KB that fills the knowledge gap updateNetwork(gaps); @@ -245,12 +246,11 @@ public void instantiateHVTSearcherKB() { // start a knowledge base with the behaviour "I am interested in high-value // targets" kbHVTSearcher = new KnowledgeBaseImpl("HVTSearcher"); - kbHVTSearcher.setReasonerEnabled(true); // Patterns for the HVTSearcher // a pattern to ask for High Value Target searches GraphPattern gp2 = new GraphPattern(prefixes, "?id rdf:type v1905:HighValueTarget . ?id v1905:hasName ?name ."); - this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp2, "askHVTargets",true); + this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp2, "askHVTargets", true); kbHVTSearcher.register(this.askKI); // a pattern to react to incoming new High Value Targets ReactKnowledgeInteraction reactKIsearcher = new ReactKnowledgeInteraction(new CommunicativeAct(), gp2, null); @@ -273,7 +273,6 @@ public void instantiateObserverKB() { // start a knowledge base with the behaviour "I can supply observations of // targets" kbTargetObserver = new KnowledgeBaseImpl("TargetObserver"); - kbTargetObserver.setReasonerEnabled(true); // Patterns for the TargetObserver // an Answer pattern for Target observations @@ -307,7 +306,6 @@ public void instantiateObserverKB() { public void instantiateTargetLanguageSupplierKB() { kbTargetLanguageSupplier = new KnowledgeBaseImpl("TargetLanguageSupplier"); - kbTargetLanguageSupplier.setReasonerEnabled(true); // Patterns for the TargetLanguageSupplier // a react pattern to get from targets to language @@ -349,14 +347,12 @@ public void instantiateTargetLanguageSupplierKB() { public void instantiateTargetAgeSupplierKB() { kbTargetAgeSupplier = new KnowledgeBaseImpl("TargetAgeSupplier"); - kbTargetAgeSupplier.setReasonerEnabled(true); } public void instantiateTargetCountrySupplierKB() { // start a knowledge base with the behaviour "Give me a target and I can supply // its basic attributes" kbTargetCountrySupplier = new KnowledgeBaseImpl("TargetCountrySupplier"); - kbTargetCountrySupplier.setReasonerEnabled(true); // Patterns for the TargetCountrySupplier // a react pattern to get from targets to countries diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestGraphPatternMatch.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestGraphPatternMatch.java index 91a60eac0..3a6177428 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestGraphPatternMatch.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestGraphPatternMatch.java @@ -3,28 +3,23 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Iterator; +import java.util.Collections; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.ResultSet; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.sparql.core.TriplePath; -import org.apache.jena.sparql.graph.PrefixMappingMem; import org.apache.jena.sparql.lang.arq.ParseException; -import org.apache.jena.sparql.util.FmtUtils; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.impl.GraphPatternMatcher; +import eu.knowledge.engine.reasoner.BaseRule; +import eu.knowledge.engine.reasoner.Match; +import eu.knowledge.engine.reasoner.Rule; +import eu.knowledge.engine.reasoner.SinkBindingSetHandler; +import eu.knowledge.engine.reasoner.TransformBindingSetHandler; +import eu.knowledge.engine.smartconnector.impl.Util; public class TestGraphPatternMatch { @@ -36,8 +31,7 @@ public void testSimpleIsomorphisms() throws ParseException { GraphPattern gp1 = new GraphPattern(" . ?p ."); GraphPattern gp2 = new GraphPattern(" ?p . ."); -// assertTrue(GraphPatternMatcher.areIsomorphic(gp1, gp2)); - Map isomorphism = GraphPatternMatcher.getIsomorphisms(gp1, gp2); + var isomorphism = getIsos(gp1, gp2); LOG.info("iso: {}", isomorphism); assertTrue(!isomorphism.isEmpty()); @@ -53,7 +47,7 @@ public void testMultipleIsomorphisms() throws ParseException { new String[] { "?a ?b ?c", "?x ?y ?z" }, new String[] { " ?b ?c", " ?y ?z" }, // this is a known problem in the isomorphism testing. The ordering becomes // important if the nodes are all concrete. - // new String[] {"

.

", "

.

"}, + // new String[] {"

.

", "

.

"}, new String[] { "?id . ?id ?name . ?obs .", "?a . ?c . ?c ?d ." }, new String[] { @@ -96,8 +90,8 @@ public void testMultipleIsomorphisms() throws ParseException { GraphPattern ks1 = new GraphPattern(pair[0]); GraphPattern ks2 = new GraphPattern(pair[1]); - boolean doesMatch = GraphPatternMatcher.areIsomorphic(ks1, ks2); - LOG.info("SSpace graph should be equal: {}", doesMatch); + boolean doesMatch = !getIsos(ks1, ks2).isEmpty(); + LOG.info("Should be equal: {}", doesMatch); assertTrue(doesMatch); LOG.info("--------------------"); @@ -144,9 +138,9 @@ public void testMultipleIsomorphisms() throws ParseException { GraphPattern ks1 = new GraphPattern(pair[0]); GraphPattern ks2 = new GraphPattern(pair[1]); - boolean doesMatch = GraphPatternMatcher.areIsomorphic(ks1, ks2); + boolean doesMatch = !this.getIsos(ks1, ks2).isEmpty(); - LOG.info("SSpace graph shoud not be equal: {}", doesMatch); + LOG.info("Should not be equal: {}", doesMatch); assertFalse(doesMatch); LOG.info("--------------------"); @@ -154,86 +148,38 @@ public void testMultipleIsomorphisms() throws ParseException { } @Test - public void testMetadataBindingSetTransformation() { - String[] patterns = new String[] { - "?kb1 . ?kb1 ?name1 . ?kb1 ?description1 . ?kb1 ?ki1 . ?ki1 ?kiType1 . ?ki1 ?isMeta1 . ?ki1 ?act1 . ?act1 . ?act1 ?req1 . ?act1 ?sat1 . ?req1 ?reqType1 . ?sat1 ?satType1 . ?ki1 ?gp1 . ?gp1 ?patternType1 . ?gp1 ?pattern1 . ", - "?kb2 ?name2 . ?kb2 . ?kb2 ?description2 . ?kb2 ?ki2 . ?ki2 ?kiType2 . ?ki2 ?isMeta2 . ?ki2 ?act2 . ?act2 . ?act2 ?req2 . ?act2 ?sat2 . ?req2 ?reqType2 . ?sat2 ?satType2 . ?ki2 ?gp2 . ?gp2 ?patternType2 . ?gp2 ?pattern2 . " }; - - GraphPattern gp1 = new GraphPattern(patterns[0]); - GraphPattern gp2 = new GraphPattern(patterns[1]); - - Model m = ModelFactory.createDefaultModel(); - - m.read(this.getClass().getResourceAsStream("/metadata.ttl"), null, "turtle"); - - // then use the Knowledge Interaction as a query to retrieve the bindings. - Query q = QueryFactory.create("SELECT * WHERE {" + this.convertToPattern(gp1) + "}"); - LOG.trace("Query: {}", q); - QueryExecution qe = QueryExecutionFactory.create(q, m); - ResultSet rs = qe.execSelect(); - BindingSet fromBindingSet = new BindingSet(rs); - qe.close(); - - for (Binding binding : fromBindingSet) { - assertTrue(binding.containsKey("kb1")); - assertTrue(binding.containsKey("name1")); - assertTrue(binding.containsKey("description1")); - assertTrue(binding.containsKey("ki1")); - assertTrue(binding.containsKey("kiType1")); - assertTrue(binding.containsKey("isMeta1")); - assertTrue(binding.containsKey("act1")); - assertTrue(binding.containsKey("req1")); - assertTrue(binding.containsKey("sat1")); - assertTrue(binding.containsKey("reqType1")); - assertTrue(binding.containsKey("satType1")); - assertTrue(binding.containsKey("gp1")); - assertTrue(binding.containsKey("patternType1")); - assertTrue(binding.containsKey("pattern1")); - } - - BindingSet toBindingSet = GraphPatternMatcher.transformBindingSet(gp1, gp2, fromBindingSet); - - for (Binding binding : toBindingSet) { - assertTrue(binding.containsKey("kb2")); - assertTrue(binding.containsKey("name2")); - assertTrue(binding.containsKey("description2")); - assertTrue(binding.containsKey("ki2")); - assertTrue(binding.containsKey("kiType2")); - assertTrue(binding.containsKey("isMeta2")); - assertTrue(binding.containsKey("act2")); - assertTrue(binding.containsKey("req2")); - assertTrue(binding.containsKey("sat2")); - assertTrue(binding.containsKey("reqType2")); - assertTrue(binding.containsKey("satType2")); - assertTrue(binding.containsKey("gp2")); - assertTrue(binding.containsKey("patternType2")); - assertTrue(binding.containsKey("pattern2")); - } + public void testGraphPatternWithLiteral() { + GraphPattern gp = new GraphPattern("?s \"test\" ."); + assertTrue(true); + } - LOG.info("{}", fromBindingSet); - LOG.info("{}", toBindingSet); + private Set getIsos(GraphPattern gp1, GraphPattern gp2) { - } + Rule anteRule = new Rule(Util.translateGraphPatternTo(gp1), + (SinkBindingSetHandler) new SinkBindingSetHandler() { - private String convertToPattern(GraphPattern gp) { - Iterator iter = gp.getGraphPattern().patternElts(); + @Override + public CompletableFuture handle(eu.knowledge.engine.reasoner.api.BindingSet aBindingSet) { + // TODO Auto-generated method stub + return null; + } + }); - StringBuilder sb = new StringBuilder(); + Rule consRule = new Rule(Util.translateGraphPatternTo(gp2), new TransformBindingSetHandler() { - while (iter.hasNext()) { + @Override + public CompletableFuture handle( + eu.knowledge.engine.reasoner.api.BindingSet bs) { + // TODO Auto-generated method stub + return null; + } + }); - TriplePath tp = iter.next(); - sb.append(FmtUtils.stringForTriple(tp.asTriple(), new PrefixMappingMem())); - sb.append(" . "); - } +// assertTrue(GraphPatternMatcher.areIsomorphic(gp1, gp2)); + Map> isomorphism = BaseRule.getMatches(anteRule, Collections.singleton(consRule), true, + MatchStrategy.ENTRY_LEVEL.toConfig(true)); - return sb.toString(); - } - - @Test - public void testGraphPatternWithLiteral() - { - GraphPattern gp = new GraphPattern("?s \"test\" ."); + return isomorphism.containsKey(consRule) ? isomorphism.get(consRule) : new HashSet(); } } diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestIRI.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestIRI.java index 5d0aa9552..4dd9d4f88 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestIRI.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestIRI.java @@ -7,8 +7,6 @@ import org.apache.jena.iri.IRIFactory; import org.junit.jupiter.api.Test; -import eu.knowledge.engine.smartconnector.api.GraphPattern; - class TestIRI { private String[] validUris = new String[] { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestKnowledgeGapDetection.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestKnowledgeGapDetection.java index fd15e3b0c..ed40e703d 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestKnowledgeGapDetection.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestKnowledgeGapDetection.java @@ -25,175 +25,181 @@ public class TestKnowledgeGapDetection { - private static final Logger LOG = LoggerFactory.getLogger(TestKnowledgeGapDetection.class); - - private KnowledgeBaseImpl kbEggObserver; - private KnowledgeBaseImpl kbImperialEggSearcher; - private KnowledgeNetwork kn; - private PrefixMappingMem prefixes; - private AskKnowledgeInteraction askKI; - private Set ruleSet; - - @BeforeEach - public void setup() throws InterruptedException, BrokenBarrierException, TimeoutException { - prefixes = new PrefixMappingMem(); - prefixes.setNsPrefixes(PrefixMapping.Standard); - prefixes.setNsPrefix("ex", "https://www.tno.nl/example/"); - addDomainKnowledge(); - - instantiateImperialEggSearcherKB(); - instantiateObserverKB(); - - kn = new KnowledgeNetwork(); - kn.addKB(kbEggObserver); - kn.addKB(kbImperialEggSearcher); - kn.sync(); - } - - private void addDomainKnowledge() { - this.ruleSet = new HashSet<>(); - HashSet consequent1 = new HashSet<>(); - consequent1.add(new TriplePattern( - "?id ")); - HashSet antecedent1 = new HashSet<>(); - antecedent1.add(new TriplePattern( - "?id ")); - antecedent1.add(new TriplePattern("?id \"Alexander III\"")); - antecedent1.add(new TriplePattern("?id \"Russia\"")); - antecedent1.add(new TriplePattern("?id \"House of Fabergé\"")); - this.ruleSet.add(new Rule("Domain knowledge", antecedent1, consequent1, new Rule.AntecedentToConsequentBindingSetHandler(antecedent1))); - } - - @Test - public void testKnowledgeGap() throws InterruptedException, ExecutionException { - AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); - ReasonerPlan rn = plan.getReasonerPlan(); - rn.getStore().printGraphVizCode(rn); - AskResult result = plan.execute(new BindingSet()).get(); - Set gaps = result.getKnowledgeGaps(); - - LOG.info("Found gaps: " + gaps); - - assertEquals(1, gaps.size()); - - Set expectedGap = new HashSet<>(); - expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); - - assertEquals(expectedGap, gaps.toArray()[0]); - } - - - @Test - public void testKnowledgeGapNoMatchingVars() throws InterruptedException, ExecutionException { - GraphPattern gp = new GraphPattern(prefixes, - "?iq rdf:type . ?iq ?company . ?iq ?country . ?iq ?image ."); - this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggsNonMatching", false, false, true, MatchStrategy.SUPREME_LEVEL); - kbImperialEggSearcher.register(this.askKI); - kn.sync(); - - AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); - ReasonerPlan rn = plan.getReasonerPlan(); - rn.getStore().printGraphVizCode(rn); - - AskResult result = plan.execute(new BindingSet()).get(); - - Set gaps = result.getKnowledgeGaps(); - LOG.info("Found gaps: " + gaps); - - assertEquals(1, gaps.size()); - - Set expectedGap = new HashSet<>(); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); - - assertEquals(new KnowledgeGap(expectedGap), gaps.toArray()[0]); - } - - @Test - public void testNoKnowledgeGap() throws InterruptedException, ExecutionException { - GraphPattern gp = new GraphPattern(prefixes, - "?iq rdf:type . ?iq ?image ."); - this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggNoGap", false, false, true, MatchStrategy.SUPREME_LEVEL); - kbImperialEggSearcher.register(this.askKI); - kn.sync(); - - AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); - ReasonerPlan rn = plan.getReasonerPlan(); - rn.getStore().printGraphVizCode(rn); - - AskResult result = plan.execute(new BindingSet()).get(); - - Set gaps = result.getKnowledgeGaps(); - LOG.info("Found gaps: " + gaps); - - assertEquals(0, gaps.size()); - } - - @Test - public void testKnowledgeGapWithoutPrefixes() throws InterruptedException, ExecutionException { - GraphPattern gp = new GraphPattern("?id . ?id ?image ."); - this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggNoGap", false, false, true, MatchStrategy.SUPREME_LEVEL); - kbImperialEggSearcher.register(this.askKI); - kn.sync(); - - AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); - ReasonerPlan rn = plan.getReasonerPlan(); - rn.getStore().printGraphVizCode(rn); - - AskResult result = plan.execute(new BindingSet()).get(); - Set gaps = result.getKnowledgeGaps(); - LOG.info("Found gaps: " + gaps); - - assertEquals(1, gaps.size()); - Set expectedGap = new HashSet<>(); - expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); - expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); - assertEquals(expectedGap, gaps.toArray()[0]); - } - - public void instantiateImperialEggSearcherKB() { - kbImperialEggSearcher = new KnowledgeBaseImpl("ImperialEggSearcher"); - kbImperialEggSearcher.setReasonerEnabled(true); - - GraphPattern gp2 = new GraphPattern(prefixes, - "?id rdf:type . ?id ?company . ?id ?country . ?id ?image ."); - this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp2, "askImperialEggs", false, false, true, MatchStrategy.SUPREME_LEVEL); - kbImperialEggSearcher.register(this.askKI); - kbImperialEggSearcher.setDomainKnowledge(this.ruleSet); - } - - public void instantiateObserverKB() { - kbEggObserver = new KnowledgeBaseImpl("EggObserver"); - kbEggObserver.setReasonerEnabled(true); - - GraphPattern gp1 = new GraphPattern(prefixes, "?id . ?id ?image ."); - AnswerKnowledgeInteraction aKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), gp1, "answerEggs"); - kbEggObserver.register(aKI, (AnswerHandler) (anAKI, anAnswerExchangeInfo) -> { - assertTrue( - anAnswerExchangeInfo.getIncomingBindings().isEmpty() - || anAnswerExchangeInfo.getIncomingBindings().iterator().next().getVariables().isEmpty(), - "Should not have bindings in this binding set."); - BindingSet bindingSet = new BindingSet(); - Binding binding1 = new Binding(); - binding1.put("id", ""); - binding1.put("image", "\"Picture Of Hen Fabergé Egg\"^^"); - bindingSet.add(binding1); - Binding binding2 = new Binding(); - binding2.put("id", ""); - binding2.put("image", "\"Picture of Third Imperial Fabergé Egg\""); - bindingSet.add(binding2); - - return bindingSet; - }); - } - - @AfterEach - public void cleanup() throws InterruptedException, ExecutionException { - LOG.info("Clean up: {}", TestKnowledgeGapDetection.class.getSimpleName()); - kn.stop().get(); - } + private static final Logger LOG = LoggerFactory.getLogger(TestKnowledgeGapDetection.class); + + private KnowledgeBaseImpl kbEggObserver; + private KnowledgeBaseImpl kbImperialEggSearcher; + private KnowledgeNetwork kn; + private PrefixMappingMem prefixes; + private AskKnowledgeInteraction askKI; + private Set ruleSet; + + @BeforeEach + public void setup() throws InterruptedException, BrokenBarrierException, TimeoutException { + prefixes = new PrefixMappingMem(); + prefixes.setNsPrefixes(PrefixMapping.Standard); + prefixes.setNsPrefix("ex", "https://www.tno.nl/example/"); + addDomainKnowledge(); + + instantiateImperialEggSearcherKB(); + instantiateObserverKB(); + + kn = new KnowledgeNetwork(); + kn.addKB(kbEggObserver); + kn.addKB(kbImperialEggSearcher); + kn.sync(); + } + + private void addDomainKnowledge() { + this.ruleSet = new HashSet<>(); + HashSet consequent1 = new HashSet<>(); + consequent1.add(new TriplePattern( + "?id ")); + HashSet antecedent1 = new HashSet<>(); + antecedent1.add(new TriplePattern( + "?id ")); + antecedent1.add(new TriplePattern("?id \"Alexander III\"")); + antecedent1.add(new TriplePattern("?id \"Russia\"")); + antecedent1.add(new TriplePattern("?id \"House of Fabergé\"")); + this.ruleSet.add(new Rule("Domain knowledge", antecedent1, consequent1, + new Rule.AntecedentToConsequentBindingSetHandler(antecedent1))); + } + + @Test + public void testKnowledgeGap() throws InterruptedException, ExecutionException { + AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); + ReasonerPlan rn = plan.getReasonerPlan(); + rn.getStore().printGraphVizCode(rn); + AskResult result = plan.execute(new BindingSet()).get(); + Set gaps = result.getKnowledgeGaps(); + + LOG.info("Found gaps: " + gaps); + + assertEquals(1, gaps.size()); + + Set expectedGap = new HashSet<>(); + expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); + + assertEquals(expectedGap, gaps.toArray()[0]); + } + + @Test + public void testKnowledgeGapNoMatchingVars() throws InterruptedException, ExecutionException { + GraphPattern gp = new GraphPattern(prefixes, + "?iq rdf:type . ?iq ?company . ?iq ?country . ?iq ?image ."); + this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggsNonMatching", false, false, + true, MatchStrategy.SUPREME_LEVEL); + kbImperialEggSearcher.register(this.askKI); + kn.sync(); + + AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); + ReasonerPlan rn = plan.getReasonerPlan(); + rn.getStore().printGraphVizCode(rn); + + AskResult result = plan.execute(new BindingSet()).get(); + + Set gaps = result.getKnowledgeGaps(); + LOG.info("Found gaps: " + gaps); + + assertEquals(1, gaps.size()); + + Set expectedGap = new HashSet<>(); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); + + assertEquals(new KnowledgeGap(expectedGap), gaps.toArray()[0]); + } + + @Test + public void testNoKnowledgeGap() throws InterruptedException, ExecutionException { + GraphPattern gp = new GraphPattern(prefixes, + "?iq rdf:type . ?iq ?image ."); + this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggNoGap", false, false, true, + MatchStrategy.SUPREME_LEVEL); + kbImperialEggSearcher.register(this.askKI); + kn.sync(); + + AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); + ReasonerPlan rn = plan.getReasonerPlan(); + rn.getStore().printGraphVizCode(rn); + + AskResult result = plan.execute(new BindingSet()).get(); + + Set gaps = result.getKnowledgeGaps(); + LOG.info("Found gaps: " + gaps); + + assertEquals(0, gaps.size()); + } + + @Test + public void testKnowledgeGapWithoutPrefixes() throws InterruptedException, ExecutionException { + GraphPattern gp = new GraphPattern( + "?id . ?id ?image ."); + this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp, "askImperialEggNoGap", false, false, true, + MatchStrategy.SUPREME_LEVEL); + kbImperialEggSearcher.register(this.askKI); + kn.sync(); + + AskPlan plan = kbImperialEggSearcher.planAsk(askKI, new RecipientSelector()); + ReasonerPlan rn = plan.getReasonerPlan(); + rn.getStore().printGraphVizCode(rn); + + AskResult result = plan.execute(new BindingSet()).get(); + Set gaps = result.getKnowledgeGaps(); + LOG.info("Found gaps: " + gaps); + + assertEquals(1, gaps.size()); + Set expectedGap = new HashSet<>(); + expectedGap.add(new TriplePattern(prefixes, "?id ex:commissionedBy \"Alexander III\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeIn \"Russia\"")); + expectedGap.add(new TriplePattern(prefixes, "?id ex:madeBy \"House of Fabergé\"")); + assertEquals(expectedGap, gaps.toArray()[0]); + } + + public void instantiateImperialEggSearcherKB() { + kbImperialEggSearcher = new KnowledgeBaseImpl("ImperialEggSearcher"); + kbImperialEggSearcher.setReasonerLevel(4); + + GraphPattern gp2 = new GraphPattern(prefixes, + "?id rdf:type . ?id ?company . ?id ?country . ?id ?image ."); + this.askKI = new AskKnowledgeInteraction(new CommunicativeAct(), gp2, "askImperialEggs", false, false, true, + MatchStrategy.SUPREME_LEVEL); + kbImperialEggSearcher.register(this.askKI); + kbImperialEggSearcher.setDomainKnowledge(this.ruleSet); + } + + public void instantiateObserverKB() { + kbEggObserver = new KnowledgeBaseImpl("EggObserver"); + kbEggObserver.setReasonerLevel(4); + + GraphPattern gp1 = new GraphPattern(prefixes, + "?id . ?id ?image ."); + AnswerKnowledgeInteraction aKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), gp1, "answerEggs"); + kbEggObserver.register(aKI, (AnswerHandler) (anAKI, anAnswerExchangeInfo) -> { + assertTrue( + anAnswerExchangeInfo.getIncomingBindings().isEmpty() + || anAnswerExchangeInfo.getIncomingBindings().iterator().next().getVariables().isEmpty(), + "Should not have bindings in this binding set."); + BindingSet bindingSet = new BindingSet(); + Binding binding1 = new Binding(); + binding1.put("id", ""); + binding1.put("image", "\"Picture Of Hen Fabergé Egg\"^^"); + bindingSet.add(binding1); + Binding binding2 = new Binding(); + binding2.put("id", ""); + binding2.put("image", "\"Picture of Third Imperial Fabergé Egg\""); + bindingSet.add(binding2); + + return bindingSet; + }); + } + + @AfterEach + public void cleanup() throws InterruptedException, ExecutionException { + LOG.info("Clean up: {}", TestKnowledgeGapDetection.class.getSimpleName()); + kn.stop().get(); + } } \ No newline at end of file diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataFromNormalKnowledgeInteraction.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataFromNormalKnowledgeInteraction.java index cdfa4d2ca..a7d3c1fe3 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataFromNormalKnowledgeInteraction.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataFromNormalKnowledgeInteraction.java @@ -34,6 +34,7 @@ public void testPostReact() throws InterruptedException { KnowledgeNetwork kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); + kb1.setReasonerLevel(1); kn.addKB(kb1); kb2 = new KnowledgeBaseImpl("kb2"); kn.addKB(kb2); @@ -46,23 +47,14 @@ public void testPostReact() throws InterruptedException { prefixes.setNsPrefixes(PrefixMapping.Standard); prefixes.setNsPrefix("ke", Vocab.ONTO_URI); var metaGraphPattern = new GraphPattern(prefixes, - // @formatter:off - "?kb rdf:type ke:KnowledgeBase .", - "?kb ke:hasName ?name .", - "?kb ke:hasDescription ?description .", - "?kb ke:hasKnowledgeInteraction ?ki .", - "?ki rdf:type ?kiType .", - "?ki ke:isMeta ?isMeta .", - "?ki ke:hasCommunicativeAct ?act .", - "?act rdf:type ke:CommunicativeAct .", - "?act ke:hasRequirement ?req .", - "?act ke:hasSatisfaction ?sat .", - "?req rdf:type ?reqType .", - "?sat rdf:type ?satType .", - "?ki ke:hasGraphPattern ?gp .", - "?gp rdf:type ?patternType .", + // @formatter:off + "?kb rdf:type ke:KnowledgeBase .", "?kb ke:hasName ?name .", "?kb ke:hasDescription ?description .", + "?kb ke:hasKnowledgeInteraction ?ki .", "?ki rdf:type ?kiType .", "?ki ke:isMeta ?isMeta .", + "?ki ke:hasCommunicativeAct ?act .", "?act rdf:type ke:CommunicativeAct .", + "?act ke:hasRequirement ?req .", "?act ke:hasSatisfaction ?sat .", "?req rdf:type ?reqType .", + "?sat rdf:type ?satType .", "?ki ke:hasGraphPattern ?gp .", "?gp rdf:type ?patternType .", "?gp ke:hasPattern ?pattern ."); - // @formatter:on + // @formatter:on PostKnowledgeInteraction ki1 = new PostKnowledgeInteraction( new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), new HashSet<>(Arrays.asList(Vocab.NEW_KNOWLEDGE_PURPOSE))), diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataKnowledgeInteractionMatching.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataKnowledgeInteractionMatching.java index 5193f1184..a4f6dd1e5 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataKnowledgeInteractionMatching.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestMetadataKnowledgeInteractionMatching.java @@ -1,7 +1,11 @@ package eu.knowledge.engine.smartconnector.api; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; -import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; + import org.apache.jena.shared.PrefixMapping; import org.apache.jena.sparql.graph.PrefixMappingMem; import org.junit.jupiter.api.AfterEach; @@ -10,116 +14,109 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.concurrent.ExecutionException; - -import static org.junit.jupiter.api.Assertions.*; +import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; /** - * This test checks whether we can use knowledge interactions to react to (part of) the metadata of a knowledge base - * We thought this would be impossible right now as someone tried to disable this because of the slow graph matching algorithm. - * However, we can still match on a small graph pattern, this may be caused by the order in which it is checked whether - * one pattern is a subset of the other. + * This test checks whether we can use knowledge interactions to react to (part + * of) the metadata of a knowledge base We thought this would be impossible + * right now as someone tried to disable this because of the slow graph matching + * algorithm. However, we can still match on a small graph pattern, this may be + * caused by the order in which it is checked whether one pattern is a subset of + * the other. */ public class TestMetadataKnowledgeInteractionMatching { - private static final Logger LOG = LoggerFactory.getLogger(TestDynamicSemanticComposition.class); - - private static KnowledgeNetwork kn; - private static KnowledgeBaseImpl kb1, kb2; - private static PrefixMappingMem prefixes; - - - @BeforeEach - public void setup() { - kn = new KnowledgeNetwork(); - kb1 = new KnowledgeBaseImpl("Kb1"); - kb1.setReasonerEnabled(true); - - prefixes = new PrefixMappingMem(); - prefixes.setNsPrefixes(PrefixMapping.Standard); - prefixes.setNsPrefix("ke", Vocab.ONTO_URI); - } - - @Test - public void testNewKB() { - ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction(new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), - new HashSet<>(Arrays.asList(Vocab.NEW_KNOWLEDGE_PURPOSE))), new GraphPattern(prefixes, - "?k ke:hasName ?n . ?k ke:hasDescription ?d ." - ), null, true); - kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { - var argument = aReactExchangeInfo.getArgumentBindings(); - Iterator iter = argument.iterator(); - assertTrue(iter.hasNext(), "There should be matches on metadata when a new KB is registered."); - return new BindingSet(); - })); - kn.addKB(kb1); - kn.sync(); - - kb2 = new KnowledgeBaseImpl("Kb2"); - kb2.setReasonerEnabled(true); - kn.addKB(kb2); - kn.sync(); - } - - @Test - public void testChangedKB() { - ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction(new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), - new HashSet<>(Arrays.asList(Vocab.CHANGED_KNOWLEDGE_PURPOSE))), new GraphPattern(prefixes, - "?k ke:hasName ?n . ?k ke:hasDescription ?d ." - ), null, true); - kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { - var argument = aReactExchangeInfo.getArgumentBindings(); - Iterator iter = argument.iterator(); - assertTrue(iter.hasNext(), "There should be matches on metadata when the network changes."); - return new BindingSet(); - })); - kn.addKB(kb1); - kn.sync(); - - kb2 = new KnowledgeBaseImpl("Kb2"); - kb2.setReasonerEnabled(true); - kn.addKB(kb2); - kn.sync(); - - GraphPattern gp1 = new GraphPattern(prefixes, "?a ?c."); - AnswerKnowledgeInteraction aKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), gp1); - kb1.register(aKI, (anAKI, anAnswerExchangeInfo) -> new BindingSet()); - } - - @Test - public void testRemovedKB() { - ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction(new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), - new HashSet<>(Arrays.asList(Vocab.REMOVED_KNOWLEDGE_PURPOSE))), new GraphPattern(prefixes, - "?k ke:hasName ?n . ?k ke:hasDescription ?d ." - ), null, true); - kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { - var argument = aReactExchangeInfo.getArgumentBindings(); - Iterator iter = argument.iterator(); - assertTrue(iter.hasNext(), "There should be matches on metadata when a KB is removed from the network."); - return new BindingSet(); - })); - kn.addKB(kb1); - kb2 = new KnowledgeBaseImpl("Kb2"); - kb2.setReasonerEnabled(true); - kn.addKB(kb2); - kn.sync(); - - kb2.stop(); - } - - @AfterEach - public void cleanup() { - try { - kb1.stop(); - } catch (IllegalStateException e) { - LOG.error("Stopping a knowledge base should succeed: {}", e.getMessage()); - } - try { - kb2.stop(); - } catch (IllegalStateException e) { - LOG.error("Stopping a knowledge base should succeed. {}", e.getMessage()); - } - } + private static final Logger LOG = LoggerFactory.getLogger(TestDynamicSemanticComposition.class); + + private static KnowledgeNetwork kn; + private static KnowledgeBaseImpl kb1, kb2; + private static PrefixMappingMem prefixes; + + @BeforeEach + public void setup() { + kn = new KnowledgeNetwork(); + kb1 = new KnowledgeBaseImpl("Kb1"); + + prefixes = new PrefixMappingMem(); + prefixes.setNsPrefixes(PrefixMapping.Standard); + prefixes.setNsPrefix("ke", Vocab.ONTO_URI); + } + + @Test + public void testNewKB() { + ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction( + new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), + new HashSet<>(Arrays.asList(Vocab.NEW_KNOWLEDGE_PURPOSE))), + new GraphPattern(prefixes, "?k ke:hasName ?n . ?k ke:hasDescription ?d ."), null, true); + kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { + var argument = aReactExchangeInfo.getArgumentBindings(); + Iterator iter = argument.iterator(); + assertTrue(iter.hasNext(), "There should be matches on metadata when a new KB is registered."); + return new BindingSet(); + })); + kn.addKB(kb1); + kn.sync(); + + kb2 = new KnowledgeBaseImpl("Kb2"); + kn.addKB(kb2); + kn.sync(); + } + + @Test + public void testChangedKB() { + ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction( + new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), + new HashSet<>(Arrays.asList(Vocab.CHANGED_KNOWLEDGE_PURPOSE))), + new GraphPattern(prefixes, "?k ke:hasName ?n . ?k ke:hasDescription ?d ."), null, true); + kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { + var argument = aReactExchangeInfo.getArgumentBindings(); + Iterator iter = argument.iterator(); + assertTrue(iter.hasNext(), "There should be matches on metadata when the network changes."); + return new BindingSet(); + })); + kn.addKB(kb1); + kn.sync(); + + kb2 = new KnowledgeBaseImpl("Kb2"); + kn.addKB(kb2); + kn.sync(); + + GraphPattern gp1 = new GraphPattern(prefixes, "?a ?c."); + AnswerKnowledgeInteraction aKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), gp1); + kb1.register(aKI, (anAKI, anAnswerExchangeInfo) -> new BindingSet()); + } + + @Test + public void testRemovedKB() { + ReactKnowledgeInteraction rKI = new ReactKnowledgeInteraction( + new CommunicativeAct(new HashSet<>(Arrays.asList(Vocab.INFORM_PURPOSE)), + new HashSet<>(Arrays.asList(Vocab.REMOVED_KNOWLEDGE_PURPOSE))), + new GraphPattern(prefixes, "?k ke:hasName ?n . ?k ke:hasDescription ?d ."), null, true); + kb1.register(rKI, ((anRKI, aReactExchangeInfo) -> { + var argument = aReactExchangeInfo.getArgumentBindings(); + Iterator iter = argument.iterator(); + assertTrue(iter.hasNext(), "There should be matches on metadata when a KB is removed from the network."); + return new BindingSet(); + })); + kn.addKB(kb1); + kb2 = new KnowledgeBaseImpl("Kb2"); + kn.addKB(kb2); + kn.sync(); + + kb2.stop(); + } + + @AfterEach + public void cleanup() { + try { + kb1.stop(); + } catch (IllegalStateException e) { + LOG.error("Stopping a knowledge base should succeed: {}", e.getMessage()); + } + try { + kb2.stop(); + } catch (IllegalStateException e) { + LOG.error("Stopping a knowledge base should succeed. {}", e.getMessage()); + } + } } diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact2.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact2.java index 0922d71fc..7159984fb 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact2.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact2.java @@ -6,8 +6,6 @@ import static org.junit.jupiter.api.Assertions.fail; import java.util.Iterator; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import org.apache.jena.shared.PrefixMapping; import org.apache.jena.sparql.graph.PrefixMappingMem; @@ -16,15 +14,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.PostKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.PostResult; -import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestPostReact2 { private static KnowledgeBaseImpl kb1; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact3.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact3.java index f752257ee..7187202a8 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact3.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReact3.java @@ -5,8 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import java.util.Arrays; -import java.util.HashSet; import java.util.Iterator; import org.apache.jena.shared.PrefixMapping; @@ -16,8 +14,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestPostReact3 { private static KnowledgeBaseImpl kb1; @@ -36,13 +34,10 @@ public void testPostReact() throws InterruptedException { KnowledgeNetwork kn = new KnowledgeNetwork(); kb1 = new KnowledgeBaseImpl("kb1"); - kb1.setReasonerEnabled(true); kn.addKB(kb1); kb2 = new KnowledgeBaseImpl("kb2"); - kb2.setReasonerEnabled(true); kn.addKB(kb2); kb3 = new KnowledgeBaseImpl("kb3"); - kb3.setReasonerEnabled(true); kn.addKB(kb3); // start registering diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReactPerformance.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReactPerformance.java index d33645b8a..4804f8b38 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReactPerformance.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostReactPerformance.java @@ -14,16 +14,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.PostKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.PostResult; -import eu.knowledge.engine.smartconnector.api.ReactHandler; -import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestPostReactPerformance { private static KnowledgeBaseImpl kb1; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostRecipientSelector.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostRecipientSelector.java index ac59b3d0d..32de69ee5 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostRecipientSelector.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestPostRecipientSelector.java @@ -11,21 +11,12 @@ import org.apache.jena.shared.PrefixMapping; import org.apache.jena.sparql.graph.PrefixMappingMem; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.knowledge.engine.smartconnector.api.Binding; -import eu.knowledge.engine.smartconnector.api.BindingSet; -import eu.knowledge.engine.smartconnector.api.CommunicativeAct; -import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.api.PostKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.PostResult; -import eu.knowledge.engine.smartconnector.api.ReactKnowledgeInteraction; -import eu.knowledge.engine.smartconnector.api.RecipientSelector; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestPostRecipientSelector { private static KnowledgeBaseImpl kb1; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRegisterKnowledgeInteraction.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRegisterKnowledgeInteraction.java index baf672371..ec5b08dc6 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRegisterKnowledgeInteraction.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRegisterKnowledgeInteraction.java @@ -1,12 +1,8 @@ package eu.knowledge.engine.smartconnector.api; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; import java.net.URI; -import java.net.URISyntaxException; -import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRequestMetadata.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRequestMetadata.java index 9aa46f338..8eb7e0041 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRequestMetadata.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestRequestMetadata.java @@ -7,7 +7,6 @@ import java.util.concurrent.ExecutionException; import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.shared.PrefixMapping; @@ -20,8 +19,8 @@ import org.slf4j.LoggerFactory; import eu.knowledge.engine.smartconnector.impl.Util; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class TestRequestMetadata { private static KnowledgeBaseImpl kb1; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestUtils.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestUtils.java index b365c3bb4..58ccd487d 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestUtils.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestUtils.java @@ -32,7 +32,6 @@ import eu.knowledge.engine.smartconnector.impl.ReasonerProcessor.AnswerBindingSetHandler; import eu.knowledge.engine.smartconnector.impl.ReasonerProcessor.ReactBindingSetHandler; import eu.knowledge.engine.smartconnector.impl.ReasonerProcessor.ReactVoidBindingSetHandler; -import eu.knowledge.engine.smartconnector.impl.SmartConnectorBuilder; public class TestUtils { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TimeOntologyTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TimeOntologyTest.java index 4bbb4944b..587567f49 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TimeOntologyTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TimeOntologyTest.java @@ -38,10 +38,6 @@ public void test() throws InterruptedException, ExecutionException { // add KBs - this.calendar.setReasonerEnabled(true); - this.app.setReasonerEnabled(true); - this.time.setReasonerEnabled(true); - kn.addKB(this.calendar); kn.addKB(this.app); kn.addKB(this.time); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImplTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImplTest.java index 64d25b885..7196a8d3a 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImplTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/InteractionProcessorImplTest.java @@ -30,14 +30,6 @@ import eu.knowledge.engine.smartconnector.api.CommunicativeAct; import eu.knowledge.engine.smartconnector.api.GraphPattern; import eu.knowledge.engine.smartconnector.api.RecipientSelector; -import eu.knowledge.engine.smartconnector.impl.InteractionProcessor; -import eu.knowledge.engine.smartconnector.impl.InteractionProcessorImpl; -import eu.knowledge.engine.smartconnector.impl.KnowledgeInteractionInfo; -import eu.knowledge.engine.smartconnector.impl.MessageRouter; -import eu.knowledge.engine.smartconnector.impl.MetaKnowledgeBase; -import eu.knowledge.engine.smartconnector.impl.MyKnowledgeInteractionInfo; -import eu.knowledge.engine.smartconnector.impl.OtherKnowledgeBase; -import eu.knowledge.engine.smartconnector.impl.OtherKnowledgeBaseStore; import eu.knowledge.engine.smartconnector.messaging.AnswerMessage; import eu.knowledge.engine.smartconnector.messaging.AskMessage; import eu.knowledge.engine.smartconnector.messaging.PostMessage; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java index a9237ae0f..4ef09a7ce 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java @@ -8,7 +8,6 @@ import org.apache.jena.datatypes.xsd.XSDDatatype; import org.apache.jena.graph.Node; import org.apache.jena.graph.NodeFactory; -import org.apache.jena.graph.Node; import org.apache.jena.sparql.core.Var; import org.junit.jupiter.api.Test; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/ConfigurationTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/ConfigurationTest.java index 2735eb4dc..958e4ecea 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/ConfigurationTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/ConfigurationTest.java @@ -1,6 +1,7 @@ package eu.knowledge.engine.smartconnector.misc; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -21,9 +22,9 @@ import eu.knowledge.engine.smartconnector.api.CommunicativeAct; import eu.knowledge.engine.smartconnector.api.ExchangeInfo; import eu.knowledge.engine.smartconnector.api.GraphPattern; -import eu.knowledge.engine.smartconnector.impl.SmartConnectorConfig; -import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.util.KnowledgeBaseImpl; +import eu.knowledge.engine.smartconnector.util.KnowledgeNetwork; public class ConfigurationTest { @@ -166,6 +167,20 @@ public void testConfigWaitForKnowledgeBasePositive() { System.clearProperty(SmartConnectorConfig.CONF_KEY_KE_KB_WAIT_TIMEOUT); } + @Test + public void testConfigReasonerLevelOutOfRange() { + + var kb = new KnowledgeBaseImpl("kb11"); + this.kn.addKB(kb); + kb.setReasonerLevel(0); + assertThrowsExactly(IllegalArgumentException.class, () -> kb.start()); + + var kbb = new KnowledgeBaseImpl("kb22"); + this.kn.addKB(kbb); + kbb.setReasonerLevel(6); + assertThrowsExactly(IllegalArgumentException.class, () -> kbb.start()); + } + @AfterEach public void afterTest() { try { diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/WireMockFirstConfigurationTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/WireMockFirstConfigurationTest.java index ceab06b27..13713940f 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/WireMockFirstConfigurationTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/misc/WireMockFirstConfigurationTest.java @@ -1,14 +1,8 @@ package eu.knowledge.engine.smartconnector.misc; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.matching; -import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.status; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.mockito.Mockito.mock; @@ -18,7 +12,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.slf4j.Logger; @@ -27,8 +20,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; -import eu.knowledge.engine.smartconnector.impl.SmartConnectorConfig; -import eu.knowledge.engine.smartconnector.runtime.KeRuntime; +import eu.knowledge.engine.smartconnector.api.SmartConnectorConfig; import eu.knowledge.engine.smartconnector.runtime.messaging.MessageDispatcher; import eu.knowledge.engine.smartconnector.runtime.messaging.RemoteKerConnection; import eu.knowledge.engine.smartconnector.runtime.messaging.kd.model.KnowledgeEngineRuntimeConnectionDetails; diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/MockSmartConnector.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/MockSmartConnector.java index a8f86ae70..16a99d566 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/MockSmartConnector.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/MockSmartConnector.java @@ -189,15 +189,15 @@ public void setDomainKnowledge(Set someDomainKnowledge) { } @Override - public void setReasonerEnabled(boolean aReasonerEnabled) { + public void setReasonerLevel(int aReasonerLevel) { // TODO Auto-generated method stub } @Override - public boolean isReasonerEnabled() { + public int getReasonerLevel() { // TODO Auto-generated method stub - return false; + return 2; } @Override diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/TestRegisterSmartConnectorWithSameId.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/TestRegisterSmartConnectorWithSameId.java index 02c2799c3..4fed65a85 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/TestRegisterSmartConnectorWithSameId.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/runtime/messaging/TestRegisterSmartConnectorWithSameId.java @@ -16,13 +16,15 @@ public class TestRegisterSmartConnectorWithSameId { private static final Logger LOG = LoggerFactory.getLogger(TestRegisterSmartConnectorWithSameId.class); private Phaser readyPhaser = new Phaser(1); + @Test - public void testRegisterSmartConnectorWithSameIdInSameRuntimeThrows() { + public void testRegisterSmartConnectorWithSameIdInSameRuntimeThrows() throws InterruptedException { var kb1 = new KnowledgeBaseImpl("http://example.org/kb1"); kb1.setPhaser(this.readyPhaser); kb1.start(); - + var kb1AsWell = new KnowledgeBaseImpl("http://example.org/kb1"); + kb1.setPhaser(this.readyPhaser); assertThrows(IllegalArgumentException.class, () -> { kb1AsWell.start();