Skip to content

Commit

Permalink
Merge pull request #553 from TNO/add-admin-ui-delay-and-reload
Browse files Browse the repository at this point in the history
Make AdminUI in distributive setup more useful.
  • Loading branch information
bnouwt authored Nov 7, 2024
2 parents 1f5ba3e + 7c1501b commit 954ca4b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 25 deletions.
74 changes: 49 additions & 25 deletions admin-ui/src/main/java/eu/knowledge/engine/admin/AdminUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class AdminUI implements KnowledgeBase {

private static final String META_GRAPH_PATTERN_STR = "?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 .";

private static final String CONF_KEY_INITIAL_ADMIN_UI_DELAY = "INITIAL_ADMIN_UI_DELAY";

private SmartConnector sc;
private final PrefixMapping prefixes;

Expand Down Expand Up @@ -119,34 +121,41 @@ public void smartConnectorReady(SmartConnector aSC) {
// create the correct Knowledge Interactions
this.aKI = new AskKnowledgeInteraction(new CommunicativeAct(), this.metaGraphPattern, true);
this.rKINew = new ReactKnowledgeInteraction(
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.NEW_KNOWLEDGE_PURPOSE)), new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null
);
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.NEW_KNOWLEDGE_PURPOSE)),
new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null);
this.rKIChanged = new ReactKnowledgeInteraction(
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.CHANGED_KNOWLEDGE_PURPOSE)), new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null
);
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.CHANGED_KNOWLEDGE_PURPOSE)),
new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null);
this.rKIRemoved = new ReactKnowledgeInteraction(
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.REMOVED_KNOWLEDGE_PURPOSE)), new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null
);
new CommunicativeAct(new HashSet<Resource>(Arrays.asList(Vocab.REMOVED_KNOWLEDGE_PURPOSE)),
new HashSet<Resource>(Arrays.asList(Vocab.INFORM_PURPOSE))),
this.metaGraphPattern, null);

// register the knowledge interactions with the smart connector.
this.sc.register(this.aKI);
this.sc.register(this.rKINew, (rki, ei) -> this.handleNewKnowledgeBaseKnowledge(ei));
this.sc.register(this.rKIChanged, (rki, ei) -> this.handleChangedKnowledgeBaseKnowledge(ei));
this.sc.register(this.rKIRemoved, (rki, ei) -> this.handleRemovedKnowledgeBaseKnowledge(ei));

// to receive the initial state, we do a single Ask
// to receive the initial state, we do a single Ask (after sleeping for a
// specific amount of time)
try {
Thread.sleep(Integer.parseInt(AdminUI.getConfigProperty(CONF_KEY_INITIAL_ADMIN_UI_DELAY, "5000")));
} catch (InterruptedException e) {
LOG.info("{}", e);
}
this.fetchInitialData();
}

