From aa8db80f35f271da731e1ade85f78f22585bfdf3 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Fri, 23 Jun 2023 12:54:03 +0200 Subject: [PATCH 01/28] [New] Initial implementation of rdf4j update module --- doc/scripts/myscript.sms.ttl | 32 ++++++++ doc/scripts/updatescript.sms.ttl | 45 +++++++++++ .../spipes/modules/Rdf4jUpdateModule.java | 78 +++++++++++++++++++ .../spipes/modules/Rdf4jUpdateModuleTest.java | 14 ++++ 4 files changed, 169 insertions(+) create mode 100644 doc/scripts/myscript.sms.ttl create mode 100644 doc/scripts/updatescript.sms.ttl create mode 100644 s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java create mode 100644 s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java diff --git a/doc/scripts/myscript.sms.ttl b/doc/scripts/myscript.sms.ttl new file mode 100644 index 00000000..d83553c2 --- /dev/null +++ b/doc/scripts/myscript.sms.ttl @@ -0,0 +1,32 @@ +# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/my-script +# imports: http://onto.fel.cvut.cz/ontologies/s-pipes-lib + +@prefix : . +@prefix doc: . +@prefix kbss-module: . +@prefix km-sesame: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sm: . +@prefix sml: . +@prefix sp: . +@prefix spif: . +@prefix spin: . +@prefix spl: . +@prefix xsd: . + + + a owl:Ontology ; + owl:imports ; +. + +:new-function + a sm:Function ; + sm:returnModule :new-function_Return ; +. +:new-function_Return + a sml:ReturnRDF ; + sml:serialization sml:JSONLD ; + rdfs:label "Return greeting statement" ; +. \ No newline at end of file diff --git a/doc/scripts/updatescript.sms.ttl b/doc/scripts/updatescript.sms.ttl new file mode 100644 index 00000000..769cce91 --- /dev/null +++ b/doc/scripts/updatescript.sms.ttl @@ -0,0 +1,45 @@ +# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/update-script +# imports: http://onto.fel.cvut.cz/ontologies/s-pipes-lib + +@prefix : . +@prefix doc: . +@prefix kbss: . +@prefix km-sesame: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sm: . +@prefix sml: . +@prefix sp: . +@prefix spif: . +@prefix spin: . +@prefix spl: . +@prefix xsd: . + + + a owl:Ontology ; + owl:imports ; +. + +:update + a kbss:rdf4j-update ; + sml:updateQuery [ + a sp:Update ; + sp:text """ + INSERT DATA { + "John" . + } + """ ; + ]; + rdfs:label "Make insert update" ; +. + +:func2_Return + a sml:ReturnRDF ; + sml:serialization sml:JSONLD ; + rdfs:label "Return data". + +:func2 + a sm:Function ; + sm:returnModule :func2_Return ; + rdfs:subClassOf sm:Functions . diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java new file mode 100644 index 00000000..38b35cad --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -0,0 +1,78 @@ +package cz.cvut.spipes.modules; + +import cz.cvut.spipes.constants.KBSS_MODULE; +import cz.cvut.spipes.engine.ExecutionContext; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Literal; +import org.eclipse.rdf4j.model.util.Values; +import org.eclipse.rdf4j.query.TupleQuery; +import org.eclipse.rdf4j.query.TupleQueryResult; +import org.eclipse.rdf4j.repository.Repository; +import org.eclipse.rdf4j.repository.RepositoryConnection; +import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; + +import java.io.File; +import java.io.IOException; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + + +public class Rdf4jUpdateModule extends AbstractModule{ + private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); + private static final String TYPE_URI = KBSS_MODULE.getURI()+"rdf4j-update"; + private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI()+"rdf4j"; + Repository queryRepository = new SPARQLRepository("http://localhost:8080/rdf4j-server/repositories/1"); + Repository updateRepository = new SPARQLRepository("http://localhost:8080/rdf4j-server/repositories/1/statements"); + + private static void setLogger(){ + logger.setLevel(Level.ALL); + logger.setUseParentHandlers(false); + FileHandler fh; + boolean dirCreated = new File("./LOGS/").mkdirs(); + try { + fh = new FileHandler("./LOGS/testlogs.txt"); + }catch (IOException e){ + return; + } + fh.setFormatter(new SimpleFormatter()); + logger.addHandler(fh); + } + + @Override + ExecutionContext executeSelf() { + setLogger(); + logger.info("executeSelf entered"); + insertQuery(); + selectQuery("SELECT* WHERE{ ?s ?p ?o }"); + return this.executionContext; + } + + void selectQuery(String query){ + RepositoryConnection connection = queryRepository.getConnection(); + TupleQuery tupleQuery = connection.prepareTupleQuery(query); + TupleQueryResult tupleQueryResult = tupleQuery.evaluate(); + while(tupleQueryResult.hasNext()){ + System.out.println(tupleQueryResult.next()); + } + } + + void insertQuery(){ + RepositoryConnection connection = updateRepository.getConnection(); + IRI john = Values.iri("http://example.org/people/john"); + IRI name = Values.iri("http://example.org/ontology/name"); + Literal johnName = Values.literal("John"); + connection.add(john,name,johnName); + } + + @Override + public String getTypeURI() { + return TYPE_URI; + } + + @Override + public void loadConfiguration() { + + } +} diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java new file mode 100644 index 00000000..5466a748 --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -0,0 +1,14 @@ +package cz.cvut.spipes.modules; + +import cz.cvut.spipes.engine.ExecutionContext; +import org.junit.jupiter.api.Test; + +class Rdf4jUpdateModuleTest { + + @Test + void executeSelf() { + Rdf4jUpdateModule module = new Rdf4jUpdateModule(); + ExecutionContext newContext = module.executeSelf(); +// System.out.println(newContext.getDefaultModel().listStatements().toList()); + } +} \ No newline at end of file From d459c80a19366e9e3e3c327ad463004ef7708590 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Fri, 23 Jun 2023 13:18:14 +0200 Subject: [PATCH 02/28] [Upd] Refactor --- .../rdf-update/rdf-update.sms.ttl} | 19 ++++++----- doc/scripts/myscript.sms.ttl | 32 ------------------- 2 files changed, 11 insertions(+), 40 deletions(-) rename doc/{scripts/updatescript.sms.ttl => examples/rdf-update/rdf-update.sms.ttl} (74%) delete mode 100644 doc/scripts/myscript.sms.ttl diff --git a/doc/scripts/updatescript.sms.ttl b/doc/examples/rdf-update/rdf-update.sms.ttl similarity index 74% rename from doc/scripts/updatescript.sms.ttl rename to doc/examples/rdf-update/rdf-update.sms.ttl index 769cce91..b1717ca7 100644 --- a/doc/scripts/updatescript.sms.ttl +++ b/doc/examples/rdf-update/rdf-update.sms.ttl @@ -1,7 +1,7 @@ -# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/update-script +# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/rdf-update-example # imports: http://onto.fel.cvut.cz/ontologies/s-pipes-lib -@prefix : . +@prefix : . @prefix doc: . @prefix kbss: . @prefix km-sesame: . @@ -16,13 +16,14 @@ @prefix spl: . @prefix xsd: . - + a owl:Ontology ; owl:imports ; . :update a kbss:rdf4j-update ; + sm:next :update-repository_Return ; sml:updateQuery [ a sp:Update ; sp:text """ @@ -34,12 +35,14 @@ rdfs:label "Make insert update" ; . -:func2_Return +:update-repository_Return a sml:ReturnRDF ; sml:serialization sml:JSONLD ; - rdfs:label "Return data". + rdfs:label "Update repository" ; +. -:func2 +:update-repository a sm:Function ; - sm:returnModule :func2_Return ; - rdfs:subClassOf sm:Functions . + sm:returnModule :update-repository_Return ; + rdfs:subClassOf sm:Functions ; +. \ No newline at end of file diff --git a/doc/scripts/myscript.sms.ttl b/doc/scripts/myscript.sms.ttl deleted file mode 100644 index d83553c2..00000000 --- a/doc/scripts/myscript.sms.ttl +++ /dev/null @@ -1,32 +0,0 @@ -# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/my-script -# imports: http://onto.fel.cvut.cz/ontologies/s-pipes-lib - -@prefix : . -@prefix doc: . -@prefix kbss-module: . -@prefix km-sesame: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sm: . -@prefix sml: . -@prefix sp: . -@prefix spif: . -@prefix spin: . -@prefix spl: . -@prefix xsd: . - - - a owl:Ontology ; - owl:imports ; -. - -:new-function - a sm:Function ; - sm:returnModule :new-function_Return ; -. -:new-function_Return - a sml:ReturnRDF ; - sml:serialization sml:JSONLD ; - rdfs:label "Return greeting statement" ; -. \ No newline at end of file From 3bd1e141a15ae04f8b9fe1d83fc6b5c8aef10c35 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Fri, 23 Jun 2023 13:29:16 +0200 Subject: [PATCH 03/28] [Fix] Disable failing test --- .../test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 5466a748..6e7ee210 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -1,11 +1,13 @@ package cz.cvut.spipes.modules; import cz.cvut.spipes.engine.ExecutionContext; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; class Rdf4jUpdateModuleTest { @Test + @Disabled void executeSelf() { Rdf4jUpdateModule module = new Rdf4jUpdateModule(); ExecutionContext newContext = module.executeSelf(); From f1a477f18ccd6791221f8d4c8debe8122949b2b8 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Wed, 28 Jun 2023 19:01:56 +0200 Subject: [PATCH 04/28] [UPD] Implementation of Rdf4j Update Module --- .../java/cz/cvut/spipes/constants/SML.java | 1 + .../spipes/modules/Rdf4jUpdateModule.java | 111 +++++++++++------- .../spipes/modules/Rdf4jUpdateModuleTest.java | 25 ++++ 3 files changed, 93 insertions(+), 44 deletions(-) diff --git a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/SML.java b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/SML.java index c41d1dc5..8ef0e64c 100644 --- a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/SML.java +++ b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/SML.java @@ -21,6 +21,7 @@ protected static final Property property(String local ) public static final Property constructQuery = property("constructQuery"); public static final Property value = property("value"); public static final Property selectQuery = property("selectQuery"); + public static final Property updateQuery = property("updateQuery"); public static final Property sourceFilePath = property("sourceFilePath"); public static final Property url = property("url"); public static final Property targetFilePath = property("targetFilePath"); diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index 38b35cad..b10916a2 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -1,69 +1,82 @@ package cz.cvut.spipes.modules; import cz.cvut.spipes.constants.KBSS_MODULE; +import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; -import org.eclipse.rdf4j.model.IRI; -import org.eclipse.rdf4j.model.Literal; -import org.eclipse.rdf4j.model.util.Values; -import org.eclipse.rdf4j.query.TupleQuery; -import org.eclipse.rdf4j.query.TupleQueryResult; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.eclipse.rdf4j.query.*; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnection; +import org.eclipse.rdf4j.repository.RepositoryException; import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; - -import java.io.File; -import java.io.IOException; -import java.util.logging.FileHandler; -import java.util.logging.Level; +import org.topbraid.spin.vocabulary.SP; +import java.util.List; import java.util.logging.Logger; -import java.util.logging.SimpleFormatter; - public class Rdf4jUpdateModule extends AbstractModule{ private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI()+"rdf4j-update"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI()+"rdf4j"; - Repository queryRepository = new SPARQLRepository("http://localhost:8080/rdf4j-server/repositories/1"); - Repository updateRepository = new SPARQLRepository("http://localhost:8080/rdf4j-server/repositories/1/statements"); + private RepositoryConnection updateConnection; + static final Property P_RDF4J_SERVER_URL = getParameter("p-rdf4j-server-url"); + static final Property P_RDF4J_REPOSITORY_NAME = getParameter("p-rdf4j-repository-name"); + private List updateQueries; - private static void setLogger(){ - logger.setLevel(Level.ALL); - logger.setUseParentHandlers(false); - FileHandler fh; - boolean dirCreated = new File("./LOGS/").mkdirs(); - try { - fh = new FileHandler("./LOGS/testlogs.txt"); - }catch (IOException e){ - return; + private static Property getParameter(final String name) { + return ResourceFactory.createProperty(PROPERTY_PREFIX_URI + "/" + name); + } + private String getUpdateType(String updateString){ + StringBuilder res = new StringBuilder(); + char[] updateArr = updateString.toCharArray(); + for (char c : updateArr) { + if (c == ' ') break; + res.append(c); } - fh.setFormatter(new SimpleFormatter()); - logger.addHandler(fh); + return res.toString(); } @Override ExecutionContext executeSelf() { - setLogger(); - logger.info("executeSelf entered"); - insertQuery(); - selectQuery("SELECT* WHERE{ ?s ?p ?o }"); + for (Resource updateQuery : updateQueries) { + String text = updateQuery.getProperty(SP.text).getLiteral().getString(); + String[] queries = text.split("\\}"); + for (int j = 0; j < queries.length - 1; j++) { + queries[j] = (queries[j] + "}").trim(); + String updateString = queries[j]; + if( (j < queries.length-2) && (getUpdateType((queries[j + 1]+"}").trim()).equals("WHERE")) ){ + updateString += (queries[j+1]+"}").trim(); + j++; + } + makeUpdate(updateString); + } + } + updateConnection.close(); return this.executionContext; } - void selectQuery(String query){ - RepositoryConnection connection = queryRepository.getConnection(); - TupleQuery tupleQuery = connection.prepareTupleQuery(query); - TupleQueryResult tupleQueryResult = tupleQuery.evaluate(); - while(tupleQueryResult.hasNext()){ - System.out.println(tupleQueryResult.next()); + void makeUpdate(String updateString){ + org.eclipse.rdf4j.query.Update prepareUpdate = null; + try { + prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL,updateString); + } + catch (MalformedQueryException e){ + logger.severe("Malformed Query, query text:\n"+updateString); + return; + } + catch (RepositoryException e){ + logger.severe("Repository exception\n"+e.getMessage()); + return; + } + try { + assert prepareUpdate != null; + prepareUpdate.execute(); + logger.info("Update executed"); + } + catch (UpdateExecutionException e){ + logger.severe("Update execution exception, query text:\n"+updateString+"\n"+e.getMessage()); } - } - - void insertQuery(){ - RepositoryConnection connection = updateRepository.getConnection(); - IRI john = Values.iri("http://example.org/people/john"); - IRI name = Values.iri("http://example.org/ontology/name"); - Literal johnName = Values.literal("John"); - connection.add(john,name,johnName); } @Override @@ -73,6 +86,16 @@ public String getTypeURI() { @Override public void loadConfiguration() { - + String rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); + String rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); + Repository updateRepository = new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements"); + updateQueries = getResourcesByProperty(SML.updateQuery); + try { + updateConnection = updateRepository.getConnection(); + logger.info("Connection created for repository "+rdf4jRepositoryName); + } + catch (RepositoryException e){ + logger.severe("Repository exception\n"+e.getMessage()); + } } } diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 6e7ee210..9a4fde22 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -1,6 +1,8 @@ package cz.cvut.spipes.modules; import cz.cvut.spipes.engine.ExecutionContext; +import cz.cvut.spipes.engine.ExecutionContextFactory; +import org.apache.jena.rdf.model.*; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -13,4 +15,27 @@ void executeSelf() { ExecutionContext newContext = module.executeSelf(); // System.out.println(newContext.getDefaultModel().listStatements().toList()); } + + @Test + @Disabled + public void testUpdateEmpty() { + final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); + + final Model updateModel = ModelFactory.createDefaultModel(); + final Property resource = ResourceFactory.createProperty("http://a"); + updateModel.add(resource, resource, resource); + + final ExecutionContext executionContext = ExecutionContextFactory.createContext(updateModel); + + final Model model = ModelFactory.createDefaultModel(); + final Resource root = model.createResource(); + model.add(root, Rdf4jDeployModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); + model.add(root, Rdf4jDeployModule.P_RDF4J_REPOSITORY_NAME, "1"); + + moduleRdf4j.setConfigurationResource(root); + + // TODO: currently running server is needed; + moduleRdf4j.setInputContext(executionContext); + moduleRdf4j.execute(); + } } \ No newline at end of file From 0662f82b3794179ae6a84e463fbc16c506ef5ee8 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Wed, 28 Jun 2023 19:08:10 +0200 Subject: [PATCH 05/28] [UPD] Update example for rdf4j update module --- doc/examples/rdf-update/rdf-update.sms.ttl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/examples/rdf-update/rdf-update.sms.ttl b/doc/examples/rdf-update/rdf-update.sms.ttl index b1717ca7..ffcafbae 100644 --- a/doc/examples/rdf-update/rdf-update.sms.ttl +++ b/doc/examples/rdf-update/rdf-update.sms.ttl @@ -15,6 +15,7 @@ @prefix spin: . @prefix spl: . @prefix xsd: . +@prefix rdf4j: . a owl:Ontology ; @@ -28,10 +29,20 @@ a sp:Update ; sp:text """ INSERT DATA { - "John" . + "John" . + "Alice" . + "Bob" . + } + DELETE { + ?s "John" . + } + WHERE { + ?s "John" . } """ ; ]; + rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; + rdf4j:p-rdf4j-repository-name "1" ; rdfs:label "Make insert update" ; . From d1589accc4f7fbd7932686dc9c851d021c32c31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bla=C5=A1ko?= Date: Thu, 29 Jun 2023 12:20:15 +0200 Subject: [PATCH 06/28] Add link to rdf4j example --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 048bbc0f..1ce1c40a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ SPipes loads pipelines by recursive traversal of configured directories, searchi SPipes script construction, execution, and execution history tracking is explained in [Hello world example](doc/examples/hello-world/hello-world.md). Script debugging is explained in [skosify example](doc/examples/skosify/skosify.md). +Woring with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-example/rdf4j-update.md) Constraint validation is described in [constraint validation example](doc/examples/constraint-validation/constraint-validation.md). From e4da8cb63cdae6e2804133cf76e270a330efd25a Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Thu, 29 Jun 2023 12:22:05 +0200 Subject: [PATCH 07/28] [Upd] Partial update toward meaningful example of rdf4j update x --- README.md | 2 +- .../rdf4j-update.sms.ttl} | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) rename doc/examples/{rdf-update/rdf-update.sms.ttl => rdf4j-update/rdf4j-update.sms.ttl} (77%) diff --git a/README.md b/README.md index 1ce1c40a..44533ef6 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ SPipes loads pipelines by recursive traversal of configured directories, searchi SPipes script construction, execution, and execution history tracking is explained in [Hello world example](doc/examples/hello-world/hello-world.md). Script debugging is explained in [skosify example](doc/examples/skosify/skosify.md). -Woring with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-example/rdf4j-update.md) +Woring with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-update/rdf4j-update.md) Constraint validation is described in [constraint validation example](doc/examples/constraint-validation/constraint-validation.md). diff --git a/doc/examples/rdf-update/rdf-update.sms.ttl b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl similarity index 77% rename from doc/examples/rdf-update/rdf-update.sms.ttl rename to doc/examples/rdf4j-update/rdf4j-update.sms.ttl index ffcafbae..777a7937 100644 --- a/doc/examples/rdf-update/rdf-update.sms.ttl +++ b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl @@ -28,17 +28,17 @@ sml:updateQuery [ a sp:Update ; sp:text """ - INSERT DATA { - "John" . - "Alice" . - "Bob" . - } - DELETE { - ?s "John" . - } - WHERE { - ?s "John" . - } +DELETE { + ?oldAge . +} +INSERT { + ?newAge . +} WHERE { + OPTIONAL { + ?oldAge . + } + BIND(COALESCE(?oldAge+1, 1) as ?newAge) +} """ ; ]; rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; From 19b1dfabba963fc1cdcf5a6d07a2465fdc2220f6 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Thu, 29 Jun 2023 12:26:16 +0200 Subject: [PATCH 08/28] [New] Initial web page about rdf4j update example --- doc/examples/rdf4j-update/rdf4j-update.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 doc/examples/rdf4j-update/rdf4j-update.md diff --git a/doc/examples/rdf4j-update/rdf4j-update.md b/doc/examples/rdf4j-update/rdf4j-update.md new file mode 100644 index 00000000..f6e53e43 --- /dev/null +++ b/doc/examples/rdf4j-update/rdf4j-update.md @@ -0,0 +1,5 @@ +# RDF4J update example + +RDF4J update example explains how to update RDF4J repository. + +## Introduction \ No newline at end of file From 6752bcace73a25ab610c37f5ad364652a2eb77e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bla=C5=A1ko?= Date: Thu, 29 Jun 2023 12:26:53 +0200 Subject: [PATCH 09/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44533ef6..ba785383 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ SPipes loads pipelines by recursive traversal of configured directories, searchi SPipes script construction, execution, and execution history tracking is explained in [Hello world example](doc/examples/hello-world/hello-world.md). Script debugging is explained in [skosify example](doc/examples/skosify/skosify.md). -Woring with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-update/rdf4j-update.md) +Working with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-update/rdf4j-update.md). Constraint validation is described in [constraint validation example](doc/examples/constraint-validation/constraint-validation.md). From 213dc3b5c2254b30ccdca94ccb34908281d82191 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Thu, 29 Jun 2023 13:15:39 +0200 Subject: [PATCH 10/28] [Fix] Fix test and parsing of rdf4j update module --- .../spipes/modules/Rdf4jUpdateModule.java | 97 +++++++++++-------- .../spipes/modules/Rdf4jUpdateModuleTest.java | 48 ++++----- 2 files changed, 82 insertions(+), 63 deletions(-) diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index b10916a2..eece7aa5 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -3,79 +3,97 @@ import cz.cvut.spipes.constants.KBSS_MODULE; import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; +import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; -import org.eclipse.rdf4j.query.*; +import org.apache.jena.vocabulary.RDF; +import org.eclipse.rdf4j.query.MalformedQueryException; +import org.eclipse.rdf4j.query.QueryLanguage; +import org.eclipse.rdf4j.query.UpdateExecutionException; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnection; import org.eclipse.rdf4j.repository.RepositoryException; import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; import org.topbraid.spin.vocabulary.SP; + import java.util.List; import java.util.logging.Logger; -public class Rdf4jUpdateModule extends AbstractModule{ +public class Rdf4jUpdateModule extends AbstractModule { private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); - private static final String TYPE_URI = KBSS_MODULE.getURI()+"rdf4j-update"; - private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI()+"rdf4j"; + private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-update"; + private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; private RepositoryConnection updateConnection; + + /** + * URL of the Rdf4j server + */ static final Property P_RDF4J_SERVER_URL = getParameter("p-rdf4j-server-url"); + private String rdf4jServerURL; + + /** + * Rdf4j repository ID + */ static final Property P_RDF4J_REPOSITORY_NAME = getParameter("p-rdf4j-repository-name"); + private String rdf4jRepositoryName; + + public String getRdf4jServerURL() { + return rdf4jServerURL; + } + + public void setRdf4jServerURL(String rdf4jServerURL) { + this.rdf4jServerURL = rdf4jServerURL; + } + + public String getRdf4jRepositoryName() { + return rdf4jRepositoryName; + } + + public void setRdf4jRepositoryName(String rdf4jRepositoryName) { + this.rdf4jRepositoryName = rdf4jRepositoryName; + } + private List updateQueries; + public static Resource createUpdateQueryResource(Model model, String updateQuery) { + return + model.createResource() + .addProperty(RDF.type, SML.updateQuery) + .addProperty(SP.text, ResourceFactory.createPlainLiteral(updateQuery)); + } + private static Property getParameter(final String name) { return ResourceFactory.createProperty(PROPERTY_PREFIX_URI + "/" + name); } - private String getUpdateType(String updateString){ - StringBuilder res = new StringBuilder(); - char[] updateArr = updateString.toCharArray(); - for (char c : updateArr) { - if (c == ' ') break; - res.append(c); - } - return res.toString(); - } @Override ExecutionContext executeSelf() { - for (Resource updateQuery : updateQueries) { - String text = updateQuery.getProperty(SP.text).getLiteral().getString(); - String[] queries = text.split("\\}"); - for (int j = 0; j < queries.length - 1; j++) { - queries[j] = (queries[j] + "}").trim(); - String updateString = queries[j]; - if( (j < queries.length-2) && (getUpdateType((queries[j + 1]+"}").trim()).equals("WHERE")) ){ - updateString += (queries[j+1]+"}").trim(); - j++; - } - makeUpdate(updateString); - } + for (Resource updateQueryResource : updateQueries) { + String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); + makeUpdate(updateQuery); } updateConnection.close(); return this.executionContext; } - void makeUpdate(String updateString){ + void makeUpdate(String updateString) { org.eclipse.rdf4j.query.Update prepareUpdate = null; try { - prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL,updateString); - } - catch (MalformedQueryException e){ - logger.severe("Malformed Query, query text:\n"+updateString); + prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); + } catch (MalformedQueryException e) { + logger.severe("Malformed Query, query text:\n" + updateString); return; - } - catch (RepositoryException e){ - logger.severe("Repository exception\n"+e.getMessage()); + } catch (RepositoryException e) { + logger.severe("Repository exception\n" + e.getMessage()); return; } try { assert prepareUpdate != null; prepareUpdate.execute(); logger.info("Update executed"); - } - catch (UpdateExecutionException e){ - logger.severe("Update execution exception, query text:\n"+updateString+"\n"+e.getMessage()); + } catch (UpdateExecutionException e) { + logger.severe("Update execution exception, query text:\n" + updateString + "\n" + e.getMessage()); } } @@ -92,10 +110,9 @@ public void loadConfiguration() { updateQueries = getResourcesByProperty(SML.updateQuery); try { updateConnection = updateRepository.getConnection(); - logger.info("Connection created for repository "+rdf4jRepositoryName); - } - catch (RepositoryException e){ - logger.severe("Repository exception\n"+e.getMessage()); + logger.info("Connection created for repository " + rdf4jRepositoryName); + } catch (RepositoryException e) { + logger.severe("Repository exception\n" + e.getMessage()); } } } diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 9a4fde22..7f23a147 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -1,41 +1,43 @@ package cz.cvut.spipes.modules; +import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; import cz.cvut.spipes.engine.ExecutionContextFactory; -import org.apache.jena.rdf.model.*; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.util.FileUtils; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; class Rdf4jUpdateModuleTest { - @Test - @Disabled - void executeSelf() { - Rdf4jUpdateModule module = new Rdf4jUpdateModule(); - ExecutionContext newContext = module.executeSelf(); -// System.out.println(newContext.getDefaultModel().listStatements().toList()); - } + private static String query = "DELETE {\n" + + "\t ?oldAge .\n" + + "}\n" + + "INSERT {\n" + + "\t ?newAge .\n" + + "} WHERE {\n" + + " OPTIONAL {\n" + + " ?oldAge .\n" + + " }\n" + + " BIND(COALESCE(?oldAge+1, 1) as ?newAge)\n" + + "}"; @Test @Disabled public void testUpdateEmpty() { - final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); - - final Model updateModel = ModelFactory.createDefaultModel(); - final Property resource = ResourceFactory.createProperty("http://a"); - updateModel.add(resource, resource, resource); - - final ExecutionContext executionContext = ExecutionContextFactory.createContext(updateModel); - - final Model model = ModelFactory.createDefaultModel(); - final Resource root = model.createResource(); - model.add(root, Rdf4jDeployModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); - model.add(root, Rdf4jDeployModule.P_RDF4J_REPOSITORY_NAME, "1"); + final ExecutionContext inputExecutionContext = ExecutionContextFactory.createEmptyContext(); + Model configModel = ModelFactory.createDefaultModel(); + final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); + final Resource root = configModel.createResource(); + configModel.add(root, Rdf4jDeployModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); + configModel.add(root, Rdf4jDeployModule.P_RDF4J_REPOSITORY_NAME, "mb-test"); + configModel.add(root, SML.updateQuery, Rdf4jUpdateModule.createUpdateQueryResource(configModel, query)); + configModel.write(System.out, FileUtils.langTurtle, null); moduleRdf4j.setConfigurationResource(root); - - // TODO: currently running server is needed; - moduleRdf4j.setInputContext(executionContext); + moduleRdf4j.setInputContext(inputExecutionContext); moduleRdf4j.execute(); } } \ No newline at end of file From 515ffc6d9bf65d4dbbac8b8041584b7c611c8b58 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Thu, 29 Jun 2023 14:07:32 +0200 Subject: [PATCH 11/28] [Upd] Full example script for rdf4j update Does not work yet. --- doc/examples/rdf4j-update/rdf4j-update.sms.ttl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl index 777a7937..fbe29161 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl +++ b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl @@ -22,6 +22,14 @@ owl:imports ; . +:create-repository + a kbss:rdf4j-create-repository ; + rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; + rdf4j:p-rdf4j-repository-name "test-update" ; + rdf4j:p-rdf4j-ignore-if-exists "true" ; + sm:next :update ; +. + :update a kbss:rdf4j-update ; sm:next :update-repository_Return ; @@ -42,7 +50,7 @@ INSERT { """ ; ]; rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; - rdf4j:p-rdf4j-repository-name "1" ; + rdf4j:p-rdf4j-repository-name "test-update" ; rdfs:label "Make insert update" ; . From 39ec87f05bd057de2ae039b192f60d380e209b91 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Sun, 2 Jul 2023 13:53:38 +0200 Subject: [PATCH 12/28] [New] Initial implementation of rdf4j create repository module --- .../modules/Rdf4jCreateRepositoryModule.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java new file mode 100644 index 00000000..17b49859 --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java @@ -0,0 +1,90 @@ +package cz.cvut.spipes.modules; + +import cz.cvut.spipes.constants.KBSS_MODULE; +import cz.cvut.spipes.engine.ExecutionContext; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.ResourceFactory; +import org.eclipse.rdf4j.repository.config.RepositoryConfig; +import org.eclipse.rdf4j.repository.manager.RemoteRepositoryManager; +import org.eclipse.rdf4j.repository.manager.RepositoryManager; +import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig; +import org.eclipse.rdf4j.sail.nativerdf.config.NativeStoreConfig; + +import java.util.Objects; +import java.util.logging.Logger; + +public class Rdf4jCreateRepositoryModule extends AbstractModule { + private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); + private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-create-repository"; + private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; + + /** + * URL of the Rdf4j server + */ + static final Property P_RDF4J_SERVER_URL = getParameter("p-rdf4j-server-url"); + private String rdf4jServerURL; + + /** + * Rdf4j repository ID + */ + static final Property P_RDF4J_REPOSITORY_NAME = getParameter("p-rdf4j-repository-name"); + private String rdf4jRepositoryName; + + /** + * Don't try to create new repository if it already exists + */ + static final Property P_RDF4J_IGNORE_IF_EXISTS = getParameter("p-rdf4j-ignore-if-exists"); + private boolean rdf4jIgnoreIfExists; + + public String getRdf4jServerURL() { + return rdf4jServerURL; + } + + public void setRdf4jServerURL(String rdf4jServerURL) { + this.rdf4jServerURL = rdf4jServerURL; + } + + public String getRdf4jRepositoryName() { + return rdf4jRepositoryName; + } + + public void setRdf4jRepositoryName(String rdf4jRepositoryName) { + this.rdf4jRepositoryName = rdf4jRepositoryName; + } + + private static Property getParameter(final String name) { + return ResourceFactory.createProperty(PROPERTY_PREFIX_URI + "/" + name); + } + + @Override + ExecutionContext executeSelf() { + NativeStoreConfig nativeStoreConfig = new NativeStoreConfig(); + SailRepositoryConfig sailRepositoryConfig = new SailRepositoryConfig(nativeStoreConfig); + + RepositoryManager repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); + repositoryManager.init(); + + if(rdf4jIgnoreIfExists && repositoryManager.hasRepositoryConfig(rdf4jRepositoryName)){ + logger.info("Repository \""+rdf4jRepositoryName+"\" already exists"); + return executionContext; + } + + RepositoryConfig repositoryConfig = new RepositoryConfig(rdf4jRepositoryName,sailRepositoryConfig); + repositoryManager.addRepositoryConfig(repositoryConfig); + repositoryManager.getRepository(rdf4jRepositoryName).init(); + + return executionContext; + } + + @Override + public String getTypeURI() { + return TYPE_URI; + } + + @Override + public void loadConfiguration() { + rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); + rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); + rdf4jIgnoreIfExists = (Objects.equals(getEffectiveValue(P_RDF4J_IGNORE_IF_EXISTS).asLiteral().getString(), "true")); + } +} From 8ce7be68247180c33c9c60f9974c57b1bc963dfb Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Sun, 2 Jul 2023 14:24:58 +0200 Subject: [PATCH 13/28] [Upd] Update web page about rdf4j update module --- doc/examples/rdf4j-update/rdf4j-update.md | 68 ++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.md b/doc/examples/rdf4j-update/rdf4j-update.md index f6e53e43..cd57a2fe 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.md +++ b/doc/examples/rdf4j-update/rdf4j-update.md @@ -2,4 +2,70 @@ RDF4J update example explains how to update RDF4J repository. -## Introduction \ No newline at end of file +## Introduction + +This example contains script *rdf4j-update.sms.ttl* that contain one pipeline. It creates RDF4J repository and performs update query. For more details about script construction and execution you can see [hello-world-example](https://github.com/kbss-cvut/s-pipes/blob/main/doc/examples/hello-world/hello-world.md). + +## Script structure + +Script performs following steps: +1) Creates RDF4J repository using `kbss:rdf4j-create-repository` module. Repository is specified by parameters `rdf4j:p-rdf4j-server-url` and `rdf4j:p-rdf4j-repository-name`. Parameter `rdf4j:p-rdf4j-ignore-if-exists` defines behavior of the module in case when defined repository already exists: +in case if it is set to be "true", module will not do anything if repository with given ID already exists on the server. + + + :create-repository + a kbss:rdf4j-create-repository ; + rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; + rdf4j:p-rdf4j-repository-name "test-update" ; + rdf4j:p-rdf4j-ignore-if-exists "true" ; + sm:next :update ; + . + +2) Perform an update on repository using `a kbss:rdf4j-update` module. Repository is defined in the same way as in `:create-repository`. Update query is set by string in `sp:text` section. + + + :update + a kbss:rdf4j-update ; + sm:next :update-repository_Return ; + sml:updateQuery [ + a sp:Update ; + sp:text """ + DELETE { + ?oldAge . + } + INSERT { + ?newAge . + } WHERE { + OPTIONAL { + ?oldAge . + } + BIND(COALESCE(?oldAge+1, 1) as ?newAge) + } + """ ; + ]; + rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; + rdf4j:p-rdf4j-repository-name "test-update" ; + rdfs:label "Make insert update" ; + . + +## Script execution + +Let's assume that SPipes web application is running at `http://localhost:8080/s-pipes`. We can call the *pipeline* with: + + http://localhost:8080/s-pipes/service?_pId=update-repository + +Note, that rdf4j server should be running on the URL that is specified in script (`http://localhost:8080/rdf4j-server/` for example). +You can see following logs while execution: + + [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### create-repository + ... + INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Server url: http://localhost:8080/rdf4j-server/ Repository name: test-update Ignore flag: true + INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists + ... + [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### Make insert update + ... + INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.loadConfiguration Connection created for repository test-update + INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.makeUpdate Update executed + +This log will occur when Ignore flag is set to true and repository already exists: +`INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists` \ No newline at end of file From 9c9bf010e65c7fd039ec0415f93dcc564e40b027 Mon Sep 17 00:00:00 2001 From: Rodion Nazarov <130922166+rodionnv@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:47:33 +0200 Subject: [PATCH 14/28] [Upd] Apply suggestions for rdf4j-update.md from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Miroslav Blaško --- doc/examples/rdf4j-update/rdf4j-update.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.md b/doc/examples/rdf4j-update/rdf4j-update.md index cd57a2fe..9c52c6ae 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.md +++ b/doc/examples/rdf4j-update/rdf4j-update.md @@ -4,7 +4,7 @@ RDF4J update example explains how to update RDF4J repository. ## Introduction -This example contains script *rdf4j-update.sms.ttl* that contain one pipeline. It creates RDF4J repository and performs update query. For more details about script construction and execution you can see [hello-world-example](https://github.com/kbss-cvut/s-pipes/blob/main/doc/examples/hello-world/hello-world.md). +This example explains script [rdf4j-update.sms.ttl](./rdf4j-update.sms.ttl]) that contain one pipeline. It creates RDF4J repository and performs update query. For more details about script construction and execution you can see [hello-world-example](../hello-world/hello-world.md). ## Script structure @@ -21,10 +21,10 @@ in case if it is set to be "true", module will not do anything if repository wit sm:next :update ; . -2) Perform an update on repository using `a kbss:rdf4j-update` module. Repository is defined in the same way as in `:create-repository`. Update query is set by string in `sp:text` section. +2) Perform an update on repository using `kbss:rdf4j-update` module. Repository is defined in the same way as in `:create-repository`. Update query is set by string in `sp:text` section. - :update + :update-repository a kbss:rdf4j-update ; sm:next :update-repository_Return ; sml:updateQuery [ @@ -45,7 +45,6 @@ in case if it is set to be "true", module will not do anything if repository wit ]; rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; rdf4j:p-rdf4j-repository-name "test-update" ; - rdfs:label "Make insert update" ; . ## Script execution @@ -59,13 +58,13 @@ You can see following logs while execution: [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### create-repository ... - INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Server url: http://localhost:8080/rdf4j-server/ Repository name: test-update Ignore flag: true + INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Server url: http://localhost:8080/rdf4j-server/, Repository name: test-update, Ignore if repository exists: true INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists ... [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### Make insert update ... - INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.loadConfiguration Connection created for repository test-update - INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.makeUpdate Update executed + DEBUG [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.loadConfiguration Connected to repository test-update + DEBUG [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.makeUpdate Update successful This log will occur when Ignore flag is set to true and repository already exists: `INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists` \ No newline at end of file From f235b5e3819d805f85f0ac72a30097cc196ec806 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Mon, 3 Jul 2023 17:57:07 +0200 Subject: [PATCH 15/28] [Upd] Update modules Rdf4jUpdateModule, Rdf4jCreateRepositoryModule and rdf4j-udpate script to match web page about rdf4j modules --- doc/examples/rdf4j-update/rdf4j-update.md | 10 +++++----- .../rdf4j-update/rdf4j-update.sms.ttl | 5 ++--- .../modules/Rdf4jCreateRepositoryModule.java | 6 ++++-- .../spipes/modules/Rdf4jUpdateModule.java | 20 ++++++++++--------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.md b/doc/examples/rdf4j-update/rdf4j-update.md index 9c52c6ae..60457757 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.md +++ b/doc/examples/rdf4j-update/rdf4j-update.md @@ -58,13 +58,13 @@ You can see following logs while execution: [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### create-repository ... - INFO [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Server url: http://localhost:8080/rdf4j-server/, Repository name: test-update, Ignore if repository exists: true - INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists + [http-nio-8080-exec-1] INFO c.c.s.m.Rdf4jUpdateModule - Server url: http://localhost:8080/rdf4j-server/, Repsitory name: test-update, Ignore if repository exist: true + [http-nio-8080-exec-6] INFO c.c.s.m.Rdf4jUpdateModule - Repository "test-update" already exists ... [http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### Make insert update ... - DEBUG [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.loadConfiguration Connected to repository test-update - DEBUG [http-nio-8080-exec-7] cz.cvut.spipes.modules.Rdf4jUpdateModule.makeUpdate Update successful + [http-nio-8080-exec-7] DEBUG c.c.s.m.Rdf4jUpdateModule - Connected to test-update + [http-nio-8080-exec-7] DEBUG c.c.s.m.Rdf4jUpdateModule - Update successful This log will occur when Ignore flag is set to true and repository already exists: -`INFO [http-nio-8080-exec-6] cz.cvut.spipes.modules.Rdf4jCreateRepositoryModule.executeSelf Repository "test-update" already exists` \ No newline at end of file +`[http-nio-8080-exec-6] INFO c.c.s.m.Rdf4jUpdateModule - Repository "test-update" already exists` \ No newline at end of file diff --git a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl index fbe29161..fafda440 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl +++ b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl @@ -27,10 +27,10 @@ rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; rdf4j:p-rdf4j-repository-name "test-update" ; rdf4j:p-rdf4j-ignore-if-exists "true" ; - sm:next :update ; + sm:next :update-repository ; . -:update +:update-repository a kbss:rdf4j-update ; sm:next :update-repository_Return ; sml:updateQuery [ @@ -51,7 +51,6 @@ INSERT { ]; rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; rdf4j:p-rdf4j-repository-name "test-update" ; - rdfs:label "Make insert update" ; . :update-repository_Return diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java index 17b49859..5fe41006 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java @@ -11,10 +11,11 @@ import org.eclipse.rdf4j.sail.nativerdf.config.NativeStoreConfig; import java.util.Objects; -import java.util.logging.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Rdf4jCreateRepositoryModule extends AbstractModule { - private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); + private static final Logger logger = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-create-repository"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; @@ -63,6 +64,7 @@ ExecutionContext executeSelf() { RepositoryManager repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); repositoryManager.init(); + logger.info("Server url: "+rdf4jServerURL+", Repsitory name: "+rdf4jRepositoryName+ ", Ignore if repository exist: "+rdf4jIgnoreIfExists); if(rdf4jIgnoreIfExists && repositoryManager.hasRepositoryConfig(rdf4jRepositoryName)){ logger.info("Repository \""+rdf4jRepositoryName+"\" already exists"); diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index eece7aa5..2f442a74 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -10,6 +10,7 @@ import org.apache.jena.vocabulary.RDF; import org.eclipse.rdf4j.query.MalformedQueryException; import org.eclipse.rdf4j.query.QueryLanguage; +import org.eclipse.rdf4j.query.Update; import org.eclipse.rdf4j.query.UpdateExecutionException; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnection; @@ -18,10 +19,11 @@ import org.topbraid.spin.vocabulary.SP; import java.util.List; -import java.util.logging.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Rdf4jUpdateModule extends AbstractModule { - private static final Logger logger = Logger.getLogger(Rdf4jUpdateModule.class.getName()); + private static final Logger logger = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-update"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; private RepositoryConnection updateConnection; @@ -78,22 +80,22 @@ ExecutionContext executeSelf() { } void makeUpdate(String updateString) { - org.eclipse.rdf4j.query.Update prepareUpdate = null; + Update prepareUpdate = null; try { prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); } catch (MalformedQueryException e) { - logger.severe("Malformed Query, query text:\n" + updateString); + logger.error("Malformed Query, query text:\n" + updateString); return; } catch (RepositoryException e) { - logger.severe("Repository exception\n" + e.getMessage()); + logger.error("Repository exception\n" + e.getMessage()); return; } try { assert prepareUpdate != null; prepareUpdate.execute(); - logger.info("Update executed"); + logger.debug("Update successful"); } catch (UpdateExecutionException e) { - logger.severe("Update execution exception, query text:\n" + updateString + "\n" + e.getMessage()); + logger.error("Update execution exception, query text:\n" + updateString + "\n" + e.getMessage()); } } @@ -110,9 +112,9 @@ public void loadConfiguration() { updateQueries = getResourcesByProperty(SML.updateQuery); try { updateConnection = updateRepository.getConnection(); - logger.info("Connection created for repository " + rdf4jRepositoryName); + logger.debug("Connected to " + rdf4jRepositoryName); } catch (RepositoryException e) { - logger.severe("Repository exception\n" + e.getMessage()); + logger.error("Repository exception\n" + e.getMessage()); } } } From b415da3a7623d756cadba65d6549578e03c84c97 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Wed, 5 Jul 2023 14:09:03 +0200 Subject: [PATCH 16/28] [Upd] Add prefix in rdf4-update example --- doc/examples/rdf4j-update/rdf4j-update.sms.ttl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl index fafda440..20ca2c6f 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl +++ b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl @@ -36,14 +36,15 @@ sml:updateQuery [ a sp:Update ; sp:text """ +PREFIX ex-people: DELETE { - ?oldAge . + ex-people:john ex-people:age ?oldAge . } INSERT { - ?newAge . + ex-people:john ex-people:age ?newAge . } WHERE { OPTIONAL { - ?oldAge . + ex-people:john ex-people:age ?oldAge . } BIND(COALESCE(?oldAge+1, 1) as ?newAge) } From 89553883a7c9baeed4b3f93f887cfb57e4d9f5b8 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Wed, 5 Jul 2023 14:18:41 +0200 Subject: [PATCH 17/28] [Upd] Refactor loggers in rdf4j update and create repository modules --- .../modules/Rdf4jCreateRepositoryModule.java | 11 +++++++--- .../spipes/modules/Rdf4jUpdateModule.java | 20 ++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java index 5fe41006..f52ba168 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java @@ -15,7 +15,7 @@ import org.slf4j.LoggerFactory; public class Rdf4jCreateRepositoryModule extends AbstractModule { - private static final Logger logger = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-create-repository"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; @@ -64,10 +64,15 @@ ExecutionContext executeSelf() { RepositoryManager repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); repositoryManager.init(); - logger.info("Server url: "+rdf4jServerURL+", Repsitory name: "+rdf4jRepositoryName+ ", Ignore if repository exist: "+rdf4jIgnoreIfExists); + LOG.info("Server url:{}, Repsitory name:{}, Ignore if repository exist:{}.", + rdf4jServerURL, + rdf4jRepositoryName, + rdf4jIgnoreIfExists); if(rdf4jIgnoreIfExists && repositoryManager.hasRepositoryConfig(rdf4jRepositoryName)){ - logger.info("Repository \""+rdf4jRepositoryName+"\" already exists"); + + LOG.info("Repository \"{}\" already exists", + rdf4jRepositoryName); return executionContext; } diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index 2f442a74..1ee3183c 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory; public class Rdf4jUpdateModule extends AbstractModule { - private static final Logger logger = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-update"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; private RepositoryConnection updateConnection; @@ -84,18 +84,22 @@ void makeUpdate(String updateString) { try { prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); } catch (MalformedQueryException e) { - logger.error("Malformed Query, query text:\n" + updateString); + LOG.error("Malformed Query, query text:\n{}", + updateString); return; } catch (RepositoryException e) { - logger.error("Repository exception\n" + e.getMessage()); + LOG.error("Repository exception\n{}", + e.getMessage()); return; } try { assert prepareUpdate != null; prepareUpdate.execute(); - logger.debug("Update successful"); + LOG.debug("Update successful"); } catch (UpdateExecutionException e) { - logger.error("Update execution exception, query text:\n" + updateString + "\n" + e.getMessage()); + LOG.error("Update execution exception, query text:\n{}\n{}", + updateString, + e.getMessage()); } } @@ -112,9 +116,11 @@ public void loadConfiguration() { updateQueries = getResourcesByProperty(SML.updateQuery); try { updateConnection = updateRepository.getConnection(); - logger.debug("Connected to " + rdf4jRepositoryName); + LOG.debug("Connected to {}", + rdf4jRepositoryName); } catch (RepositoryException e) { - logger.error("Repository exception\n" + e.getMessage()); + LOG.error("Repository exception\n{}", + e.getMessage()); } } } From 1e736e8c981499f87bfb95b3e651e56b2f339be7 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Tue, 18 Jul 2023 15:52:28 +0200 Subject: [PATCH 18/28] [Upd] Refactor --- .../cz/cvut/spipes/modules/RetrievePrefixesModuleTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/s-pipes-core/src/test/java/cz/cvut/spipes/modules/RetrievePrefixesModuleTest.java b/s-pipes-core/src/test/java/cz/cvut/spipes/modules/RetrievePrefixesModuleTest.java index a7bcc42d..955ac64f 100644 --- a/s-pipes-core/src/test/java/cz/cvut/spipes/modules/RetrievePrefixesModuleTest.java +++ b/s-pipes-core/src/test/java/cz/cvut/spipes/modules/RetrievePrefixesModuleTest.java @@ -7,7 +7,6 @@ import org.apache.jena.ontology.OntModel; import org.apache.jena.ontology.OntModelSpec; import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.shared.PrefixMapping; import org.apache.jena.util.FileManager; import org.apache.jena.util.FileUtils; import org.apache.jena.vocabulary.OWL; @@ -52,7 +51,7 @@ void setUp() { } @Test - void testExecuteSelf() { + void executeSelfReturnPrefixes() { given(ontoDocManager.getRegisteredOntologyUris()).willReturn(uri2ontModel.keySet()); uri2ontModel.forEach((key, value) -> { doReturn(value).when(ontoDocManager).getOntology(key); From e0e05919b16935c251a79108d324d071efc17044 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Tue, 18 Jul 2023 16:01:12 +0200 Subject: [PATCH 19/28] [New] Test for ignore-if-exists parameter --- s-pipes-modules/module-rdf4j/pom.xml | 10 ++++++ .../RepositoryAlreadyExistsException.java | 9 +++++ .../modules/Rdf4jCreateRepositoryModule.java | 25 +++++++++++--- .../Rdf4jCreateRepositoryModuleTest.java | 34 +++++++++++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAlreadyExistsException.java create mode 100644 s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModuleTest.java diff --git a/s-pipes-modules/module-rdf4j/pom.xml b/s-pipes-modules/module-rdf4j/pom.xml index 69169b82..f8920ff7 100644 --- a/s-pipes-modules/module-rdf4j/pom.xml +++ b/s-pipes-modules/module-rdf4j/pom.xml @@ -44,6 +44,16 @@ junit-jupiter-api test + + org.mockito + mockito-junit-jupiter + test + + + org.mockito + mockito-core + test + diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAlreadyExistsException.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAlreadyExistsException.java new file mode 100644 index 00000000..6bb40dba --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAlreadyExistsException.java @@ -0,0 +1,9 @@ +package cz.cvut.spipes.exceptions; + +public class RepositoryAlreadyExistsException extends RuntimeException { + + public RepositoryAlreadyExistsException(String repositoryName) { + super("Repository " + repositoryName + " already exists."); + } + +} \ No newline at end of file diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java index f52ba168..0327823c 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java @@ -2,6 +2,7 @@ import cz.cvut.spipes.constants.KBSS_MODULE; import cz.cvut.spipes.engine.ExecutionContext; +import cz.cvut.spipes.exceptions.RepositoryAlreadyExistsException; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.ResourceFactory; import org.eclipse.rdf4j.repository.config.RepositoryConfig; @@ -9,11 +10,11 @@ import org.eclipse.rdf4j.repository.manager.RepositoryManager; import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig; import org.eclipse.rdf4j.sail.nativerdf.config.NativeStoreConfig; - -import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Objects; + public class Rdf4jCreateRepositoryModule extends AbstractModule { private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-create-repository"; @@ -37,6 +38,8 @@ public class Rdf4jCreateRepositoryModule extends AbstractModule { static final Property P_RDF4J_IGNORE_IF_EXISTS = getParameter("p-rdf4j-ignore-if-exists"); private boolean rdf4jIgnoreIfExists; + private RepositoryManager repositoryManager; + public String getRdf4jServerURL() { return rdf4jServerURL; } @@ -53,27 +56,38 @@ public void setRdf4jRepositoryName(String rdf4jRepositoryName) { this.rdf4jRepositoryName = rdf4jRepositoryName; } + public boolean isRdf4jIgnoreIfExists() { + return rdf4jIgnoreIfExists; + } + + public void setRdf4jIgnoreIfExists(boolean rdf4jIgnoreIfExists) { + this.rdf4jIgnoreIfExists = rdf4jIgnoreIfExists; + } + private static Property getParameter(final String name) { return ResourceFactory.createProperty(PROPERTY_PREFIX_URI + "/" + name); } + void setRepositoryManager(RepositoryManager repositoryManager) { + this.repositoryManager = repositoryManager; + } + @Override ExecutionContext executeSelf() { NativeStoreConfig nativeStoreConfig = new NativeStoreConfig(); SailRepositoryConfig sailRepositoryConfig = new SailRepositoryConfig(nativeStoreConfig); - RepositoryManager repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); repositoryManager.init(); LOG.info("Server url:{}, Repsitory name:{}, Ignore if repository exist:{}.", rdf4jServerURL, rdf4jRepositoryName, rdf4jIgnoreIfExists); - if(rdf4jIgnoreIfExists && repositoryManager.hasRepositoryConfig(rdf4jRepositoryName)){ + if((!rdf4jIgnoreIfExists) && repositoryManager.hasRepositoryConfig(rdf4jRepositoryName)){ LOG.info("Repository \"{}\" already exists", rdf4jRepositoryName); - return executionContext; + throw new RepositoryAlreadyExistsException(rdf4jRepositoryName); } RepositoryConfig repositoryConfig = new RepositoryConfig(rdf4jRepositoryName,sailRepositoryConfig); @@ -93,5 +107,6 @@ public void loadConfiguration() { rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); rdf4jIgnoreIfExists = (Objects.equals(getEffectiveValue(P_RDF4J_IGNORE_IF_EXISTS).asLiteral().getString(), "true")); + repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); } } diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModuleTest.java new file mode 100644 index 00000000..b9158ee6 --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModuleTest.java @@ -0,0 +1,34 @@ +package cz.cvut.spipes.modules; + +import cz.cvut.spipes.exceptions.RepositoryAlreadyExistsException; +import org.eclipse.rdf4j.repository.manager.RepositoryManager; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +public class Rdf4jCreateRepositoryModuleTest { + + @Mock + private RepositoryManager repositoryManager; + + @Test + void executeSelfFailsIfRdf4jIgnoreIfExistsIsFalseAndRepositoryExists() { + Rdf4jCreateRepositoryModule rdf4CreateRepositoryModule = new Rdf4jCreateRepositoryModule(); + rdf4CreateRepositoryModule.setRdf4jIgnoreIfExists(false); + rdf4CreateRepositoryModule.setRepositoryManager(repositoryManager); + + + given(repositoryManager.hasRepositoryConfig(any())).willReturn(true); + assertThrows(RepositoryAlreadyExistsException.class, rdf4CreateRepositoryModule::executeSelf); + verify(repositoryManager, times(1)).init(); + } + +} \ No newline at end of file From ed3f3ea445499f451a74686c0355aa4d57b0a2e8 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Tue, 18 Jul 2023 16:28:33 +0200 Subject: [PATCH 20/28] [New] Refactor --- .../exceptions/RepositoryAccessException.java | 8 ++++ .../spipes/modules/Rdf4jUpdateModule.java | 37 +++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAccessException.java diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAccessException.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAccessException.java new file mode 100644 index 00000000..d42e05f2 --- /dev/null +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/exceptions/RepositoryAccessException.java @@ -0,0 +1,8 @@ +package cz.cvut.spipes.exceptions; + +public class RepositoryAccessException extends RuntimeException { + + public RepositoryAccessException(String repositoryName, Throwable cause) { + super("Cannot connect to repository " + repositoryName + ".", cause); + } +} \ No newline at end of file diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index 1ee3183c..219d64ae 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -3,6 +3,7 @@ import cz.cvut.spipes.constants.KBSS_MODULE; import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; +import cz.cvut.spipes.exceptions.RepositoryAccessException; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.Resource; @@ -16,17 +17,16 @@ import org.eclipse.rdf4j.repository.RepositoryConnection; import org.eclipse.rdf4j.repository.RepositoryException; import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.topbraid.spin.vocabulary.SP; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class Rdf4jUpdateModule extends AbstractModule { private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-update"; private static final String PROPERTY_PREFIX_URI = KBSS_MODULE.getURI() + "rdf4j"; - private RepositoryConnection updateConnection; /** * URL of the Rdf4j server @@ -39,6 +39,9 @@ public class Rdf4jUpdateModule extends AbstractModule { */ static final Property P_RDF4J_REPOSITORY_NAME = getParameter("p-rdf4j-repository-name"); private String rdf4jRepositoryName; + private List updateQueries; + + private Repository updateRepository; public String getRdf4jServerURL() { return rdf4jServerURL; @@ -56,8 +59,6 @@ public void setRdf4jRepositoryName(String rdf4jRepositoryName) { this.rdf4jRepositoryName = rdf4jRepositoryName; } - private List updateQueries; - public static Resource createUpdateQueryResource(Model model, String updateQuery) { return model.createResource() @@ -71,15 +72,21 @@ private static Property getParameter(final String name) { @Override ExecutionContext executeSelf() { - for (Resource updateQueryResource : updateQueries) { - String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); - makeUpdate(updateQuery); + try (RepositoryConnection updateConnection = updateRepository.getConnection()) { + LOG.debug("Connected to {}", rdf4jRepositoryName); + + for (Resource updateQueryResource : updateQueries) { + String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); + makeUpdate(updateQuery, updateConnection); + } + } catch (RepositoryException e) { + throw new RepositoryAccessException(rdf4jRepositoryName, e); } - updateConnection.close(); + return this.executionContext; } - void makeUpdate(String updateString) { + void makeUpdate(String updateString, RepositoryConnection updateConnection) { Update prepareUpdate = null; try { prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); @@ -112,15 +119,7 @@ public String getTypeURI() { public void loadConfiguration() { String rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); String rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); - Repository updateRepository = new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements"); + updateRepository = new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements"); updateQueries = getResourcesByProperty(SML.updateQuery); - try { - updateConnection = updateRepository.getConnection(); - LOG.debug("Connected to {}", - rdf4jRepositoryName); - } catch (RepositoryException e) { - LOG.error("Repository exception\n{}", - e.getMessage()); - } } } From fe3b0b2e9f81001d6d502815155a75e933f87751 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Tue, 18 Jul 2023 16:29:13 +0200 Subject: [PATCH 21/28] [New] Test for rdf4j update module (not finished) --- .../java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 7f23a147..0f4a6cda 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -40,4 +40,9 @@ public void testUpdateEmpty() { moduleRdf4j.setInputContext(inputExecutionContext); moduleRdf4j.execute(); } + + void executeSelfExecutesAllUpdateQueries() { + // given(repository.getConnection()).return(connection); + // verify ... ~ updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); + } } \ No newline at end of file From ffe0f3f5ad43f4e8c14c389206ff6aa43055001f Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Thu, 20 Jul 2023 12:41:53 +0200 Subject: [PATCH 22/28] [Upd] Add support of kbss:iterationCount and kbss:onlyIfTripleCountChanges for Rdf4jUpdateModule --- .../rdf4j-update/rdf4j-update.sms.ttl | 2 ++ .../cz/cvut/spipes/constants/KBSS_MODULE.java | 1 + .../spipes/modules/Rdf4jUpdateModule.java | 26 ++++++++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl index 20ca2c6f..9e12d1bf 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.sms.ttl +++ b/doc/examples/rdf4j-update/rdf4j-update.sms.ttl @@ -50,6 +50,8 @@ INSERT { } """ ; ]; + kbss:has-max-iteration-count 5 ; + kbss:only-if-triple-count-changes false; rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ; rdf4j:p-rdf4j-repository-name "test-update" ; . diff --git a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java index b55659fe..bdf554bd 100644 --- a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java +++ b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java @@ -20,6 +20,7 @@ protected static final Property property(String local ) public static final Property is_parse_text = property("is-parse-text"); public static final Property has_max_iteration_count = property("has-max-iteration-count"); public static final Property has_resource_uri = property("has-resource-uri"); + public static final Property only_if_triple_count_changes = property("only-if-triple-count-changes"); /** returns the URI for this schema diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index 219d64ae..6187a063 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -42,6 +42,16 @@ public class Rdf4jUpdateModule extends AbstractModule { private List updateQueries; private Repository updateRepository; + private int iterationCount; + private boolean onlyIfTripleCountChanges; + + public int getIterationCount() { + return iterationCount; + } + + public void setIterationCount(int iterationCount) { + this.iterationCount = iterationCount; + } public String getRdf4jServerURL() { return rdf4jServerURL; @@ -77,7 +87,12 @@ ExecutionContext executeSelf() { for (Resource updateQueryResource : updateQueries) { String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); - makeUpdate(updateQuery, updateConnection); + for(int i = 0;i < iterationCount;i++) { + long oldTriplesCount = updateConnection.size(); + makeUpdate(updateQuery, updateConnection); + long newTriplesCount = updateConnection.size(); + if(onlyIfTripleCountChanges && (newTriplesCount == oldTriplesCount) )break; + } } } catch (RepositoryException e) { throw new RepositoryAccessException(rdf4jRepositoryName, e); @@ -117,8 +132,13 @@ public String getTypeURI() { @Override public void loadConfiguration() { - String rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); - String rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); + rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); + rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); + iterationCount = getPropertyValue(KBSS_MODULE.has_max_iteration_count,1); + onlyIfTripleCountChanges = getPropertyValue(KBSS_MODULE.only_if_triple_count_changes,false); + LOG.debug("Iteration count={}\nOnlyIf...Changes={}" + ,iterationCount + ,onlyIfTripleCountChanges); updateRepository = new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements"); updateQueries = getResourcesByProperty(SML.updateQuery); } From e075f206925207ab87cd39e119118c9ec4de6ea6 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Thu, 20 Jul 2023 20:42:00 +0200 Subject: [PATCH 23/28] [Upd] In Rdf4jCreateRepositoryModule make p-rdf4j-ignore-if-exists false by default and add it in the comment --- .../spipes/modules/Rdf4jCreateRepositoryModule.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java index 0327823c..3de9ea58 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jCreateRepositoryModule.java @@ -15,6 +15,9 @@ import java.util.Objects; +/** + * Module creates native store rdf4j repository on the given server with the given name + */ public class Rdf4jCreateRepositoryModule extends AbstractModule { private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); private static final String TYPE_URI = KBSS_MODULE.getURI() + "rdf4j-create-repository"; @@ -33,7 +36,7 @@ public class Rdf4jCreateRepositoryModule extends AbstractModule { private String rdf4jRepositoryName; /** - * Don't try to create new repository if it already exists + * Don't try to create new repository if it already exists (Default value is false) */ static final Property P_RDF4J_IGNORE_IF_EXISTS = getParameter("p-rdf4j-ignore-if-exists"); private boolean rdf4jIgnoreIfExists; @@ -106,7 +109,12 @@ public String getTypeURI() { public void loadConfiguration() { rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); - rdf4jIgnoreIfExists = (Objects.equals(getEffectiveValue(P_RDF4J_IGNORE_IF_EXISTS).asLiteral().getString(), "true")); + try { + rdf4jIgnoreIfExists = (Objects.equals(getEffectiveValue(P_RDF4J_IGNORE_IF_EXISTS).asLiteral().getString(), "true")); + } + catch (NullPointerException e){ + rdf4jIgnoreIfExists = false; + } repositoryManager = new RemoteRepositoryManager(rdf4jServerURL); } } From 22213003b681decfd0c2ca8b5257d8944dc25a94 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Thu, 20 Jul 2023 20:43:22 +0200 Subject: [PATCH 24/28] [Fix] Fix incorrect implementation, rename parameter --- .../cz/cvut/spipes/constants/KBSS_MODULE.java | 2 +- .../cz/cvut/spipes/modules/Rdf4jUpdateModule.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java index bdf554bd..f634309d 100644 --- a/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java +++ b/s-pipes-core/src/main/java/cz/cvut/spipes/constants/KBSS_MODULE.java @@ -20,7 +20,7 @@ protected static final Property property(String local ) public static final Property is_parse_text = property("is-parse-text"); public static final Property has_max_iteration_count = property("has-max-iteration-count"); public static final Property has_resource_uri = property("has-resource-uri"); - public static final Property only_if_triple_count_changes = property("only-if-triple-count-changes"); + public static final Property stop_iteration_on_stable_triple_count = property("stop-iteration-on-stable-triple-count"); /** returns the URI for this schema diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index 6187a063..bb06873e 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -84,15 +84,14 @@ private static Property getParameter(final String name) { ExecutionContext executeSelf() { try (RepositoryConnection updateConnection = updateRepository.getConnection()) { LOG.debug("Connected to {}", rdf4jRepositoryName); - - for (Resource updateQueryResource : updateQueries) { - String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); - for(int i = 0;i < iterationCount;i++) { - long oldTriplesCount = updateConnection.size(); + for(int i = 0;i < iterationCount;i++) { + long oldTriplesCount = updateConnection.size(); + for (Resource updateQueryResource : updateQueries) { + String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); makeUpdate(updateQuery, updateConnection); - long newTriplesCount = updateConnection.size(); - if(onlyIfTripleCountChanges && (newTriplesCount == oldTriplesCount) )break; } + long newTriplesCount = updateConnection.size(); + if(onlyIfTripleCountChanges && (newTriplesCount == oldTriplesCount) )break; } } catch (RepositoryException e) { throw new RepositoryAccessException(rdf4jRepositoryName, e); @@ -135,7 +134,7 @@ public void loadConfiguration() { rdf4jServerURL = getEffectiveValue(P_RDF4J_SERVER_URL).asLiteral().getString(); rdf4jRepositoryName = getEffectiveValue(P_RDF4J_REPOSITORY_NAME).asLiteral().getString(); iterationCount = getPropertyValue(KBSS_MODULE.has_max_iteration_count,1); - onlyIfTripleCountChanges = getPropertyValue(KBSS_MODULE.only_if_triple_count_changes,false); + onlyIfTripleCountChanges = getPropertyValue(KBSS_MODULE.stop_iteration_on_stable_triple_count,false); LOG.debug("Iteration count={}\nOnlyIf...Changes={}" ,iterationCount ,onlyIfTripleCountChanges); From 7866ad310a2ec582da2a34b58aee820e58a91123 Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Thu, 20 Jul 2023 20:44:08 +0200 Subject: [PATCH 25/28] [Upd] Update documentation of the example to match actual script --- doc/examples/rdf4j-update/rdf4j-update.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/examples/rdf4j-update/rdf4j-update.md b/doc/examples/rdf4j-update/rdf4j-update.md index 60457757..ceef3025 100644 --- a/doc/examples/rdf4j-update/rdf4j-update.md +++ b/doc/examples/rdf4j-update/rdf4j-update.md @@ -30,14 +30,15 @@ in case if it is set to be "true", module will not do anything if repository wit sml:updateQuery [ a sp:Update ; sp:text """ + PREFIX ex-people: DELETE { - ?oldAge . + ex-people:john ex-people:age ?oldAge . } INSERT { - ?newAge . + ex-people:john ex-people:age ?newAge . } WHERE { OPTIONAL { - ?oldAge . + ex-people:john ex-people:age ?oldAge . } BIND(COALESCE(?oldAge+1, 1) as ?newAge) } From 400c00cab62f07c6f83e1fa519666e33e1e1ddab Mon Sep 17 00:00:00 2001 From: "Nazarov, Rodion" Date: Fri, 21 Jul 2023 12:38:29 +0200 Subject: [PATCH 26/28] [New] New test for Rdf4jUpdateModule --- .../spipes/modules/Rdf4jUpdateModule.java | 8 +++- .../spipes/modules/Rdf4jUpdateModuleTest.java | 46 +++++++++++++++---- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index bb06873e..bdf02dfc 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -42,6 +42,7 @@ public class Rdf4jUpdateModule extends AbstractModule { private List updateQueries; private Repository updateRepository; + private Update prepareUpdate; private int iterationCount; private boolean onlyIfTripleCountChanges; @@ -69,6 +70,10 @@ public void setRdf4jRepositoryName(String rdf4jRepositoryName) { this.rdf4jRepositoryName = rdf4jRepositoryName; } + void setUpdateRepository(Repository updateRepository) { + this.updateRepository = updateRepository; + } + public static Resource createUpdateQueryResource(Model model, String updateQuery) { return model.createResource() @@ -101,7 +106,6 @@ ExecutionContext executeSelf() { } void makeUpdate(String updateString, RepositoryConnection updateConnection) { - Update prepareUpdate = null; try { prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); } catch (MalformedQueryException e) { @@ -138,7 +142,7 @@ public void loadConfiguration() { LOG.debug("Iteration count={}\nOnlyIf...Changes={}" ,iterationCount ,onlyIfTripleCountChanges); - updateRepository = new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements"); + if(updateRepository == null)setUpdateRepository(new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements")); updateQueries = getResourcesByProperty(SML.updateQuery); } } diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 0f4a6cda..569bb346 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -1,17 +1,43 @@ package cz.cvut.spipes.modules; +import cz.cvut.spipes.constants.KBSS_MODULE; import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; import cz.cvut.spipes.engine.ExecutionContextFactory; +import org.eclipse.rdf4j.query.QueryLanguage; +import org.eclipse.rdf4j.repository.Repository; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Resource; import org.apache.jena.util.FileUtils; +import org.eclipse.rdf4j.repository.RepositoryConnection; +import org.eclipse.rdf4j.query.Update; +import org.eclipse.rdf4j.repository.http.HTTPUpdate; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) class Rdf4jUpdateModuleTest { + @Mock + Repository updateRepository; + @Mock + RepositoryConnection updateConnection; + @Mock + Update prepareUpdate; + private static String query = "DELETE {\n" + "\t ?oldAge .\n" + "}\n" + @@ -25,24 +51,26 @@ class Rdf4jUpdateModuleTest { "}"; @Test - @Disabled - public void testUpdateEmpty() { + void executeSelfExecutesAllUpdateQueries() { + final ExecutionContext inputExecutionContext = ExecutionContextFactory.createEmptyContext(); Model configModel = ModelFactory.createDefaultModel(); - final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); final Resource root = configModel.createResource(); - configModel.add(root, Rdf4jDeployModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); - configModel.add(root, Rdf4jDeployModule.P_RDF4J_REPOSITORY_NAME, "mb-test"); + given(updateRepository.getConnection()).willReturn(updateConnection); + given(updateConnection.size()).willReturn(1L); + given(updateConnection.prepareUpdate(any(QueryLanguage.class), anyString())).willReturn(prepareUpdate); + moduleRdf4j.setUpdateRepository(updateRepository); + + configModel.add(root, Rdf4jUpdateModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); + configModel.add(root, Rdf4jUpdateModule.P_RDF4J_REPOSITORY_NAME, "new-test"); configModel.add(root, SML.updateQuery, Rdf4jUpdateModule.createUpdateQueryResource(configModel, query)); + configModel.add(root, KBSS_MODULE.has_max_iteration_count, "5"); configModel.write(System.out, FileUtils.langTurtle, null); moduleRdf4j.setConfigurationResource(root); moduleRdf4j.setInputContext(inputExecutionContext); moduleRdf4j.execute(); - } - void executeSelfExecutesAllUpdateQueries() { - // given(repository.getConnection()).return(connection); - // verify ... ~ updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); + verify(updateConnection,times(5)).prepareUpdate(any(QueryLanguage.class), anyString()); } } \ No newline at end of file From 3b65e8dd86d3a10127d6676107fef8d55104372d Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Sun, 23 Jul 2023 09:30:50 +0200 Subject: [PATCH 27/28] [Upd] Fixed access method to rdf4j update module --- .../spipes/modules/Rdf4jUpdateModule.java | 32 ++++++++++++++++--- .../spipes/modules/Rdf4jUpdateModuleTest.java | 32 ++++++------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index bdf02dfc..f499cf2b 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -22,6 +22,7 @@ import org.topbraid.spin.vocabulary.SP; import java.util.List; +import java.util.stream.Collectors; public class Rdf4jUpdateModule extends AbstractModule { private static final Logger LOG = LoggerFactory.getLogger(Rdf4jUpdateModule.class.getName()); @@ -39,10 +40,18 @@ public class Rdf4jUpdateModule extends AbstractModule { */ static final Property P_RDF4J_REPOSITORY_NAME = getParameter("p-rdf4j-repository-name"); private String rdf4jRepositoryName; - private List updateQueries; + private List updateQueries; private Repository updateRepository; - private Update prepareUpdate; + + public void setUpdateQueries(List updateQueries) { + this.updateQueries = updateQueries; + } + + public List getUpdateQueries() { + return updateQueries; + } + private int iterationCount; private boolean onlyIfTripleCountChanges; @@ -62,6 +71,14 @@ public void setRdf4jServerURL(String rdf4jServerURL) { this.rdf4jServerURL = rdf4jServerURL; } + public boolean isOnlyIfTripleCountChanges() { + return onlyIfTripleCountChanges; + } + + public void setOnlyIfTripleCountChanges(boolean onlyIfTripleCountChanges) { + this.onlyIfTripleCountChanges = onlyIfTripleCountChanges; + } + public String getRdf4jRepositoryName() { return rdf4jRepositoryName; } @@ -91,8 +108,7 @@ ExecutionContext executeSelf() { LOG.debug("Connected to {}", rdf4jRepositoryName); for(int i = 0;i < iterationCount;i++) { long oldTriplesCount = updateConnection.size(); - for (Resource updateQueryResource : updateQueries) { - String updateQuery = updateQueryResource.getProperty(SP.text).getLiteral().getString(); + for (String updateQuery : updateQueries) { makeUpdate(updateQuery, updateConnection); } long newTriplesCount = updateConnection.size(); @@ -106,6 +122,7 @@ ExecutionContext executeSelf() { } void makeUpdate(String updateString, RepositoryConnection updateConnection) { + Update prepareUpdate; try { prepareUpdate = updateConnection.prepareUpdate(QueryLanguage.SPARQL, updateString); } catch (MalformedQueryException e) { @@ -143,6 +160,11 @@ public void loadConfiguration() { ,iterationCount ,onlyIfTripleCountChanges); if(updateRepository == null)setUpdateRepository(new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements")); - updateQueries = getResourcesByProperty(SML.updateQuery); + updateQueries = loadUpdateQueries(); + } + + private List loadUpdateQueries() { + return getResourcesByProperty(SML.updateQuery).stream().map( + r -> r.getProperty(SP.text).getLiteral().getString()).collect(Collectors.toList()); } } diff --git a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java index 569bb346..0ffa61f9 100644 --- a/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java +++ b/s-pipes-modules/module-rdf4j/src/test/java/cz/cvut/spipes/modules/Rdf4jUpdateModuleTest.java @@ -1,19 +1,11 @@ package cz.cvut.spipes.modules; -import cz.cvut.spipes.constants.KBSS_MODULE; -import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; import cz.cvut.spipes.engine.ExecutionContextFactory; import org.eclipse.rdf4j.query.QueryLanguage; +import org.eclipse.rdf4j.query.Update; import org.eclipse.rdf4j.repository.Repository; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.util.FileUtils; import org.eclipse.rdf4j.repository.RepositoryConnection; -import org.eclipse.rdf4j.query.Update; -import org.eclipse.rdf4j.repository.http.HTTPUpdate; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -21,6 +13,8 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import java.util.Collections; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; @@ -52,24 +46,18 @@ class Rdf4jUpdateModuleTest { @Test void executeSelfExecutesAllUpdateQueries() { - - final ExecutionContext inputExecutionContext = ExecutionContextFactory.createEmptyContext(); - Model configModel = ModelFactory.createDefaultModel(); - final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); - final Resource root = configModel.createResource(); given(updateRepository.getConnection()).willReturn(updateConnection); given(updateConnection.size()).willReturn(1L); given(updateConnection.prepareUpdate(any(QueryLanguage.class), anyString())).willReturn(prepareUpdate); - moduleRdf4j.setUpdateRepository(updateRepository); - configModel.add(root, Rdf4jUpdateModule.P_RDF4J_SERVER_URL, "http://localhost:8080/rdf4j-server/"); - configModel.add(root, Rdf4jUpdateModule.P_RDF4J_REPOSITORY_NAME, "new-test"); - configModel.add(root, SML.updateQuery, Rdf4jUpdateModule.createUpdateQueryResource(configModel, query)); - configModel.add(root, KBSS_MODULE.has_max_iteration_count, "5"); - configModel.write(System.out, FileUtils.langTurtle, null); - moduleRdf4j.setConfigurationResource(root); + final ExecutionContext inputExecutionContext = ExecutionContextFactory.createEmptyContext(); + final Rdf4jUpdateModule moduleRdf4j = new Rdf4jUpdateModule(); moduleRdf4j.setInputContext(inputExecutionContext); - moduleRdf4j.execute(); + moduleRdf4j.setUpdateRepository(updateRepository); + moduleRdf4j.setUpdateQueries(Collections.singletonList(query)); + moduleRdf4j.setIterationCount(5); + + moduleRdf4j.executeSelf(); verify(updateConnection,times(5)).prepareUpdate(any(QueryLanguage.class), anyString()); } From 82fb232cd7a9770d402ce5406204c9dd6bbccba7 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Sun, 23 Jul 2023 10:36:13 +0200 Subject: [PATCH 28/28] [Fix] Fix strange test in loadConfiguration method --- .../ModuleConfigurationInconsistentException.java | 11 +++++++++++ .../cz/cvut/spipes/modules/Rdf4jUpdateModule.java | 9 ++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 s-pipes-core/src/main/java/cz/cvut/spipes/exception/ModuleConfigurationInconsistentException.java diff --git a/s-pipes-core/src/main/java/cz/cvut/spipes/exception/ModuleConfigurationInconsistentException.java b/s-pipes-core/src/main/java/cz/cvut/spipes/exception/ModuleConfigurationInconsistentException.java new file mode 100644 index 00000000..f810a118 --- /dev/null +++ b/s-pipes-core/src/main/java/cz/cvut/spipes/exception/ModuleConfigurationInconsistentException.java @@ -0,0 +1,11 @@ +package cz.cvut.spipes.exception; + +/** + * Indicate that SPipes Module was incorrectly configured. + */ +public class ModuleConfigurationInconsistentException extends RuntimeException { + + public ModuleConfigurationInconsistentException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java index f499cf2b..caabf48d 100644 --- a/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java +++ b/s-pipes-modules/module-rdf4j/src/main/java/cz/cvut/spipes/modules/Rdf4jUpdateModule.java @@ -3,6 +3,7 @@ import cz.cvut.spipes.constants.KBSS_MODULE; import cz.cvut.spipes.constants.SML; import cz.cvut.spipes.engine.ExecutionContext; +import cz.cvut.spipes.exception.ModuleConfigurationInconsistentException; import cz.cvut.spipes.exceptions.RepositoryAccessException; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Property; @@ -159,7 +160,13 @@ public void loadConfiguration() { LOG.debug("Iteration count={}\nOnlyIf...Changes={}" ,iterationCount ,onlyIfTripleCountChanges); - if(updateRepository == null)setUpdateRepository(new SPARQLRepository(rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements")); + if (updateRepository == null && rdf4jServerURL != null) { + throw new ModuleConfigurationInconsistentException( + "Repository is already initialized. Trying to override its configuration from RDF."); + } + updateRepository = new SPARQLRepository( + rdf4jServerURL + "repositories/" + rdf4jRepositoryName + "/statements" + ); updateQueries = loadUpdateQueries(); }