public BindingSet handleNewKnowledgeBaseKnowledge(ReactExchangeInfo ei) {
if (!this.canReceiveUpdates()) return new BindingSet();
if (!this.canReceiveUpdates())
return new BindingSet();

try {
Model model = eu.knowledge.engine.smartconnector.impl.Util
.generateModel(this.aKI.getPattern(), ei.getArgumentBindings());
Model model = eu.knowledge.engine.smartconnector.impl.Util.generateModel(this.aKI.getPattern(),
ei.getArgumentBindings());

// this we can simply add to our model
this.model.add(model);
Expand All @@ -161,21 +170,23 @@ public BindingSet handleNewKnowledgeBaseKnowledge(ReactExchangeInfo ei) {
}
return new BindingSet();
}

public BindingSet handleChangedKnowledgeBaseKnowledge(ReactExchangeInfo ei) {
if (!this.canReceiveUpdates()) return new BindingSet();
if (!this.canReceiveUpdates())
return new BindingSet();

try {
Model model = eu.knowledge.engine.smartconnector.impl.Util
.generateModel(this.aKI.getPattern(), ei.getArgumentBindings());
Model model = eu.knowledge.engine.smartconnector.impl.Util.generateModel(this.aKI.getPattern(),
ei.getArgumentBindings());

// this is a little more complex... we have to:
// - extract the knowledge base that this message is about
// - delete all old data about that knowledge base
// - insert the *new* data about that knowledge base

Resource kb = model.query(new SimpleSelector(null, RDF.type, Vocab.KNOWLEDGE_BASE)).listSubjects().next();
String query = String.format("DELETE { %s } WHERE { %s FILTER (?kb = <%s>) } ", this.metaGraphPattern.getPattern(), this.metaGraphPattern.getPattern(), kb.toString());
String query = String.format("DELETE { %s } WHERE { %s FILTER (?kb = <%s>) } ",
this.metaGraphPattern.getPattern(), this.metaGraphPattern.getPattern(), kb.toString());
UpdateRequest updateRequest = UpdateFactory.create(query);
UpdateAction.execute(updateRequest, this.model);

Expand All @@ -193,18 +204,20 @@ public BindingSet handleChangedKnowledgeBaseKnowledge(ReactExchangeInfo ei) {
}

public BindingSet handleRemovedKnowledgeBaseKnowledge(ReactExchangeInfo ei) {
if (!this.canReceiveUpdates()) return new BindingSet();
if (!this.canReceiveUpdates())
return new BindingSet();

try {
Model model = eu.knowledge.engine.smartconnector.impl.Util
.generateModel(this.aKI.getPattern(), ei.getArgumentBindings());
Model model = eu.knowledge.engine.smartconnector.impl.Util.generateModel(this.aKI.getPattern(),
ei.getArgumentBindings());

// this is also a little complex... we have to:
// - extract the knowledge base that this message is about
// - delete all old data about that knowledge base

Resource kb = model.query(new SimpleSelector(null, RDF.type, Vocab.KNOWLEDGE_BASE)).listSubjects().next();
String query = String.format("DELETE { %s } WHERE { %s FILTER (?kb = <%s>) } ", this.metaGraphPattern.getPattern(), this.metaGraphPattern.getPattern(), kb.toString());
String query = String.format("DELETE { %s } WHERE { %s FILTER (?kb = <%s>) } ",
this.metaGraphPattern.getPattern(), this.metaGraphPattern.getPattern(), kb.toString());
UpdateRequest updateRequest = UpdateFactory.create(query);
UpdateAction.execute(updateRequest, this.model);

Expand All @@ -227,8 +240,8 @@ public void fetchInitialData() {
try {
// using the BindingSet#generateModel() helper method, we can combine the graph
// pattern and the bindings for its variables into a valid RDF Model.
this.model = eu.knowledge.engine.smartconnector.impl.Util
.generateModel(this.aKI.getPattern(), askResult.getBindings());
this.model = eu.knowledge.engine.smartconnector.impl.Util.generateModel(this.aKI.getPattern(),
askResult.getBindings());
this.model.setNsPrefixes(this.prefixes);
// when result available (and the config is enabled), we print the
// knowledge bases to the console.
Expand Down Expand Up @@ -316,4 +329,15 @@ public void close() {
public Model getModel() {
return model;
}

public static String getConfigProperty(String key, String defaultValue) {
// We might replace this with something a bit more fancy in the future...
String value = System.getenv(key);
if (value == null) {
value = defaultValue;
LOG.info("No value for the configuration parameter '" + key + "' was provided, using the default value '"
+ defaultValue + "'");
}
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ public void getSCOverview(
}
}

@GET
@Path("/reload")
@Operation(summary = "Manually reload the admin-ui's smart connectors within the network. This is sometimes necessary when the initial load did not pick up all SCs correctly.")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "If the SC were reloaded."),
@ApiResponse(responseCode = "500", description = "If a problem occurred.") })
public void reloadSCs() {
AdminUI.newInstance(false).fetchInitialData();
}

private eu.knowledge.engine.admin.model.SmartConnector[] findAndAddConnections(SmartConnector[] smartConnectors) {

Set<KnowledgeInteractionInfo> allRelevantKnowledgeInteractions = new HashSet<>();
Expand Down

0 comments on commit 954ca4b

Please sign in to comment.