From 19abb90507ae1dc8aeec1e73b0020d5e591f79b5 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Sat, 12 Aug 2023 19:32:44 +0200 Subject: [PATCH 1/9] feat: use Lyo Store in TRS Client Signed-off-by: Andrew Berezovskyi --- CHANGELOG.md | 3 + .../java/org/eclipse/lyo/store/Store.java | 7 + .../lyo/store/internals/SparqlStoreImpl.java | 5 + trs/client/trs-client/pom.xml | 10 +- .../sparql/SparqlBatchingHandler.java | 15 +- .../lyo/trs/client/util/SparqlUtil.java | 173 +++++++++--------- 6 files changed, 117 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5d0db6e..2db669893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,11 @@ ### Added - Introducing capability to set the servletUri to be used by the OAuthConfiguration +- `Store.rawUpdateQuery(String)` allows making raw SPARQL UPDATE queries. ### Changed +- TRS Client uses Lyo Store instead of using Eclipse RDF4J directly. - Kotlin 1.9.0 is used; `kotlin-stdlib-jdk8` dependency was replaced with `kotlin-stdlib` due to [Kotlin updates](https://kotlinlang.org/docs/whatsnew18.html#updated-jvm-compilation-target). - Allow application to reset the oauth token cached within the server, when it deems that it is no longer valid - 🧨Corrected cardinality and range of the oslc_config:acceptedBy property (from String[0..1] to Resource[0..*]) @@ -17,6 +19,7 @@ ### Removed - 🧨 Support for JDK 11 (and all versions below 17) is removed. **JDK 17 is the new baseline for Eclipse Lyo.** The SDK and sample code has been tested using JDK 17, 20, and 21-ea. +- TRS Client no longer depends on Eclipse RDF4J. Helper methods for RDF4J were also removed. ### Fixed diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java index 33b36f17e..d9e41b355 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java @@ -397,4 +397,11 @@ default boolean appendResource(URI namedGraphUri, final T * @since 4.1.0 */ void close(); + + /** + * Execute a raw SPARQL query against the UPDATE endpoint. + * + * @param finalQueryString + */ + void rawUpdateQuery(String finalQueryString); } diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java index dbafb6418..7d861a3bd 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java @@ -437,6 +437,11 @@ public void close() { log.debug("Underlying SPARQL connection has been released"); } + @Override + public void rawUpdateQuery(String finalQueryString) { + queryExecutor.prepareSparqlUpdate(finalQueryString).execute(); + } + private String oslcQueryPrefixes(final Class clazz) { return "rdf=" + "<" + org.apache.jena.vocabulary.RDF.uri + ">"; } diff --git a/trs/client/trs-client/pom.xml b/trs/client/trs-client/pom.xml index 45259883b..e1044eeff 100644 --- a/trs/client/trs-client/pom.xml +++ b/trs/client/trs-client/pom.xml @@ -119,10 +119,6 @@ com.google.guava guava - - org.eclipse.rdf4j - rdf4j-repository-sparql - org.glassfish.jersey.core jersey-client @@ -139,6 +135,12 @@ slf4j-simple test + + org.eclipse.lyo.store + store-core + 6.0.0-SNAPSHOT + compile + diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java index 93f50a07a..eef0687df 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java @@ -4,6 +4,8 @@ import java.util.List; import org.eclipse.lyo.core.trs.ChangeEvent; import org.eclipse.lyo.core.trs.Deletion; +import org.eclipse.lyo.store.Store; +import org.eclipse.lyo.store.StoreFactory; import org.eclipse.lyo.trs.client.handlers.IProviderEventHandler; import org.eclipse.lyo.trs.client.model.BaseMember; import org.eclipse.lyo.trs.client.model.ChangeEventMessageTR; @@ -30,11 +32,18 @@ public SparqlBatchingHandler(final String sparqlUpdateService, @Override public void finishCycle() { log.debug("number of processed queries: " + queries.size()); - String finalQueryString = buildYugeQuery(queries); + String updateQuery = buildYugeQuery(queries); log.debug("sending Update SPARQL Query to server"); - SparqlUtil.processQuery_sesame(finalQueryString, sparqlUpdateService, - sparql_baseAuth_userName, sparql_baseAuth_pwd); + // TODO: build one or use a pool + Store store = StoreFactory.sparql(null, sparqlUpdateService, + sparql_baseAuth_userName, sparql_baseAuth_pwd); + try { + store.rawUpdateQuery(updateQuery); + } finally { + store.close(); + } + log.debug("Update SPARQL Queries successful!"); queries.clear(); diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java index 39163e8fc..bdec55e07 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java @@ -24,11 +24,6 @@ import org.eclipse.lyo.core.trs.Creation; import org.eclipse.lyo.core.trs.Deletion; import org.eclipse.lyo.core.trs.Modification; -import org.eclipse.rdf4j.query.QueryLanguage; -import org.eclipse.rdf4j.query.TupleQueryResult; -import org.eclipse.rdf4j.query.Update; -import org.eclipse.rdf4j.repository.RepositoryConnection; -import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -393,13 +388,13 @@ static public void processQuery(String query, String serviceUrl) { * @param pwd * password for authentication if applicable */ - static public void processQuery_sesame(String query, String serviceUrl, String user, String pwd) { - SPARQLRepository repo = new SPARQLRepository(serviceUrl); - repo.setUsernameAndPassword(user, pwd); - repo.initialize(); - RepositoryConnection rc = repo.getConnection(); - processQuery_sesame(query, rc); - } +// static public void processQuery_sesame(String query, String serviceUrl, String user, String pwd) { +// SPARQLRepository repo = new SPARQLRepository(serviceUrl); +// repo.setUsernameAndPassword(user, pwd); +// repo.initialize(); +// RepositoryConnection rc = repo.getConnection(); +// processQuery_sesame(query, rc); +// } /** * Send the given sparql update to the sparql update service using the @@ -411,10 +406,10 @@ static public void processQuery_sesame(String query, String serviceUrl, String u * the repository connection object holding credentials and the * sparql update endpoint */ - static public void processQuery_sesame(String query, RepositoryConnection conn) { - Update u = conn.prepareUpdate(query); - u.execute(); - } +// static public void processQuery_sesame(String query, RepositoryConnection conn) { +// Update u = conn.prepareUpdate(query); +// u.execute(); +// } /** * return the repo connection object in order to be able to use the sesame @@ -428,23 +423,23 @@ static public void processQuery_sesame(String query, RepositoryConnection conn) * password for authentication if applicable * @return */ - public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, String pwd) { - SPARQLRepository repo = new SPARQLRepository(queryEndpoint); - if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { - repo.setUsernameAndPassword("okacimi", "nohheis4ae"); - } - repo.initialize(); - try { - RepositoryConnection conn = repo.getConnection(); - if (conn == null) { - logger.error("error getting sparql repo connection !"); - } - return conn; - } catch (Exception e) { - logger.error("error getting sparql repo connection !", e); - return null; - } - } +// public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, String pwd) { +// SPARQLRepository repo = new SPARQLRepository(queryEndpoint); +// if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { +// repo.setUsernameAndPassword("okacimi", "nohheis4ae"); +// } +// repo.initialize(); +// try { +// RepositoryConnection conn = repo.getConnection(); +// if (conn == null) { +// logger.error("error getting sparql repo connection !"); +// } +// return conn; +// } catch (Exception e) { +// logger.error("error getting sparql repo connection !", e); +// return null; +// } +// } /** * return the repo connection object in order to be able to use the sesame @@ -458,25 +453,25 @@ public static RepositoryConnection getRepoConnection(String queryEndpoint, Strin * password for authentication if applicable * @return */ - public static RepositoryConnection getRepoConnection(String queryEndpoint, String updateEndPoint, String user, - String pwd) { - SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); - if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && !user.isEmpty()) { - repo.setUsernameAndPassword(user, pwd); - } - repo.initialize(); - try { - RepositoryConnection conn = repo.getConnection(); - - if (conn == null) { - logger.error("error getting sparql repo connection !"); - } - return conn; - } catch (Exception e) { - logger.error("error getting sparql repo connection !", e); - return null; - } - } +// public static RepositoryConnection getRepoConnection(String queryEndpoint, String updateEndPoint, String user, +// String pwd) { +// SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); +// if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && !user.isEmpty()) { +// repo.setUsernameAndPassword(user, pwd); +// } +// repo.initialize(); +// try { +// RepositoryConnection conn = repo.getConnection(); +// +// if (conn == null) { +// logger.error("error getting sparql repo connection !"); +// } +// return conn; +// } catch (Exception e) { +// logger.error("error getting sparql repo connection !", e); +// return null; +// } +// } /** * evaluate the given sparql query against the given sparql query endpoint @@ -491,19 +486,19 @@ public static RepositoryConnection getRepoConnection(String queryEndpoint, Strin * sparql query * @return the result of the querie's evaluation */ - public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, String query) { - RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); - TupleQueryResult result = null; - try { - - result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); - } catch (Exception e) { - logger.error("error during the execution of the query !", e); - } finally { - conn.close(); - } - return result; - } +// public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, String query) { +// RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); +// TupleQueryResult result = null; +// try { +// +// result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); +// } catch (Exception e) { +// logger.error("error during the execution of the query !", e); +// } finally { +// conn.close(); +// } +// return result; +// } /** * evaluate the given sparql update using the sesame repository connection @@ -514,14 +509,14 @@ public static TupleQueryResult evalQuery(String queryEndpoint, String user, Stri * @param sparqlQuery * sparql update to evaluate */ - public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { - try { - - conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); - } catch (Exception e) { - logger.error("error during the execution of the query !", e); - } - } +// public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { +// try { +// +// conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); +// } catch (Exception e) { +// logger.error("error during the execution of the query !", e); +// } +// } /** * evaluate the given sparql query using the sesame repository connection @@ -533,18 +528,18 @@ public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { * sparql query to evaluate * @return the queri's evaluation result */ - public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { - TupleQueryResult result = null; - try { - - result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); - - } catch (Exception e) { - logger.error("error during the execution of the query !", e); - } - - return result; - } +// public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { +// TupleQueryResult result = null; +// try { +// +// result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); +// +// } catch (Exception e) { +// logger.error("error during the execution of the query !", e); +// } +// +// return result; +// } /** * append a sparql update to another @@ -583,10 +578,10 @@ public static String appendSparqldQuery(String appending, String appended) { * @param graphName * named graph to which the triples shall be added */ - public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String graphName) { - String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); - SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); - } +// public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String graphName) { +// String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); +// SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); +// } /** * Create a triple with the link type as a predicate the src as subject and From 2dccf52aa42c8c4acb590baa2e4a4ac3779316b4 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Sat, 22 Mar 2025 14:58:54 +0100 Subject: [PATCH 2/9] Update pom.xml --- trs/client/trs-client/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/trs/client/trs-client/pom.xml b/trs/client/trs-client/pom.xml index d70899ccc..ec39453c6 100644 --- a/trs/client/trs-client/pom.xml +++ b/trs/client/trs-client/pom.xml @@ -120,6 +120,12 @@ org.glassfish.jersey.core jersey-client + + org.eclipse.lyo.store + store-core + ${v.lyo} + compile + @@ -132,12 +138,6 @@ slf4j-simple test - - org.eclipse.lyo.store - store-core - 6.0.0-SNAPSHOT - compile - From 3bbb2568ed1bde7db9548fc389552ca97218bc22 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Sat, 22 Mar 2025 15:01:43 +0100 Subject: [PATCH 3/9] Update pom.xml --- trs/client/trs-client/pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/trs/client/trs-client/pom.xml b/trs/client/trs-client/pom.xml index ec39453c6..03bf228cb 100644 --- a/trs/client/trs-client/pom.xml +++ b/trs/client/trs-client/pom.xml @@ -114,8 +114,6 @@ oslc-client ${v.lyo} - - org.glassfish.jersey.core jersey-client From 05b87f0b33ea86e3b84bbe758b85839bd5afe660 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Sat, 22 Mar 2025 15:49:47 +0100 Subject: [PATCH 4/9] fix: clean up imports --- .../lyo/trs/client/config/TrsConfigurationLoader.java | 4 ++-- .../lyo/trs/client/config/TrsConsumerConfiguration.java | 5 ++--- .../java/org/eclipse/lyo/trs/client/util/SparqlUtil.java | 6 ------ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java index a31c15868..489729bee 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java @@ -14,7 +14,7 @@ package org.eclipse.lyo.trs.client.config; -import com.google.common.base.Strings; +import org.eclipse.lyo.core.util.StringUtils; import java.io.BufferedInputStream; import java.io.File; @@ -47,7 +47,7 @@ public static TrsProviderConfiguration from(File f) throws IOException { p.load(input); String trsUriParam = p.getProperty("trs_uri"); - if (Strings.isNullOrEmpty(trsUriParam)) { + if (StringUtils.isNullOrEmpty(trsUriParam)) { throw new IllegalStateException("The 'trs_uri' field is missing in file " + f.getName()); } diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java index 2396b5c8e..f8733deec 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java @@ -17,10 +17,9 @@ import java.util.concurrent.ScheduledExecutorService; import org.eclipse.lyo.client.OslcClient; +import org.eclipse.lyo.core.util.StringUtils; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import com.google.common.base.Strings; - import jakarta.ws.rs.client.ClientBuilder; public class TrsConsumerConfiguration { @@ -70,7 +69,7 @@ public String getSparqlPassword() { public OslcClient getHttpClient() { if (httpClient == null) { final ClientBuilder builder = ClientBuilder.newBuilder(); - if (!Strings.isNullOrEmpty(basicUsername)) { + if (!StringUtils.isNullOrEmpty(basicUsername)) { builder.register(HttpAuthenticationFeature.basic(basicUsername, basicPassword)); } httpClient = new OslcClient(builder); diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java index aafbad165..c873520ec 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java @@ -25,12 +25,6 @@ import org.eclipse.lyo.core.trs.Creation; import org.eclipse.lyo.core.trs.Deletion; import org.eclipse.lyo.core.trs.Modification; -import org.eclipse.rdf4j.query.QueryLanguage; -import org.eclipse.rdf4j.query.TupleQueryResult; -import org.eclipse.rdf4j.query.Update; -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; From 0218b1830b4d7c5e387287f585d95736ce1f173b Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Wed, 18 Jun 2025 20:52:53 +0200 Subject: [PATCH 5/9] chore: apply spotless --- .../java/org/eclipse/lyo/store/Store.java | 76 ++-- .../lyo/store/internals/SparqlStoreImpl.java | 400 +++++++++++------- .../client/config/TrsConfigurationLoader.java | 6 +- .../config/TrsConsumerConfiguration.java | 14 +- .../sparql/SparqlBatchingHandler.java | 30 +- .../lyo/trs/client/util/SparqlUtil.java | 303 +++++++------ 6 files changed, 494 insertions(+), 335 deletions(-) diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java index a81cf2153..1b53e388d 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java @@ -1,14 +1,3 @@ -package org.eclipse.lyo.store; - -import java.net.URI; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Set; - -import org.apache.jena.arq.querybuilder.SelectBuilder; - /* * Copyright (c) 2020 Contributors to the Eclipse Foundation * @@ -22,7 +11,15 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +package org.eclipse.lyo.store; +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; +import org.apache.jena.arq.querybuilder.SelectBuilder; import org.apache.jena.rdf.model.Model; import org.eclipse.lyo.oslc4j.core.model.IResource; @@ -106,8 +103,7 @@ boolean insertResources(URI namedGraphUri, final Object... resources) /** * Retrieve a Jena {@link Model} for triples under the given subject from the corresponding named graph. */ - Model getJenaModelForSubject(URI namedGraphUri, URI subject) - throws NoSuchElementException; + Model getJenaModelForSubject(URI namedGraphUri, URI subject) throws NoSuchElementException; /** * Retrieve the collection of {@link IResource} instances specified by the concrete @@ -147,8 +143,9 @@ List getResources(URI namedGraphUri, final Class cla * @throws ModelUnmarshallingException if the classes cannot be instantiated or another error * occurred when working with Jena model. */ - List getResources(URI namedGraphUri, Class clazz, int limit, - int offset) throws StoreAccessException, ModelUnmarshallingException; + List getResources( + URI namedGraphUri, Class clazz, int limit, int offset) + throws StoreAccessException, ModelUnmarshallingException; /** * Alternative to {@link Store#getResources(URI, Class)} with paging on the OSLC resource level. @@ -168,9 +165,15 @@ List getResources(URI namedGraphUri, Class clazz, in * @throws ModelUnmarshallingException if the classes cannot be instantiated or another error * occurred when working with Jena model. */ - List getResources(URI namedGraphUri, Class clazz, - String prefixes, String where, String searchTerms, - int limit, int offset) throws StoreAccessException, ModelUnmarshallingException; + List getResources( + URI namedGraphUri, + Class clazz, + String prefixes, + String where, + String searchTerms, + int limit, + int offset) + throws StoreAccessException, ModelUnmarshallingException; /** * Alternative to {@link Store#getResources(URI, Class, String, String, String, int, int)} with additional parameters for inlined resources. @@ -219,10 +222,17 @@ List getResources(URI namedGraphUri, Class clazz, * @param additionalDistinctVars * @param additionalQueryFilter */ - List getResources(URI namedGraphUri, Class clazz, - String prefixes, String where, String searchTerms, - int limit, int offset, - List additionalDistinctVars, SelectBuilder additionalQueryFilter) throws StoreAccessException, ModelUnmarshallingException; + List getResources( + URI namedGraphUri, + Class clazz, + String prefixes, + String where, + String searchTerms, + int limit, + int offset, + List additionalDistinctVars, + SelectBuilder additionalQueryFilter) + throws StoreAccessException, ModelUnmarshallingException; /** * Retrieve a Jena model that satisfies the given where parameter as defined in the OSLC Query @@ -268,8 +278,13 @@ List getResources(URI namedGraphUri, Class clazz, * @return a Jena {@link Model} with the less than or equal to {@code limit} resources. * */ - Model getResources(URI namedGraph, String prefixes, String where, String searchTerms, int limit, int offset); - + Model getResources( + URI namedGraph, + String prefixes, + String where, + String searchTerms, + int limit, + int offset); /** * Alternative to {@link Store#getResources(URI, String, String, String, int, int)} with @@ -277,10 +292,17 @@ List getResources(URI namedGraphUri, Class clazz, * * See {@link Store#getResources(URI, Class, String, String, String, int, int, List, SelectBuilder)} * for an explanation of these additional parameters. - + * */ - Model getResources(URI namedGraph, String prefixes, String where, String searchTerms, int limit, int offset, - List additionalDistinctVars, SelectBuilder additionalQueryFilter); + Model getResources( + URI namedGraph, + String prefixes, + String where, + String searchTerms, + int limit, + int offset, + List additionalDistinctVars, + SelectBuilder additionalQueryFilter); /** * Retrieve a single {@link IResource} instance specified by the concrete diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java index aad9a2239..368732a0f 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java @@ -1,3 +1,16 @@ +/* + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 + * which is available at http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ package org.eclipse.lyo.store.internals; import java.lang.reflect.Array; @@ -16,23 +29,7 @@ import java.util.NoSuchElementException; import java.util.Set; import java.util.stream.Collectors; - import javax.xml.datatype.DatatypeConfigurationException; - -/* - * Copyright (c) 2020 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 - * which is available at http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ - import org.apache.jena.arq.querybuilder.DescribeBuilder; import org.apache.jena.arq.querybuilder.ExprFactory; import org.apache.jena.arq.querybuilder.Order; @@ -95,6 +92,7 @@ public class SparqlStoreImpl implements Store { * Could be used to prevent extremely large results */ public static final int TRIPLE_LIMIT = 10001; + private static final Logger log = LoggerFactory.getLogger(SparqlStoreImpl.class); private final JenaQueryExecutor queryExecutor; @@ -122,10 +120,14 @@ public SparqlStoreImpl(final String queryEndpoint, final String updateEndpoint) * @param username Username * @param password Password */ - public SparqlStoreImpl(final String queryEndpoint, final String updateEndpoint, - final String username, final String password) { - this(new SparqlQueryExecutorBasicAuthImpl(queryEndpoint, updateEndpoint, username, - password)); + public SparqlStoreImpl( + final String queryEndpoint, + final String updateEndpoint, + final String username, + final String password) { + this( + new SparqlQueryExecutorBasicAuthImpl( + queryEndpoint, updateEndpoint, username, password)); } /** @@ -165,13 +167,15 @@ public boolean insertResources(final URI namedGraph, final Object... resources) final Model model = JenaModelHelper.createJenaModel(resources); insertJenaModel(namedGraph, model); return true; - } catch (DatatypeConfigurationException | IllegalAccessException | - OslcCoreApplicationException | InvocationTargetException e) { + } catch (DatatypeConfigurationException + | IllegalAccessException + | OslcCoreApplicationException + | InvocationTargetException e) { throw new StoreAccessException(e); } } - //this is highly inefficient. I need to replace with a single query that removes all nodes. + // this is highly inefficient. I need to replace with a single query that removes all nodes. @Override public void deleteResources(final URI namedGraphUri, final URI... subjectUris) { final QuerySolutionMap map = new QuerySolutionMap(); @@ -179,9 +183,11 @@ public void deleteResources(final URI namedGraphUri, final URI... subjectUris) { map.clear(); map.add("graph", new ResourceImpl(String.valueOf(namedGraphUri))); map.add("subject", new ResourceImpl(String.valueOf(uris))); - final ParameterizedSparqlString sparqlString = new ParameterizedSparqlString( - "WITH ?graph DELETE { ?s ?p ?v } WHERE {?s ?p ?v . FILTER(?s = ?subject)}", - map); + final ParameterizedSparqlString sparqlString = + new ParameterizedSparqlString( + "WITH ?graph DELETE { ?s ?p ?v } WHERE {?s ?p ?v . FILTER(?s =" + + " ?subject)}", + map); final String query = sparqlString.toString(); final UpdateProcessor updateProcessor = queryExecutor.prepareSparqlUpdate(query); updateProcessor.execute(); @@ -201,8 +207,8 @@ public void deleteResources(final URI namedGraphUri, final IResource... resource public boolean namedGraphExists(final URI namedGraphUri) { final QuerySolutionMap map = new QuerySolutionMap(); map.add("g", new ResourceImpl(String.valueOf(namedGraphUri))); - final ParameterizedSparqlString sparqlString = new ParameterizedSparqlString( - "ASK {GRAPH ?g {?s ?p ?o} }", map); + final ParameterizedSparqlString sparqlString = + new ParameterizedSparqlString("ASK {GRAPH ?g {?s ?p ?o} }", map); final String query = sparqlString.toString(); queryExecutor.beginRead(); @@ -219,8 +225,8 @@ public boolean resourceExists(final URI namedGraphUri, final URI resourceUri) { final QuerySolutionMap map = new QuerySolutionMap(); map.add("g", new ResourceImpl(String.valueOf(namedGraphUri))); map.add("s", new ResourceImpl(String.valueOf(resourceUri))); - final ParameterizedSparqlString sparqlString = new ParameterizedSparqlString( - "ASK {GRAPH ?g {?s ?p ?o} }", map); + final ParameterizedSparqlString sparqlString = + new ParameterizedSparqlString("ASK {GRAPH ?g {?s ?p ?o} }", map); final String query = sparqlString.toString(); queryExecutor.beginRead(); @@ -236,103 +242,153 @@ public boolean resourceExists(final URI namedGraphUri, final URI resourceUri) { public Model getJenaModelForSubject(final URI namedGraphUri, final URI subject) throws NoSuchElementException { if (!namedGraphExists(namedGraphUri)) { - throw new NoSuchElementException("namedGraph '" + namedGraphUri + "' is missing from the triplestore"); + throw new NoSuchElementException( + "namedGraph '" + namedGraphUri + "' is missing from the triplestore"); } final Model model; model = modelFromQueryByUri(namedGraphUri, subject); if (model.isEmpty()) { - throw new NoSuchElementException("resource '" + subject + "' is missing from the triplestore at namedGraph '" - + namedGraphUri + "'"); + throw new NoSuchElementException( + "resource '" + + subject + + "' is missing from the triplestore at namedGraph '" + + namedGraphUri + + "'"); } return model; } @Override - public List getResources(final URI namedGraph, - final Class clazz) throws StoreAccessException, ModelUnmarshallingException { + public List getResources(final URI namedGraph, final Class clazz) + throws StoreAccessException, ModelUnmarshallingException { if (namedGraphExists(namedGraph)) { final Model model; model = modelFromQueryFlat(namedGraph); return getResourcesFromModel(model, clazz); } else { - throw new IllegalArgumentException("Named graph" - + namedGraph - + " was missing from " - + "the triplestore"); + throw new IllegalArgumentException( + "Named graph" + namedGraph + " was missing from " + "the triplestore"); } } @Override - public List getResources(final URI namedGraph, - final Class clazz, final int limit, final int offset) + public List getResources( + final URI namedGraph, final Class clazz, final int limit, final int offset) throws StoreAccessException, ModelUnmarshallingException { if (namedGraphExists(namedGraph)) { final Model model; model = modelFromQueryFlatPaged(namedGraph, getResourceNsUri(clazz), limit, offset); return getResourcesFromModel(model, clazz); } else { - throw new IllegalArgumentException("Named graph" - + namedGraph - + " was missing from " - + "the triplestore"); + throw new IllegalArgumentException( + "Named graph" + namedGraph + " was missing from " + "the triplestore"); } } @Override - public List getResources(final URI namedGraph, final Class clazz, final String prefixes, - final String where, final String searchTerms, final int limit, final int offset) + public List getResources( + final URI namedGraph, + final Class clazz, + final String prefixes, + final String where, + final String searchTerms, + final int limit, + final int offset) throws StoreAccessException, ModelUnmarshallingException { - return getResources(namedGraph, clazz, prefixes, where, searchTerms, limit, offset, - null, null); + return getResources( + namedGraph, clazz, prefixes, where, searchTerms, limit, offset, null, null); } @Override - public List getResources(final URI namedGraph, final Class clazz, final String prefixes, - final String where, final String searchTerms, final int limit, final int offset, - List additionalDistinctVars, SelectBuilder additionalQueryFilter) - throws StoreAccessException, ModelUnmarshallingException { + public List getResources( + final URI namedGraph, + final Class clazz, + final String prefixes, + final String where, + final String searchTerms, + final int limit, + final int offset, + List additionalDistinctVars, + SelectBuilder additionalQueryFilter) + throws StoreAccessException, ModelUnmarshallingException { String _prefixes = prefixes; String _where = where; - _prefixes = (StringUtils.isNullOrEmpty(_prefixes) ? "" : _prefixes + ",") + oslcQueryPrefixes(clazz); - _where = (StringUtils.isNullOrEmpty(_where) ? "" : _where + " and ") + oslcQueryWhere(clazz); - Model model = getResources(namedGraph, _prefixes, _where, searchTerms, limit, offset, additionalDistinctVars, - additionalQueryFilter); + _prefixes = + (StringUtils.isNullOrEmpty(_prefixes) ? "" : _prefixes + ",") + + oslcQueryPrefixes(clazz); + _where = + (StringUtils.isNullOrEmpty(_where) ? "" : _where + " and ") + oslcQueryWhere(clazz); + Model model = + getResources( + namedGraph, + _prefixes, + _where, + searchTerms, + limit, + offset, + additionalDistinctVars, + additionalQueryFilter); return getResourcesFromModel(model, clazz); } @Override - public Model getResources(final URI namedGraph, final String prefixes, final String where, final int limit, - final int offset) { + public Model getResources( + final URI namedGraph, + final String prefixes, + final String where, + final int limit, + final int offset) { return getResources(namedGraph, prefixes, where, null, limit, offset); } @Override - public Model getResources(final URI namedGraph, final String prefixes, final String where, final String searchTerms, - final int limit, final int offset) { - return getResources(namedGraph, prefixes, where, searchTerms, limit, offset, - null, null); + public Model getResources( + final URI namedGraph, + final String prefixes, + final String where, + final String searchTerms, + final int limit, + final int offset) { + return getResources(namedGraph, prefixes, where, searchTerms, limit, offset, null, null); } @Override - public Model getResources(final URI namedGraph, final String prefixes, final String where, final String searchTerms, - final int limit, final int offset, List additionalDistinctVars, - SelectBuilder additionalQueryFilter) { + public Model getResources( + final URI namedGraph, + final String prefixes, + final String where, + final String searchTerms, + final int limit, + final int offset, + List additionalDistinctVars, + SelectBuilder additionalQueryFilter) { if (namedGraph != null) { - //Make sure the designated namedGraph exists, if it is specified. - //Otherwise, the search occurs across all named graphs. + // Make sure the designated namedGraph exists, if it is specified. + // Otherwise, the search occurs across all named graphs. if (!namedGraphExists(namedGraph)) { - throw new IllegalArgumentException("Named graph" + namedGraph + " was missing from the triplestore"); + throw new IllegalArgumentException( + "Named graph" + namedGraph + " was missing from the triplestore"); } } - SelectBuilder sparqlWhereQuery = constructSparqlWhere (prefixes, where, searchTerms, limit, offset, - additionalDistinctVars, additionalQueryFilter); + SelectBuilder sparqlWhereQuery = + constructSparqlWhere( + prefixes, + where, + searchTerms, + limit, + offset, + additionalDistinctVars, + additionalQueryFilter); DescribeBuilder describeBuilder = new DescribeBuilder(); - describeBuilder.addVar("s") - .addGraph((namedGraph != null) ? new ResourceImpl(String.valueOf(namedGraph)) : "?g", sparqlWhereQuery); + describeBuilder + .addVar("s") + .addGraph( + (namedGraph != null) ? new ResourceImpl(String.valueOf(namedGraph)) : "?g", + sparqlWhereQuery); if (null != additionalDistinctVars) { for (String additionalDistinctVar : additionalDistinctVars) { @@ -340,22 +396,30 @@ public Model getResources(final URI namedGraph, final String prefixes, final Str } } - Query describeQuery = describeBuilder.build() ; + Query describeQuery = describeBuilder.build(); String describeQueryString = describeQuery.toString(); Model execDescribe; queryExecutor.beginRead(); try { - final QueryExecution queryExecution = queryExecutor.prepareSparqlQuery(describeQueryString); + final QueryExecution queryExecution = + queryExecutor.prepareSparqlQuery(describeQueryString); try { - log.trace("SPARQL Describe query for oslc.where='{}':\n{}", where, describeQueryString); + log.trace( + "SPARQL Describe query for oslc.where='{}':\n{}", + where, + describeQueryString); Instant start = Instant.now(); execDescribe = queryExecution.execDescribe(); Instant finish = Instant.now(); - log.trace("GetResources - SPARQL Query Execution Duration: {} ms", Duration.between(start, finish).toMillis()); + log.trace( + "GetResources - SPARQL Query Execution Duration: {} ms", + Duration.between(start, finish).toMillis()); } catch (RiotException e) { - //a request that returns an empty set seems to cause an exception when using Marklogic. - if ((e.getCause() == null) && (e.getMessage().equals("[line: 2, col: 2 ] Out of place: [DOT]"))) { + // a request that returns an empty set seems to cause an exception when using + // Marklogic. + if ((e.getCause() == null) + && (e.getMessage().equals("[line: 2, col: 2 ] Out of place: [DOT]"))) { return ModelFactory.createDefaultModel(); } // Otherwise, there is a proper exception that we need to deal with! @@ -368,31 +432,33 @@ public Model getResources(final URI namedGraph, final String prefixes, final Str } @Override - public T getResource(final URI namedGraphUri, - final URI resourceUri, final Class clazz) + public T getResource( + final URI namedGraphUri, final URI resourceUri, final Class clazz) throws NoSuchElementException, StoreAccessException, ModelUnmarshallingException { final Model model = getJenaModelForSubject(namedGraphUri, resourceUri); final List modelResources = getResourcesFromModel(model, clazz); if (modelResources == null || modelResources.isEmpty()) { throw new NoSuchElementException( - "Empty Jena model for the subject " + resourceUri + ". Use resourceExists(g," + - "r) method to check for resource existence before calling this method" + - "."); + "Empty Jena model for the subject " + + resourceUri + + ". Use resourceExists(g," + + "r) method to check for resource existence before calling this method" + + "."); } return modelResources.get(0); } @Override - public boolean updateResources(final URI namedGraphUri, - final T... resources) throws StoreAccessException { - //No need to check if the resource exists. just delete it - if it is there. + public boolean updateResources( + final URI namedGraphUri, final T... resources) throws StoreAccessException { + // No need to check if the resource exists. just delete it - if it is there. deleteResources(namedGraphUri, resources); return insertResources(namedGraphUri, resources); } @Override - public boolean putResources(final URI uri, - final Collection resources) throws StoreAccessException { + public boolean putResources(final URI uri, final Collection resources) + throws StoreAccessException { if (namedGraphExists(uri)) { clear(uri); } @@ -400,16 +466,16 @@ public boolean putResources(final URI uri, } @Override - public boolean appendResources(final URI namedGraph, - final Collection resources) throws StoreAccessException { + public boolean appendResources( + final URI namedGraph, final Collection resources) throws StoreAccessException { return insertResources(namedGraph, resources.toArray()); } @Override public void clear(final URI namedGraph) { final QuerySolutionMap map = getGraphMap(namedGraph); - final ParameterizedSparqlString query = new ParameterizedSparqlString("CLEAR GRAPH ?g", - map); + final ParameterizedSparqlString query = + new ParameterizedSparqlString("CLEAR GRAPH ?g", map); queryExecutor.beginWrite(); try { final UpdateProcessor up = queryExecutor.prepareSparqlUpdate(query.toString()); @@ -450,25 +516,34 @@ private String oslcQueryWhere(final Class clazz) { return "rdf:type=" + "<" + getResourceNsUri(clazz) + ">"; } - private List getResourcesFromModel(final Model model, - final Class clazz) throws ModelUnmarshallingException, StoreAccessException { + private List getResourcesFromModel( + final Model model, final Class clazz) + throws ModelUnmarshallingException, StoreAccessException { try { Instant start = Instant.now(); final Object[] obj = JenaModelHelper.fromJenaModel(model, clazz); - @SuppressWarnings("unchecked") final T[] castObjects = (T[]) Array.newInstance(clazz, - obj.length); + @SuppressWarnings("unchecked") + final T[] castObjects = (T[]) Array.newInstance(clazz, obj.length); for (int i = 0; i < obj.length; i++) { castObjects[i] = clazz.cast(obj[i]); } Instant finish = Instant.now(); - log.trace("getResourcesFromModel - Execution Duration: {} ms", Duration.between(start, finish).toMillis()); - //The Model is most likely obtained via Select query that is orded by the subject (ascending) - //See sparql construction in constructSparqlWhere() - //Order the list below accordingly. + log.trace( + "getResourcesFromModel - Execution Duration: {} ms", + Duration.between(start, finish).toMillis()); + // The Model is most likely obtained via Select query that is orded by the subject + // (ascending) + // See sparql construction in constructSparqlWhere() + // Order the list below accordingly. return Arrays.stream(castObjects) - .sorted(Comparator.comparing(IResource::getAbout)).collect(Collectors.toList()); - } catch (InvocationTargetException | OslcCoreApplicationException | NoSuchMethodException - | URISyntaxException | DatatypeConfigurationException | InstantiationException e) { + .sorted(Comparator.comparing(IResource::getAbout)) + .collect(Collectors.toList()); + } catch (InvocationTargetException + | OslcCoreApplicationException + | NoSuchMethodException + | URISyntaxException + | DatatypeConfigurationException + | InstantiationException e) { throw new ModelUnmarshallingException(e); } catch (final IllegalAccessException e) { throw new StoreAccessException(e); @@ -497,14 +572,13 @@ private QuerySolutionMap getGraphMap(final URI namedGraph) { private Model modelFromQueryFlat(final URI namedGraph) { // TODO avoid CONSTRUCT query final QuerySolutionMap map = getGraphMap(namedGraph); - final String queryTemplate = "DESCRIBE ?s WHERE { GRAPH ?g { ?s " - + "?p " - + "?o } }"; + final String queryTemplate = "DESCRIBE ?s WHERE { GRAPH ?g { ?s " + "?p " + "?o } }"; final ParameterizedSparqlString query = new ParameterizedSparqlString(queryTemplate, map); queryExecutor.beginRead(); try { - final QueryExecution queryExecution = queryExecutor.prepareSparqlQuery(query.toString()); + final QueryExecution queryExecution = + queryExecutor.prepareSparqlQuery(query.toString()); return queryExecution.execDescribe(); } finally { queryExecutor.end(); @@ -527,10 +601,14 @@ private Model modelFromQueryByUri(final URI namedGraph, final URI uri) { Instant start = Instant.now(); execDescribe = queryExecution.execDescribe(); Instant finish = Instant.now(); - log.trace("GetResource - SPARQL Query Execution Duration: {} ms", Duration.between(start, finish).toMillis()); + log.trace( + "GetResource - SPARQL Query Execution Duration: {} ms", + Duration.between(start, finish).toMillis()); } catch (RiotException e) { - //a request that returns an empty set seems to cause an exception when using Marklogic. - if ((e.getCause() == null) && (e.getMessage().equals("[line: 2, col: 2 ] Out of place: [DOT]"))) { + // a request that returns an empty set seems to cause an exception when using + // Marklogic. + if ((e.getCause() == null) + && (e.getMessage().equals("[line: 2, col: 2 ] Out of place: [DOT]"))) { return ModelFactory.createDefaultModel(); } // Otherwise, there is a proper exception that we need to deal with! @@ -540,36 +618,36 @@ private Model modelFromQueryByUri(final URI namedGraph, final URI uri) { queryExecutor.end(); } return execDescribe; - } - private Model modelFromQueryFlatPaged(final URI namedGraph, final URI type, final int limit, - final int offset) { + private Model modelFromQueryFlatPaged( + final URI namedGraph, final URI type, final int limit, final int offset) { // TODO avoid CONSTRUCT query final Model m = ModelFactory.createDefaultModel(); final Resource typeResource = m.createResource(type.toString()); final QuerySolutionMap map = getGraphMap(namedGraph); map.add("t", typeResource); - final String queryTemplate = "PREFIX rdf: \n" - + "DESCRIBE ?s\n" - + "WHERE {\n" - + " GRAPH ?g {\n" - + " ?s ?p ?o\n" - + " {\n" - + " SELECT DISTINCT ?s\n" - + " WHERE {\n" - + " ?s ?p ?o .\n" - + " ?s rdf:type ?t.\n" - + " }\n" - + " ORDER BY ASC(?s)\n" - + " LIMIT ?l\n" - + " OFFSET " - + "?f\n" - + "}\n" - + "}\n" - + "}\n"; + final String queryTemplate = + "PREFIX rdf: \n" + + "DESCRIBE ?s\n" + + "WHERE {\n" + + " GRAPH ?g {\n" + + " ?s ?p ?o\n" + + " {\n" + + " SELECT DISTINCT ?s\n" + + " WHERE {\n" + + " ?s ?p ?o .\n" + + " ?s rdf:type ?t.\n" + + " }\n" + + " ORDER BY ASC(?s)\n" + + " LIMIT ?l\n" + + " OFFSET " + + "?f\n" + + "}\n" + + "}\n" + + "}\n"; // TODO: 15.02.17 add global triple limit just in case // + "\n" + "LIMIT " + TRIPLE_LIMIT + "\n" + "\n" + "\n"; @@ -580,7 +658,8 @@ private Model modelFromQueryFlatPaged(final URI namedGraph, final URI type, fina queryExecutor.beginRead(); try { - final QueryExecution queryExecution = queryExecutor.prepareSparqlQuery(query.toString()); + final QueryExecution queryExecution = + queryExecutor.prepareSparqlQuery(query.toString()); return queryExecution.execDescribe(); } finally { queryExecutor.end(); @@ -591,13 +670,18 @@ private Model modelFromQueryFlatPaged(final URI namedGraph, final URI type, fina * This method currently only provides support for terms of type {@link Type#COMPARISON}, where the operator is * 'EQUALS', and the operand is either a {@link String} or a {@link URI}. */ - private SelectBuilder constructSparqlWhere(final String prefixes, final String where, final String searchTerms, - final int limit, final int offset, List additionalDistinctVars, - SelectBuilder additionalQueryFilter) { + private SelectBuilder constructSparqlWhere( + final String prefixes, + final String where, + final String searchTerms, + final int limit, + final int offset, + List additionalDistinctVars, + SelectBuilder additionalQueryFilter) { SelectBuilder distinctResourcesQuery = new SelectBuilder(); - //Setup prefixes + // Setup prefixes Map prefixesMap = new HashMap<>(); try { if (!StringUtils.isNullOrEmpty(prefixes)) { @@ -610,10 +694,7 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w throw new IllegalArgumentException("prefixesExpression could not be parsed", e); } - distinctResourcesQuery - .addVar( "s" ) - .setDistinct(true) - .addWhere( "?s", "?p", "?o"); + distinctResourcesQuery.addVar("s").setDistinct(true).addWhere("?s", "?p", "?o"); if (null != additionalDistinctVars) { for (String additionalDistinctVar : additionalDistinctVars) { @@ -624,7 +705,7 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w distinctResourcesQuery.addWhere(additionalQueryFilter); } - //Setup where + // Setup where WhereClause whereClause = null; try { if (!StringUtils.isNullOrEmpty(where)) { @@ -635,12 +716,14 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w PName property = simpleTerm.property(); if (!termType.equals(Type.COMPARISON)) { - throw new UnsupportedOperationException("only support for terms of type Comparisons"); + throw new UnsupportedOperationException( + "only support for terms of type Comparisons"); } ComparisonTerm aComparisonTerm = (ComparisonTerm) simpleTerm; if (!aComparisonTerm.operator().equals(Operator.EQUALS)) { throw new UnsupportedOperationException( - "only support for terms of type Comparisons, where the operator is 'EQUALS'"); + "only support for terms of type Comparisons, where the operator is" + + " 'EQUALS'"); } Value comparisonOperand = aComparisonTerm.operand(); @@ -655,19 +738,24 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w switch (operandType) { case DECIMAL: DecimalValue decimalOperand = (DecimalValue) comparisonOperand; - distinctResourcesQuery.addWhere("?s", predicate, decimalOperand.value()); + distinctResourcesQuery.addWhere( + "?s", predicate, decimalOperand.value()); break; case STRING: StringValue stringOperand = (StringValue) comparisonOperand; - distinctResourcesQuery.addWhere("?s", predicate, "\"" + stringOperand.value() + "\""); + distinctResourcesQuery.addWhere( + "?s", predicate, "\"" + stringOperand.value() + "\""); break; case URI_REF: UriRefValue uriOperand = (UriRefValue) comparisonOperand; - distinctResourcesQuery.addWhere("?s", predicate, new ResourceImpl(uriOperand.value())); + distinctResourcesQuery.addWhere( + "?s", predicate, new ResourceImpl(uriOperand.value())); break; default: - throw new UnsupportedOperationException("only support for terms of type Comparisons," + - " where the operator is 'EQUALS', and the operand is either a String, an Integer or a URI"); + throw new UnsupportedOperationException( + "only support for terms of type Comparisons, where the operator" + + " is 'EQUALS', and the operand is either a String, an" + + " Integer or a URI"); } } } @@ -675,16 +763,16 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w throw new IllegalArgumentException("whereExpression could not be parsed", e); } - //Setup searchTerms - //Add a sparql filter "FILTER regex(?o, "", "i")" to the distinctResourcesQuery + // Setup searchTerms + // Add a sparql filter "FILTER regex(?o, "", "i")" to the + // distinctResourcesQuery if (!StringUtils.isNullOrEmpty(searchTerms)) { ExprFactory factory = new ExprFactory(); E_Regex regex = factory.regex(factory.str("?o"), searchTerms, "i"); distinctResourcesQuery.addFilter(regex); } - - if ((limit > 0 || offset > 0) && (! OSLC4JUtils.isLyoStorePagingUnsafe())) { + if ((limit > 0 || offset > 0) && (!OSLC4JUtils.isLyoStorePagingUnsafe())) { distinctResourcesQuery.addOrderBy("?s", Order.ASCENDING); } @@ -696,10 +784,8 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w } SelectBuilder constructSelectQuery = new SelectBuilder(); - constructSelectQuery.addVar( "s p o" ) - .addSubQuery(distinctResourcesQuery); + constructSelectQuery.addVar("s p o").addSubQuery(distinctResourcesQuery); return constructSelectQuery; } - } diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java index 489729bee..03d2d51c2 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java @@ -14,8 +14,6 @@ package org.eclipse.lyo.trs.client.config; -import org.eclipse.lyo.core.util.StringUtils; - import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -23,6 +21,7 @@ import java.io.InputStream; import java.net.URI; import java.util.Properties; +import org.eclipse.lyo.core.util.StringUtils; /** * Loads TRS Provider configuration from a .properties file. @@ -48,7 +47,8 @@ public static TrsProviderConfiguration from(File f) throws IOException { String trsUriParam = p.getProperty("trs_uri"); if (StringUtils.isNullOrEmpty(trsUriParam)) { - throw new IllegalStateException("The 'trs_uri' field is missing in file " + f.getName()); + throw new IllegalStateException( + "The 'trs_uri' field is missing in file " + f.getName()); } String user = p.getProperty("baseAuth_user"); diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java index f8733deec..95196bab4 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java @@ -14,14 +14,12 @@ package org.eclipse.lyo.trs.client.config; +import jakarta.ws.rs.client.ClientBuilder; import java.util.concurrent.ScheduledExecutorService; - import org.eclipse.lyo.client.OslcClient; import org.eclipse.lyo.core.util.StringUtils; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import jakarta.ws.rs.client.ClientBuilder; - public class TrsConsumerConfiguration { private final String sparqlQueryUrl; private final String sparqlUpdateUrl; @@ -32,9 +30,13 @@ public class TrsConsumerConfiguration { private final String basicPassword; private OslcClient httpClient; - public TrsConsumerConfiguration(final String sparqlQueryUrl, final String sparqlUpdateUrl, - final String sparqlUsername, final String sparqlPassword, - final ScheduledExecutorService scheduler, final String basicUsername, + public TrsConsumerConfiguration( + final String sparqlQueryUrl, + final String sparqlUpdateUrl, + final String sparqlUsername, + final String sparqlPassword, + final ScheduledExecutorService scheduler, + final String basicUsername, final String basicPassword) { this.sparqlQueryUrl = sparqlQueryUrl; this.sparqlUpdateUrl = sparqlUpdateUrl; diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java index eef0687df..e78a04874 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java @@ -14,16 +14,17 @@ import org.slf4j.LoggerFactory; public class SparqlBatchingHandler implements IProviderEventHandler { - private final static Logger log = LoggerFactory.getLogger( - SparqlBatchingHandler.class); + private static final Logger log = LoggerFactory.getLogger(SparqlBatchingHandler.class); private final List queries = new ArrayList<>(); private final String sparqlUpdateService; private final String sparql_baseAuth_userName; private final String sparql_baseAuth_pwd; - public SparqlBatchingHandler(final String sparqlUpdateService, - final String sparql_baseAuth_userName, final String sparql_baseAuth_pwd) { + public SparqlBatchingHandler( + final String sparqlUpdateService, + final String sparql_baseAuth_userName, + final String sparql_baseAuth_pwd) { this.sparqlUpdateService = sparqlUpdateService; this.sparql_baseAuth_userName = sparql_baseAuth_userName; this.sparql_baseAuth_pwd = sparql_baseAuth_pwd; @@ -36,8 +37,9 @@ public void finishCycle() { log.debug("sending Update SPARQL Query to server"); // TODO: build one or use a pool - Store store = StoreFactory.sparql(null, sparqlUpdateService, - sparql_baseAuth_userName, sparql_baseAuth_pwd); + Store store = + StoreFactory.sparql( + null, sparqlUpdateService, sparql_baseAuth_userName, sparql_baseAuth_pwd); try { store.rawUpdateQuery(updateQuery); } finally { @@ -53,8 +55,8 @@ public void finishCycle() { public void handleBaseMember(final BaseMember baseMember) { StringBuilder query = new StringBuilder(); String graphCreationQuery = SparqlUtil.createGraphQuery(baseMember.getUri()); - String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(baseMember.getUri(), - baseMember.getModel()); + String addTriplesToGraphQuery = + SparqlUtil.addTriplesToGraphQuery(baseMember.getUri(), baseMember.getModel()); query.append(graphCreationQuery); query.append("; \n"); query.append(addTriplesToGraphQuery); @@ -70,8 +72,8 @@ public void handleChangeEvent(final ChangeEventMessageTR eventMessageTR) { String query = SparqlUtil.getChangeEventQuery(event, null); queries.add(query); } else { - String query = SparqlUtil.getChangeEventQuery(event, - eventMessageTR.getTrackedResourceModel()); + String query = + SparqlUtil.getChangeEventQuery(event, eventMessageTR.getTrackedResourceModel()); queries.add(query); } } @@ -89,9 +91,11 @@ private String buildYugeQuery(final List queries) { queriesStringBuilder.append("; \n"); } -// TODO simply join instead of append - or check for the last element - queriesStringBuilder.replace(queriesStringBuilder.lastIndexOf("; \n"), - queriesStringBuilder.lastIndexOf("; \n") + 1, ""); + // TODO simply join instead of append - or check for the last element + queriesStringBuilder.replace( + queriesStringBuilder.lastIndexOf("; \n"), + queriesStringBuilder.lastIndexOf("; \n") + 1, + ""); // TODO Andrew@2018-02-28: this is a YUGE query that can crash everything // I think individual queries are better executed in the handlers diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java index c873520ec..11075a999 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java @@ -15,7 +15,6 @@ import java.io.IOException; import java.net.URI; - import org.apache.jena.rdf.model.Model; import org.apache.jena.update.UpdateExecutionFactory; import org.apache.jena.update.UpdateFactory; @@ -52,25 +51,25 @@ public class SparqlUtil { * name of the named graph to be created * @return the graph creation sparql query as a string */ - static public String createGraphQuery(String namedGraphUrl) { + public static String createGraphQuery(String namedGraphUrl) { String query = "CREATE GRAPH <" + namedGraphUrl + ">"; logger.debug("query for creation of graph: " + namedGraphUrl); logger.debug(query); return query; } - static public String createGraphQuery(URI namedGraphUrl) { + public static String createGraphQuery(URI namedGraphUrl) { return createGraphQuery(namedGraphUrl.toASCIIString()); } - /** - * returns the query deleting siltently the graph with the given name - * - * @param namedGraphUrl - * the name of the graph to be deleted - * @return the deletion query as a string - */ - static public String dropGraphQuery(String namedGraphUrl) { + /** + * returns the query deleting siltently the graph with the given name + * + * @param namedGraphUrl + * the name of the graph to be deleted + * @return the deletion query as a string + */ + public static String dropGraphQuery(String namedGraphUrl) { String query = "DROP GRAPH <" + namedGraphUrl + ">"; logger.debug("query for removal of graph: " + namedGraphUrl); logger.debug(query); @@ -85,10 +84,36 @@ static public String dropGraphQuery(String namedGraphUrl) { * graph to be emptied * @return the query for emptying the graph */ - static public String removeAllTriplesInGraphQuery(String namedGraphUrl) { - String query = "WITH" + " " + "<" + namedGraphUrl + ">" + "\n" + "DELETE" + "\n" + "{?s ?p ?o }" + "\n" - + "WHERE" + "\n" + "{" + "\n" + "GRAPH" + " " + "<" + namedGraphUrl + ">" + "\n" + "{" + "\n" - + "?s ?p ?o" + "\n" + "}" + "\n" + "}" + "\n"; + public static String removeAllTriplesInGraphQuery(String namedGraphUrl) { + String query = + "WITH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "DELETE" + + "\n" + + "{?s ?p ?o }" + + "\n" + + "WHERE" + + "\n" + + "{" + + "\n" + + "GRAPH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "{" + + "\n" + + "?s ?p ?o" + + "\n" + + "}" + + "\n" + + "}" + + "\n"; logger.debug("query for removal of all triples from graph: " + namedGraphUrl); logger.debug(query); return query; @@ -105,7 +130,7 @@ static public String removeAllTriplesInGraphQuery(String namedGraphUrl) { * graph * @return the sparql update */ - static public String addTriplesToGraphQuery(String namedGraphUrl, Model jenaModel) { + public static String addTriplesToGraphQuery(String namedGraphUrl, Model jenaModel) { try { String nTripleRepresentation = RdfUtil.modelToNTriple(jenaModel); return addTriplesToGraphQuery(namedGraphUrl, nTripleRepresentation); @@ -115,24 +140,39 @@ static public String addTriplesToGraphQuery(String namedGraphUrl, Model jenaMode } } - static public String addTriplesToGraphQuery(URI namedGraphUrl, Model jenaModel) { + public static String addTriplesToGraphQuery(URI namedGraphUrl, Model jenaModel) { return addTriplesToGraphQuery(namedGraphUrl.toASCIIString(), jenaModel); } - - /** - * Gets a set of statements and a named graph as arguments and returns a - * sparql query for adding the statements to the named graph - * - * @param namedGraphUrl - * named graph to which the statements shall be added - * @param triples - * statements to be added to the named graph - * @return the sparql update - */ - static public String addTriplesToGraphQuery(String namedGraphUrl, String triples) { - String query = "INSERT DATA" + "\n" + "{" + "\n" + " GRAPH" + " " + "<" + namedGraphUrl + ">" + "\n" + "{" - + "\n" + triples + "\n" + "}" + "\n" + "}"; + /** + * Gets a set of statements and a named graph as arguments and returns a + * sparql query for adding the statements to the named graph + * + * @param namedGraphUrl + * named graph to which the statements shall be added + * @param triples + * statements to be added to the named graph + * @return the sparql update + */ + public static String addTriplesToGraphQuery(String namedGraphUrl, String triples) { + String query = + "INSERT DATA" + + "\n" + + "{" + + "\n" + + " GRAPH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "{" + + "\n" + + triples + + "\n" + + "}" + + "\n" + + "}"; logger.debug("query for creation of triples in graph: " + namedGraphUrl); logger.debug(query); return query; @@ -149,7 +189,7 @@ static public String addTriplesToGraphQuery(String namedGraphUrl, String triples * for a deletion event) * @return the sparql update */ - static public String getChangeEventQuery(ChangeEvent changeEvent, Model model) { + public static String getChangeEventQuery(ChangeEvent changeEvent, Model model) { if (changeEvent instanceof Creation) { return getCreationEventQuery(changeEvent, model); @@ -159,7 +199,6 @@ static public String getChangeEventQuery(ChangeEvent changeEvent, Model model) { return getModificationEventQuery(changeEvent, model); } return null; - } /** @@ -173,7 +212,7 @@ static public String getChangeEventQuery(ChangeEvent changeEvent, Model model) { * the changed resource * @return the sparql update */ - static public String getModificationEventQuery(ChangeEvent changeEvent, Model model) { + public static String getModificationEventQuery(ChangeEvent changeEvent, Model model) { String result = ""; String changeEventTarget = changeEvent.getChanged().toString(); String dropGraphQuery = dropGraphQuery(changeEventTarget); @@ -200,7 +239,7 @@ static public String getModificationEventQuery(ChangeEvent changeEvent, Model mo * representation of the changed resource * @return the sparql update */ - static public String getModificationEventQuery(ChangeEvent changeEvent, String triples) { + public static String getModificationEventQuery(ChangeEvent changeEvent, String triples) { String changeEventTarget = changeEvent.getChanged().toString(); return getModificationEventQuery(changeEventTarget, triples); @@ -217,7 +256,7 @@ static public String getModificationEventQuery(ChangeEvent changeEvent, String t * representation of the changed resource * @return the sparql update */ - static public String getModificationEventQuery(String changeEventTarget, String triples) { + public static String getModificationEventQuery(String changeEventTarget, String triples) { String result = ""; String dropGraphQuery = dropGraphQuery(changeEventTarget); String addGraphQuery = createGraphQuery(changeEventTarget); @@ -242,7 +281,7 @@ static public String getModificationEventQuery(String changeEventTarget, String * updated rdf representation of the changed resource * @return */ - static public String getCreationEventQuery(ChangeEvent changeEvent, Model model) { + public static String getCreationEventQuery(ChangeEvent changeEvent, Model model) { String result = ""; String changeEventTarget = changeEvent.getChanged().toString(); @@ -264,7 +303,7 @@ static public String getCreationEventQuery(ChangeEvent changeEvent, Model model) * created * @return the sparql update */ - static public String getDeletionEventQuery(ChangeEvent changeEvent) { + public static String getDeletionEventQuery(ChangeEvent changeEvent) { String result = ""; String changeEventTarget = changeEvent.getChanged().toString(); @@ -285,7 +324,7 @@ static public String getDeletionEventQuery(ChangeEvent changeEvent) { * @param serviceUrl * sparql update endpoint url */ - static public void createGraph(String namedGraphUrl, String serviceUrl) { + public static void createGraph(String namedGraphUrl, String serviceUrl) { UpdateRequest request = UpdateFactory.create(); request.add(createGraphQuery(namedGraphUrl)); UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); @@ -301,7 +340,7 @@ static public void createGraph(String namedGraphUrl, String serviceUrl) { * @param serviceUrl * sparql update endpoint url */ - static public void dropGraph(String namedGraphUrl, String serviceUrl) { + public static void dropGraph(String namedGraphUrl, String serviceUrl) { UpdateRequest request = UpdateFactory.create(); request.add(dropGraphQuery(namedGraphUrl)); UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); @@ -320,7 +359,8 @@ static public void dropGraph(String namedGraphUrl, String serviceUrl) { * @param serviceUrl * the sparql update endpoint */ - static public void addTriplesToNamedGraph(Model jenaModel, String namedGraphUrl, String serviceUrl) { + public static void addTriplesToNamedGraph( + Model jenaModel, String namedGraphUrl, String serviceUrl) { UpdateRequest request = UpdateFactory.create(); request.add(addTriplesToGraphQuery(namedGraphUrl, jenaModel)); UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); @@ -336,7 +376,7 @@ static public void addTriplesToNamedGraph(Model jenaModel, String namedGraphUrl, * @param serviceUrl * the sparql update endpoint */ - static public void removeAllTriplesInNamedGraph(String namedGraphUrl, String serviceUrl) { + public static void removeAllTriplesInNamedGraph(String namedGraphUrl, String serviceUrl) { UpdateRequest request = UpdateFactory.create(); request.add(removeAllTriplesInGraphQuery(namedGraphUrl)); UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); @@ -355,7 +395,7 @@ static public void removeAllTriplesInNamedGraph(String namedGraphUrl, String ser * @param serviceUrl * the sparql update endpoint */ - static public void processChangeEvent(ChangeEvent changeEvent, Model model, String serviceUrl) { + public static void processChangeEvent(ChangeEvent changeEvent, Model model, String serviceUrl) { String changeEventQuery = getChangeEventQuery(changeEvent, model); processQuery(changeEventQuery, serviceUrl); } @@ -369,7 +409,7 @@ static public void processChangeEvent(ChangeEvent changeEvent, Model model, Stri * @param serviceUrl * sparql update endpoint for processing the sparql update */ - static public void processQuery(String query, String serviceUrl) { + public static void processQuery(String query, String serviceUrl) { UpdateRequest request = UpdateFactory.create(); request.add(query); UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); @@ -389,13 +429,14 @@ static public void processQuery(String query, String serviceUrl) { * @param pwd * password for authentication if applicable */ -// static public void processQuery_sesame(String query, String serviceUrl, String user, String pwd) { -// SPARQLRepository repo = new SPARQLRepository(serviceUrl); -// repo.setUsernameAndPassword(user, pwd); -// repo.initialize(); -// RepositoryConnection rc = repo.getConnection(); -// processQuery_sesame(query, rc); -// } + // static public void processQuery_sesame(String query, String serviceUrl, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(serviceUrl); + // repo.setUsernameAndPassword(user, pwd); + // repo.initialize(); + // RepositoryConnection rc = repo.getConnection(); + // processQuery_sesame(query, rc); + // } /** * Send the given sparql update to the sparql update service using the @@ -407,10 +448,10 @@ static public void processQuery(String query, String serviceUrl) { * the repository connection object holding credentials and the * sparql update endpoint */ -// static public void processQuery_sesame(String query, RepositoryConnection conn) { -// Update u = conn.prepareUpdate(query); -// u.execute(); -// } + // static public void processQuery_sesame(String query, RepositoryConnection conn) { + // Update u = conn.prepareUpdate(query); + // u.execute(); + // } /** * return the repo connection object in order to be able to use the sesame @@ -424,23 +465,24 @@ static public void processQuery(String query, String serviceUrl) { * password for authentication if applicable * @return */ -// public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, String pwd) { -// SPARQLRepository repo = new SPARQLRepository(queryEndpoint); -// if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { -// repo.setUsernameAndPassword("okacimi", "nohheis4ae"); -// } -// repo.initialize(); -// try { -// RepositoryConnection conn = repo.getConnection(); -// if (conn == null) { -// logger.error("error getting sparql repo connection !"); -// } -// return conn; -// } catch (Exception e) { -// logger.error("error getting sparql repo connection !", e); -// return null; -// } -// } + // public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(queryEndpoint); + // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { + // repo.setUsernameAndPassword("okacimi", "nohheis4ae"); + // } + // repo.initialize(); + // try { + // RepositoryConnection conn = repo.getConnection(); + // if (conn == null) { + // logger.error("error getting sparql repo connection !"); + // } + // return conn; + // } catch (Exception e) { + // logger.error("error getting sparql repo connection !", e); + // return null; + // } + // } /** * return the repo connection object in order to be able to use the sesame @@ -454,25 +496,27 @@ static public void processQuery(String query, String serviceUrl) { * password for authentication if applicable * @return */ -// public static RepositoryConnection getRepoConnection(String queryEndpoint, String updateEndPoint, String user, -// String pwd) { -// SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); -// if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && !user.isEmpty()) { -// repo.setUsernameAndPassword(user, pwd); -// } -// repo.initialize(); -// try { -// RepositoryConnection conn = repo.getConnection(); -// -// if (conn == null) { -// logger.error("error getting sparql repo connection !"); -// } -// return conn; -// } catch (Exception e) { -// logger.error("error getting sparql repo connection !", e); -// return null; -// } -// } + // public static RepositoryConnection getRepoConnection(String queryEndpoint, String + // updateEndPoint, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); + // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && + // !user.isEmpty()) { + // repo.setUsernameAndPassword(user, pwd); + // } + // repo.initialize(); + // try { + // RepositoryConnection conn = repo.getConnection(); + // + // if (conn == null) { + // logger.error("error getting sparql repo connection !"); + // } + // return conn; + // } catch (Exception e) { + // logger.error("error getting sparql repo connection !", e); + // return null; + // } + // } /** * evaluate the given sparql query against the given sparql query endpoint @@ -487,19 +531,20 @@ static public void processQuery(String query, String serviceUrl) { * sparql query * @return the result of the querie's evaluation */ -// public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, String query) { -// RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); -// TupleQueryResult result = null; -// try { -// -// result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); -// } catch (Exception e) { -// logger.error("error during the execution of the query !", e); -// } finally { -// conn.close(); -// } -// return result; -// } + // public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, + // String query) { + // RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); + // TupleQueryResult result = null; + // try { + // + // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } finally { + // conn.close(); + // } + // return result; + // } /** * evaluate the given sparql update using the sesame repository connection @@ -510,14 +555,14 @@ static public void processQuery(String query, String serviceUrl) { * @param sparqlQuery * sparql update to evaluate */ -// public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { -// try { -// -// conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); -// } catch (Exception e) { -// logger.error("error during the execution of the query !", e); -// } -// } + // public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { + // try { + // + // conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } + // } /** * evaluate the given sparql query using the sesame repository connection @@ -529,18 +574,18 @@ static public void processQuery(String query, String serviceUrl) { * sparql query to evaluate * @return the queri's evaluation result */ -// public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { -// TupleQueryResult result = null; -// try { -// -// result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); -// -// } catch (Exception e) { -// logger.error("error during the execution of the query !", e); -// } -// -// return result; -// } + // public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { + // TupleQueryResult result = null; + // try { + // + // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); + // + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } + // + // return result; + // } /** * append a sparql update to another @@ -579,10 +624,11 @@ public static String appendSparqldQuery(String appending, String appended) { * @param graphName * named graph to which the triples shall be added */ -// public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String graphName) { -// String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); -// SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); -// } + // public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String + // graphName) { + // String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); + // SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); + // } /** * Create a triple with the link type as a predicate the src as subject and @@ -607,5 +653,4 @@ public static String linkTriple(String src, String dst, String linkType) { sb.append(" ."); return sb.toString(); } - } From 0f63a0bbcf7e08787d19500688e1e89449c939f4 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Sat, 21 Jun 2025 15:13:18 +0200 Subject: [PATCH 6/9] wip: expand tests --- .../java/org/eclipse/lyo/store/Store.java | 2 +- .../lyo/store/internals/SparqlStoreImpl.java | 23 +- .../lyo/store/SparqlStoreImplTest.java | 57 ++++- .../lyo/store/StoreRawUpdateQueryTest.java | 216 ++++++++++++++++++ .../client/TrsClientMigrationTestSuite.java | 34 +++ .../client/config/TrsConfigurationTest.java | 152 ++++++++++++ .../sparql/SparqlBatchingHandlerTest.java | 201 ++++++++++++++++ 7 files changed, 670 insertions(+), 15 deletions(-) create mode 100644 store/store-core/src/test/java/org/eclipse/lyo/store/StoreRawUpdateQueryTest.java create mode 100644 trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java create mode 100644 trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java create mode 100644 trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java index 1b53e388d..a1e3e70c4 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/Store.java @@ -426,5 +426,5 @@ default boolean appendResource(URI namedGraphUri, final T * * @param finalQueryString */ - void rawUpdateQuery(String finalQueryString); + void rawUpdateQuery(String finalQueryString) throws StoreAccessException; } diff --git a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java index 368732a0f..0fcac592e 100644 --- a/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java +++ b/store/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java @@ -207,13 +207,15 @@ public void deleteResources(final URI namedGraphUri, final IResource... resource public boolean namedGraphExists(final URI namedGraphUri) { final QuerySolutionMap map = new QuerySolutionMap(); map.add("g", new ResourceImpl(String.valueOf(namedGraphUri))); + + // Check if graph exists by looking for any triples in the graph final ParameterizedSparqlString sparqlString = - new ParameterizedSparqlString("ASK {GRAPH ?g {?s ?p ?o} }", map); - final String query = sparqlString.toString(); + new ParameterizedSparqlString("ASK WHERE { GRAPH ?g { ?s ?p ?o } }", map); queryExecutor.beginRead(); try { - final QueryExecution queryExecution = queryExecutor.prepareSparqlQuery(query); + final QueryExecution queryExecution = + queryExecutor.prepareSparqlQuery(sparqlString.toString()); return queryExecution.execAsk(); } finally { queryExecutor.end(); @@ -504,8 +506,19 @@ public void close() { } @Override - public void rawUpdateQuery(String finalQueryString) { - queryExecutor.prepareSparqlUpdate(finalQueryString).execute(); + public void rawUpdateQuery(String finalQueryString) throws StoreAccessException { + queryExecutor.beginWrite(); + try { + final UpdateProcessor updateProcessor = + queryExecutor.prepareSparqlUpdate(finalQueryString); + updateProcessor.execute(); + queryExecutor.commit(); + } catch (Exception e) { + // Don't commit on error - just end the transaction which will abort it + throw new StoreAccessException("Failed to execute raw update query", e); + } finally { + queryExecutor.end(); + } } private String oslcQueryPrefixes(final Class clazz) { diff --git a/store/store-core/src/test/java/org/eclipse/lyo/store/SparqlStoreImplTest.java b/store/store-core/src/test/java/org/eclipse/lyo/store/SparqlStoreImplTest.java index 653d3d1e3..853c5e96f 100644 --- a/store/store-core/src/test/java/org/eclipse/lyo/store/SparqlStoreImplTest.java +++ b/store/store-core/src/test/java/org/eclipse/lyo/store/SparqlStoreImplTest.java @@ -11,9 +11,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; - import javax.xml.datatype.DatatypeConfigurationException; - import org.apache.jena.rdf.model.Model; import org.eclipse.lyo.oslc4j.core.exception.OslcCoreApplicationException; import org.eclipse.lyo.oslc4j.core.model.ServiceProvider; @@ -58,7 +56,8 @@ public void storeBasicOps() { sp.setCreated(new Date()); try { manager.putResources(testNg, Collections.singletonList(sp)); - final List providers = manager.getResources(testNg, ServiceProvider.class); + final List providers = + manager.getResources(testNg, ServiceProvider.class); assertThat(providers).hasSize(1); } catch (StoreAccessException | ModelUnmarshallingException e) { fail("Store failed", e); @@ -77,12 +76,17 @@ public void testInsertionPerf() { fail("Store failed", e); } } - System.out.printf("10 named graphs persisted (resources) in %s ms", Duration.between(start, Instant.now()).toMillis()); + System.out.printf( + "10 named graphs persisted (resources) in %s ms", + Duration.between(start, Instant.now()).toMillis()); } @Test - public void testInsertionPerfRaw() throws InvocationTargetException, DatatypeConfigurationException, - OslcCoreApplicationException, IllegalAccessException { + public void testInsertionPerfRaw() + throws InvocationTargetException, + DatatypeConfigurationException, + OslcCoreApplicationException, + IllegalAccessException { final List providers = genProviders(); final Model jenaModel = JenaModelHelper.createJenaModel(providers.toArray()); var start = Instant.now(); @@ -90,7 +94,44 @@ public void testInsertionPerfRaw() throws InvocationTargetException, DatatypeCon final URI testNg = URI.create("urn:test:" + i); manager.insertJenaModel(testNg, jenaModel); } - System.out.printf("10 named graphs persisted (raw Model) in %s ms", Duration.between(start, Instant.now()).toMillis()); + System.out.printf( + "10 named graphs persisted (raw Model) in %s ms", + Duration.between(start, Instant.now()).toMillis()); + } + + @Test + public void testRawUpdateQuery() throws StoreAccessException { + final URI testNg = URI.create("urn:test:rawupdate"); + + // Create a graph using raw SPARQL UPDATE + String createGraphQuery = "CREATE GRAPH <" + testNg + ">"; + manager.rawUpdateQuery(createGraphQuery); + + // Verify the graph was created but is empty (should not exist according to our logic) + assertThat(manager.namedGraphExists(testNg)) + .isFalse(); // Insert some data using raw SPARQL UPDATE + String insertDataQuery = + "INSERT DATA { GRAPH <" + + testNg + + "> { \"test" + + " value\" . } }"; + manager.rawUpdateQuery(insertDataQuery); + + // Now the graph should exist because it has data + assertThat(manager.namedGraphExists(testNg)).isTrue(); + + // Query the data to verify it was inserted + Model model = + manager.getJenaModelForSubject(testNg, URI.create("http://example.org/subject")); + assertThat(model).isNotNull(); + assertThat(model.isEmpty()).isFalse(); + + // Clean up using raw SPARQL UPDATE + String dropGraphQuery = "DROP GRAPH <" + testNg + ">"; + manager.rawUpdateQuery(dropGraphQuery); + + // Verify the graph was dropped + assertThat(manager.namedGraphExists(testNg)).isFalse(); } private List genProviders() { @@ -104,6 +145,4 @@ private List genProviders() { } return providers; } - - } diff --git a/store/store-core/src/test/java/org/eclipse/lyo/store/StoreRawUpdateQueryTest.java b/store/store-core/src/test/java/org/eclipse/lyo/store/StoreRawUpdateQueryTest.java new file mode 100644 index 000000000..924b23799 --- /dev/null +++ b/store/store-core/src/test/java/org/eclipse/lyo/store/StoreRawUpdateQueryTest.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 + * which is available at http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.eclipse.lyo.store; + +import static org.junit.jupiter.api.Assertions.*; + +import java.net.URI; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("Store Raw Update Query Tests") +public class StoreRawUpdateQueryTest { + + private Store store; + + @BeforeEach + public void setUp() { + store = StoreFactory.sparqlInMem(); + } + + @Test + @DisplayName("Test rawUpdateQuery creates and drops graphs") + public void testRawUpdateQueryGraphOperations() throws StoreAccessException { + final URI testGraph = URI.create("http://example.org/test/graph"); + + // Create graph using raw update query + String createQuery = "CREATE GRAPH <" + testGraph + ">"; + store.rawUpdateQuery(createQuery); + + // Verify graph doesn't exist (empty graphs are not considered existing) + assertFalse( + store.namedGraphExists(testGraph), "Empty graph should not exist after creation"); + + // Drop graph using raw update query + String dropQuery = "DROP GRAPH <" + testGraph + ">"; + store.rawUpdateQuery(dropQuery); + + // Verify graph no longer exists + assertFalse(store.namedGraphExists(testGraph), "Graph should not exist after dropping"); + } + + @Test + @DisplayName("Test rawUpdateQuery inserts and deletes data") + public void testRawUpdateQueryDataOperations() throws StoreAccessException { + final URI testGraph = URI.create("http://example.org/test/data"); + final URI subject = URI.create("http://example.org/test/subject"); + + // Create graph first + String createQuery = "CREATE GRAPH <" + testGraph + ">"; + store.rawUpdateQuery(createQuery); + + // Insert data using raw update query + String insertQuery = + "INSERT DATA { " + + "GRAPH <" + + testGraph + + "> { " + + "<" + + subject + + "> " + + " . <" + + subject + + "> \"test value\" . " + + "} }"; + store.rawUpdateQuery(insertQuery); + + // Verify data exists + assertTrue( + store.resourceExists(testGraph, subject), "Resource should exist after insertion"); + + // Delete specific triples using raw update query + String deleteQuery = + "DELETE DATA { " + + "GRAPH <" + + testGraph + + "> { " + + "<" + + subject + + "> \"test value\" . " + + "} }"; + store.rawUpdateQuery(deleteQuery); + + // Verify resource still exists (type triple should remain) + assertTrue( + store.resourceExists(testGraph, subject), + "Resource should still exist after partial deletion"); + + // Delete all triples for the subject + String deleteAllQuery = + "DELETE WHERE { " + + "GRAPH <" + + testGraph + + "> { " + + "<" + + subject + + "> ?p ?o . " + + "} }"; + store.rawUpdateQuery(deleteAllQuery); + + // Verify resource no longer exists + assertFalse( + store.resourceExists(testGraph, subject), + "Resource should not exist after complete deletion"); + } + + @Test + @DisplayName("Test rawUpdateQuery with CLEAR operation") + public void testRawUpdateQueryClearOperation() throws StoreAccessException { + final URI testGraph = URI.create("http://example.org/test/clear"); + final URI subject1 = URI.create("http://example.org/test/subject1"); + final URI subject2 = URI.create("http://example.org/test/subject2"); + + // Create graph and insert multiple resources + String setupQuery = + "INSERT DATA { " + + "GRAPH <" + + testGraph + + "> { " + + "<" + + subject1 + + "> " + + " . <" + + subject2 + + "> " + + " . } }"; + store.rawUpdateQuery(setupQuery); + + // Verify resources exist + assertTrue(store.resourceExists(testGraph, subject1), "Subject1 should exist before clear"); + assertTrue(store.resourceExists(testGraph, subject2), "Subject2 should exist before clear"); + + // Clear the graph using raw update query + String clearQuery = "CLEAR GRAPH <" + testGraph + ">"; + store.rawUpdateQuery( + clearQuery); // Verify graph is empty and no longer exists (empty graphs are not + // considered existing) + assertFalse(store.namedGraphExists(testGraph), "Graph should not exist after clear"); + assertFalse( + store.resourceExists(testGraph, subject1), "Subject1 should not exist after clear"); + assertFalse( + store.resourceExists(testGraph, subject2), "Subject2 should not exist after clear"); + } + + @Test + @DisplayName("Test rawUpdateQuery with complex SPARQL update") + public void testRawUpdateQueryComplexUpdate() throws StoreAccessException { + final URI testGraph = URI.create("http://example.org/test/complex"); + + // Create a complex update that creates graph, inserts data, and modifies it + String complexQuery = + "INSERT DATA { " + + "GRAPH <" + + testGraph + + "> { " + + " " + + " . " + + " \"John Doe\" . " + + " 30 . } } ; DELETE { GRAPH <" + + testGraph + + "> { " + + "?person ?oldAge . " + + "} } " + + "INSERT { " + + "GRAPH <" + + testGraph + + "> { " + + "?person ?newAge . " + + "} } " + + "WHERE { " + + "GRAPH <" + + testGraph + + "> { " + + "?person ?oldAge . " + + "BIND(?oldAge + 1 AS ?newAge) " + + "} }"; + + store.rawUpdateQuery(complexQuery); + + // Verify the complex update worked + URI person = URI.create("http://example.org/person/1"); + assertTrue( + store.resourceExists(testGraph, person), + "Person should exist after complex update"); + + // We can't easily verify the age was incremented without querying, + // but we can verify the resource still exists and the graph is valid + assertTrue(store.namedGraphExists(testGraph), "Graph should exist after complex update"); + } + + @Test + @DisplayName("Test rawUpdateQuery handles invalid SPARQL gracefully") + public void testRawUpdateQueryInvalidSparql() { + // Test that invalid SPARQL throws an appropriate exception + String invalidQuery = "INVALID SPARQL SYNTAX"; + + assertThrows( + Exception.class, + () -> { + store.rawUpdateQuery(invalidQuery); + }, + "Invalid SPARQL should throw an exception"); + } +} diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java new file mode 100644 index 000000000..bd55dca59 --- /dev/null +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 + * which is available at http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.eclipse.lyo.trs.client; + +import org.eclipse.lyo.trs.client.config.TrsConfigurationTest; +import org.eclipse.lyo.trs.client.handlers.sparql.SparqlBatchingHandlerTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +/** + * A test suite for TRS Client functionality that tests the migration from RDF4J to Lyo Store. + */ +@Suite +@SelectClasses({ + SparqlBatchingHandlerTest.class, + TrsConfigurationTest.class +}) +@DisplayName("TRS Client Migration Test Suite") +public class TrsClientMigrationTestSuite { + +} diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java new file mode 100644 index 000000000..b72d36bff --- /dev/null +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 + * which is available at http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.eclipse.lyo.trs.client.config; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +@DisplayName("TRS Configuration Tests") +public class TrsConfigurationTest { + + @TempDir + File tempDir; + + @Test + @DisplayName("Test TrsConfigurationLoader handles missing trs_uri") + public void testTrsConfigurationLoaderMissingTrsUri() throws IOException { + // Create a properties file without trs_uri + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("baseAuth_user=testuser\n"); + writer.write("baseAuth_password=testpass\n"); + } + + // Loading should throw IllegalStateException + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { + TrsConfigurationLoader.loadTrsConfiguration(configFile); + }); + + assertTrue(exception.getMessage().contains("trs_uri")); + assertTrue(exception.getMessage().contains("missing")); + } + + @Test + @DisplayName("Test TrsConfigurationLoader with valid configuration") + public void testTrsConfigurationLoaderValid() throws IOException { + // Create a valid properties file + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("trs_uri=http://example.org/trs\n"); + writer.write("baseAuth_user=testuser\n"); + writer.write("baseAuth_password=testpass\n"); + writer.write("sparql_query_url=http://example.org/sparql/query\n"); + writer.write("sparql_update_url=http://example.org/sparql/update\n"); + writer.write("sparql_username=sparqluser\n"); + writer.write("sparql_password=sparqlpass\n"); + } + + // Loading should succeed + TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + + assertNotNull(config); + assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); + assertEquals("testuser", config.getBasicUsername()); + assertEquals("testpass", config.getBasicPassword()); + assertEquals("http://example.org/sparql/query", config.getSparqlQueryUrl()); + assertEquals("http://example.org/sparql/update", config.getSparqlUpdateUrl()); + assertEquals("sparqluser", config.getSparqlUsername()); + assertEquals("sparqlpass", config.getSparqlPassword()); + } + + @Test + @DisplayName("Test TrsConfigurationLoader with minimal configuration") + public void testTrsConfigurationLoaderMinimal() throws IOException { + // Create a minimal properties file with only required trs_uri + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("trs_uri=http://example.org/trs\n"); + } + + // Loading should succeed + TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + + assertNotNull(config); + assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); + assertNull(config.getBasicUsername()); + assertNull(config.getBasicPassword()); + assertNull(config.getSparqlQueryUrl()); + assertNull(config.getSparqlUpdateUrl()); + assertNull(config.getSparqlUsername()); + assertNull(config.getSparqlPassword()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with null basic auth") + public void testTrsConsumerConfigurationNullAuth() { + TrsConsumerConfiguration config = new TrsConsumerConfiguration( + "http://example.org/sparql/query", + "http://example.org/sparql/update", + "sparqluser", + "sparqlpass", + null, // scheduler + null, // basicUsername + null // basicPassword + ); + + // getHttpClient should handle null basic auth gracefully + assertNotNull(config.getHttpClient()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with empty basic auth") + public void testTrsConsumerConfigurationEmptyAuth() { + TrsConsumerConfiguration config = new TrsConsumerConfiguration( + "http://example.org/sparql/query", + "http://example.org/sparql/update", + "sparqluser", + "sparqlpass", + null, // scheduler + "", // empty basicUsername + "" // empty basicPassword + ); + + // getHttpClient should handle empty basic auth gracefully + assertNotNull(config.getHttpClient()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with valid basic auth") + public void testTrsConsumerConfigurationValidAuth() { + TrsConsumerConfiguration config = new TrsConsumerConfiguration( + "http://example.org/sparql/query", + "http://example.org/sparql/update", + "sparqluser", + "sparqlpass", + null, // scheduler + "basicuser", + "basicpass" + ); + + // getHttpClient should configure basic auth + assertNotNull(config.getHttpClient()); + } +} diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java new file mode 100644 index 000000000..1ea80b2ae --- /dev/null +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0 + * which is available at http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.eclipse.lyo.trs.client.handlers.sparql; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; + +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.vocabulary.RDF; +import org.eclipse.lyo.core.trs.ChangeEvent; +import org.eclipse.lyo.core.trs.Creation; +import org.eclipse.lyo.core.trs.Deletion; +import org.eclipse.lyo.core.trs.Modification; +import org.eclipse.lyo.store.Store; +import org.eclipse.lyo.store.StoreFactory; +import org.eclipse.lyo.trs.client.model.BaseMember; +import org.eclipse.lyo.trs.client.model.ChangeEventMessageTR; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +@DisplayName("SparqlBatchingHandler Tests") +public class SparqlBatchingHandlerTest { + + private SparqlBatchingHandler handler; + private final String sparqlUpdateEndpoint = "http://example.org/sparql/update"; + private final String username = "testuser"; + private final String password = "testpass"; + + @BeforeEach + public void setUp() { + handler = new SparqlBatchingHandler(sparqlUpdateEndpoint, username, password); + } + + @Test + @DisplayName("Test SparqlBatchingHandler uses Lyo Store for finishCycle") + public void testFinishCycleUsesLyoStore() { + // Create mock Store + Store mockStore = mock(Store.class); + + // Mock StoreFactory.sparql method + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + // Add some test operations to create queries + BaseMember baseMember = createTestBaseMember(); + handler.handleBaseMember(baseMember); + + // Call finishCycle which should use the Store + handler.finishCycle(); + + // Verify that StoreFactory.sparql was called with correct parameters + mockedStoreFactory.verify(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)); + + // Verify that rawUpdateQuery was called on the store + verify(mockStore).rawUpdateQuery(anyString()); + + // Verify that close was called on the store + verify(mockStore).close(); + } + } + + @Test + @DisplayName("Test handleBaseMember creates proper queries") + public void testHandleBaseMember() { + BaseMember baseMember = createTestBaseMember(); + + // This should add queries to the internal list + handler.handleBaseMember(baseMember); + + // We can't directly test the internal queries list, but we can test + // that finishCycle processes them by mocking the Store + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + // Verify rawUpdateQuery was called with some query string + verify(mockStore).rawUpdateQuery(anyString()); + } + } + + @Test + @DisplayName("Test handleChangeEvent with Creation") + public void testHandleChangeEventCreation() throws URISyntaxException { + Creation creation = new Creation(); + creation.setChanged(new URI("http://example.org/resource/1")); + creation.setOrder(1); + + Model testModel = ModelFactory.createDefaultModel(); + testModel.add(testModel.createResource("http://example.org/resource/1"), + RDF.type, + testModel.createResource("http://example.org/TestType")); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(creation, testModel); + + handler.handleChangeEvent(eventMessage); + + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + verify(mockStore).rawUpdateQuery(anyString()); + } + } + + @Test + @DisplayName("Test handleChangeEvent with Deletion") + public void testHandleChangeEventDeletion() throws URISyntaxException { + Deletion deletion = new Deletion(); + deletion.setChanged(new URI("http://example.org/resource/1")); + deletion.setOrder(2); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(deletion, null); + + handler.handleChangeEvent(eventMessage); + + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + verify(mockStore).rawUpdateQuery(anyString()); + } + } + + @Test + @DisplayName("Test handleChangeEvent with Modification") + public void testHandleChangeEventModification() throws URISyntaxException { + Modification modification = new Modification(); + modification.setChanged(new URI("http://example.org/resource/1")); + modification.setOrder(3); + + Model testModel = ModelFactory.createDefaultModel(); + testModel.add(testModel.createResource("http://example.org/resource/1"), + RDF.type, + testModel.createResource("http://example.org/ModifiedType")); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(modification, testModel); + + handler.handleChangeEvent(eventMessage); + + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + verify(mockStore).rawUpdateQuery(anyString()); + } + } + + private BaseMember createTestBaseMember() { + try { + URI memberUri = new URI("http://example.org/basemember/1"); + Model model = ModelFactory.createDefaultModel(); + model.add(model.createResource(memberUri.toString()), + RDF.type, + model.createResource("http://example.org/TestResource")); + + return new BaseMember(memberUri, model); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } +} From 2b7ca6df3996ec4f2cde742f5761af273d4d7363 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Thu, 17 Jul 2025 00:20:36 +0200 Subject: [PATCH 7/9] fix: add StoreAccessException --- .../sparql/SparqlBatchingHandler.java | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java index e78a04874..6c8584b3d 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandler.java @@ -5,6 +5,7 @@ import org.eclipse.lyo.core.trs.ChangeEvent; import org.eclipse.lyo.core.trs.Deletion; import org.eclipse.lyo.store.Store; +import org.eclipse.lyo.store.StoreAccessException; import org.eclipse.lyo.store.StoreFactory; import org.eclipse.lyo.trs.client.handlers.IProviderEventHandler; import org.eclipse.lyo.trs.client.model.BaseMember; @@ -14,93 +15,92 @@ import org.slf4j.LoggerFactory; public class SparqlBatchingHandler implements IProviderEventHandler { - private static final Logger log = LoggerFactory.getLogger(SparqlBatchingHandler.class); + private static final Logger log = LoggerFactory.getLogger(SparqlBatchingHandler.class); - private final List queries = new ArrayList<>(); - private final String sparqlUpdateService; - private final String sparql_baseAuth_userName; - private final String sparql_baseAuth_pwd; + private final List queries = new ArrayList<>(); + private final String sparqlUpdateService; + private final String sparql_baseAuth_userName; + private final String sparql_baseAuth_pwd; - public SparqlBatchingHandler( - final String sparqlUpdateService, - final String sparql_baseAuth_userName, - final String sparql_baseAuth_pwd) { - this.sparqlUpdateService = sparqlUpdateService; - this.sparql_baseAuth_userName = sparql_baseAuth_userName; - this.sparql_baseAuth_pwd = sparql_baseAuth_pwd; - } + public SparqlBatchingHandler( + final String sparqlUpdateService, + final String sparql_baseAuth_userName, + final String sparql_baseAuth_pwd) { + this.sparqlUpdateService = sparqlUpdateService; + this.sparql_baseAuth_userName = sparql_baseAuth_userName; + this.sparql_baseAuth_pwd = sparql_baseAuth_pwd; + } - @Override - public void finishCycle() { - log.debug("number of processed queries: " + queries.size()); - String updateQuery = buildYugeQuery(queries); - log.debug("sending Update SPARQL Query to server"); + @Override + public void finishCycle() { + log.debug("number of processed queries: " + queries.size()); + String updateQuery = buildYugeQuery(queries); + log.debug("sending Update SPARQL Query to server"); - // TODO: build one or use a pool - Store store = - StoreFactory.sparql( - null, sparqlUpdateService, sparql_baseAuth_userName, sparql_baseAuth_pwd); - try { - store.rawUpdateQuery(updateQuery); - } finally { - store.close(); - } + // TODO: build one or use a pool + Store store = + StoreFactory.sparql( + null, sparqlUpdateService, sparql_baseAuth_userName, sparql_baseAuth_pwd); + try { + store.rawUpdateQuery(updateQuery); + } catch (StoreAccessException e) { + throw new RuntimeException(e); + } finally { + store.close(); + } - log.debug("Update SPARQL Queries successful!"); + log.debug("Update SPARQL Queries successful!"); - queries.clear(); - } + queries.clear(); + } - @Override - public void handleBaseMember(final BaseMember baseMember) { - StringBuilder query = new StringBuilder(); - String graphCreationQuery = SparqlUtil.createGraphQuery(baseMember.getUri()); - String addTriplesToGraphQuery = - SparqlUtil.addTriplesToGraphQuery(baseMember.getUri(), baseMember.getModel()); - query.append(graphCreationQuery); - query.append("; \n"); - query.append(addTriplesToGraphQuery); - queries.add(query.toString()); - } + @Override + public void handleBaseMember(final BaseMember baseMember) { + StringBuilder query = new StringBuilder(); + String graphCreationQuery = SparqlUtil.createGraphQuery(baseMember.getUri()); + String addTriplesToGraphQuery = + SparqlUtil.addTriplesToGraphQuery(baseMember.getUri(), baseMember.getModel()); + query.append(graphCreationQuery); + query.append("; \n"); + query.append(addTriplesToGraphQuery); + queries.add(query.toString()); + } - @Override - public void handleChangeEvent(final ChangeEventMessageTR eventMessageTR) { - final ChangeEvent event = eventMessageTR.getChangeEvent(); - log.debug( - "creating query for resource " + event.getChanged().toString() + " change event "); - if (event instanceof Deletion) { - String query = SparqlUtil.getChangeEventQuery(event, null); - queries.add(query); - } else { - String query = - SparqlUtil.getChangeEventQuery(event, eventMessageTR.getTrackedResourceModel()); - queries.add(query); - } + @Override + public void handleChangeEvent(final ChangeEventMessageTR eventMessageTR) { + final ChangeEvent event = eventMessageTR.getChangeEvent(); + log.debug("creating query for resource " + event.getChanged().toString() + " change event "); + if (event instanceof Deletion) { + String query = SparqlUtil.getChangeEventQuery(event, null); + queries.add(query); + } else { + String query = + SparqlUtil.getChangeEventQuery(event, eventMessageTR.getTrackedResourceModel()); + queries.add(query); } + } - @Override - public void rebase() { - log.warn("Rebase"); - } + @Override + public void rebase() { + log.warn("Rebase"); + } - private String buildYugeQuery(final List queries) { - StringBuilder queriesStringBuilder = new StringBuilder(); + private String buildYugeQuery(final List queries) { + StringBuilder queriesStringBuilder = new StringBuilder(); - for (String query : queries) { - queriesStringBuilder.append(query); - queriesStringBuilder.append("; \n"); - } + for (String query : queries) { + queriesStringBuilder.append(query); + queriesStringBuilder.append("; \n"); + } - // TODO simply join instead of append - or check for the last element - queriesStringBuilder.replace( - queriesStringBuilder.lastIndexOf("; \n"), - queriesStringBuilder.lastIndexOf("; \n") + 1, - ""); + // TODO simply join instead of append - or check for the last element + queriesStringBuilder.replace( + queriesStringBuilder.lastIndexOf("; \n"), queriesStringBuilder.lastIndexOf("; \n") + 1, ""); - // TODO Andrew@2018-02-28: this is a YUGE query that can crash everything - // I think individual queries are better executed in the handlers - String finalQueryString = queriesStringBuilder.toString(); - log.debug(finalQueryString); - return finalQueryString; - } + // TODO Andrew@2018-02-28: this is a YUGE query that can crash everything + // I think individual queries are better executed in the handlers + String finalQueryString = queriesStringBuilder.toString(); + log.debug(finalQueryString); + return finalQueryString; + } } From a0ce090f5fab7fcc74bdd7c671e8d56da9f9bec5 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Thu, 17 Jul 2025 00:20:45 +0200 Subject: [PATCH 8/9] chore: reformat --- .../client/config/TrsConfigurationLoader.java | 31 +- .../config/TrsConsumerConfiguration.java | 98 +- .../lyo/trs/client/util/SparqlUtil.java | 1216 ++++++++--------- .../client/TrsClientMigrationTestSuite.java | 9 +- .../client/config/TrsConfigurationTest.java | 201 +-- .../sparql/SparqlBatchingHandlerTest.java | 303 ++-- 6 files changed, 930 insertions(+), 928 deletions(-) diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java index 03d2d51c2..dbdee7f1e 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConfigurationLoader.java @@ -36,25 +36,24 @@ * @since 4.0.0 */ public class TrsConfigurationLoader { - public static TrsProviderConfiguration from(File f) throws IOException { - if (f == null) { - throw new IllegalArgumentException("File is null"); - } + public static TrsProviderConfiguration from(File f) throws IOException { + if (f == null) { + throw new IllegalArgumentException("File is null"); + } - try (InputStream input = new BufferedInputStream(new FileInputStream(f))) { - Properties p = new Properties(); - p.load(input); + try (InputStream input = new BufferedInputStream(new FileInputStream(f))) { + Properties p = new Properties(); + p.load(input); - String trsUriParam = p.getProperty("trs_uri"); - if (StringUtils.isNullOrEmpty(trsUriParam)) { - throw new IllegalStateException( - "The 'trs_uri' field is missing in file " + f.getName()); - } + String trsUriParam = p.getProperty("trs_uri"); + if (StringUtils.isNullOrEmpty(trsUriParam)) { + throw new IllegalStateException("The 'trs_uri' field is missing in file " + f.getName()); + } - String user = p.getProperty("baseAuth_user"); - String pass = p.getProperty("baseAuth_pwd"); + String user = p.getProperty("baseAuth_user"); + String pass = p.getProperty("baseAuth_pwd"); - return new TrsProviderConfiguration(URI.create(trsUriParam), user, pass); - } + return new TrsProviderConfiguration(URI.create(trsUriParam), user, pass); } + } } diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java index 95196bab4..3112bdfaa 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/config/TrsConsumerConfiguration.java @@ -21,61 +21,61 @@ import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; public class TrsConsumerConfiguration { - private final String sparqlQueryUrl; - private final String sparqlUpdateUrl; - private final String sparqlUsername; - private final String sparqlPassword; - private final ScheduledExecutorService scheduler; - private final String basicUsername; - private final String basicPassword; - private OslcClient httpClient; + private final String sparqlQueryUrl; + private final String sparqlUpdateUrl; + private final String sparqlUsername; + private final String sparqlPassword; + private final ScheduledExecutorService scheduler; + private final String basicUsername; + private final String basicPassword; + private OslcClient httpClient; - public TrsConsumerConfiguration( - final String sparqlQueryUrl, - final String sparqlUpdateUrl, - final String sparqlUsername, - final String sparqlPassword, - final ScheduledExecutorService scheduler, - final String basicUsername, - final String basicPassword) { - this.sparqlQueryUrl = sparqlQueryUrl; - this.sparqlUpdateUrl = sparqlUpdateUrl; - this.sparqlUsername = sparqlUsername; - this.sparqlPassword = sparqlPassword; - this.scheduler = scheduler; - this.basicUsername = basicUsername; - this.basicPassword = basicPassword; - } + public TrsConsumerConfiguration( + final String sparqlQueryUrl, + final String sparqlUpdateUrl, + final String sparqlUsername, + final String sparqlPassword, + final ScheduledExecutorService scheduler, + final String basicUsername, + final String basicPassword) { + this.sparqlQueryUrl = sparqlQueryUrl; + this.sparqlUpdateUrl = sparqlUpdateUrl; + this.sparqlUsername = sparqlUsername; + this.sparqlPassword = sparqlPassword; + this.scheduler = scheduler; + this.basicUsername = basicUsername; + this.basicPassword = basicPassword; + } - public ScheduledExecutorService getScheduler() { - return scheduler; - } + public ScheduledExecutorService getScheduler() { + return scheduler; + } - public String getSparqlQueryUrl() { - return sparqlQueryUrl; - } + public String getSparqlQueryUrl() { + return sparqlQueryUrl; + } - public String getSparqlUpdateUrl() { - return sparqlUpdateUrl; - } + public String getSparqlUpdateUrl() { + return sparqlUpdateUrl; + } - public String getSparqlUsername() { - return sparqlUsername; - } + public String getSparqlUsername() { + return sparqlUsername; + } - public String getSparqlPassword() { - return sparqlPassword; - } + public String getSparqlPassword() { + return sparqlPassword; + } - // TODO Andrew@2019-07-15: create a client factory per domain or something similar - public OslcClient getHttpClient() { - if (httpClient == null) { - final ClientBuilder builder = ClientBuilder.newBuilder(); - if (!StringUtils.isNullOrEmpty(basicUsername)) { - builder.register(HttpAuthenticationFeature.basic(basicUsername, basicPassword)); - } - httpClient = new OslcClient(builder); - } - return httpClient; + // TODO Andrew@2019-07-15: create a client factory per domain or something similar + public OslcClient getHttpClient() { + if (httpClient == null) { + final ClientBuilder builder = ClientBuilder.newBuilder(); + if (!StringUtils.isNullOrEmpty(basicUsername)) { + builder.register(HttpAuthenticationFeature.basic(basicUsername, basicPassword)); + } + httpClient = new OslcClient(builder); } + return httpClient; + } } diff --git a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java index 11075a999..9d6b07f34 100644 --- a/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java +++ b/trs/client/trs-client/src/main/java/org/eclipse/lyo/trs/client/util/SparqlUtil.java @@ -41,616 +41,616 @@ */ public class SparqlUtil { - static Logger logger = LoggerFactory.getLogger(SparqlUtil.class); - - /** - * returns the sparql query for the creation of the named graph with the - * given name as a String - * - * @param namedGraphUrl - * name of the named graph to be created - * @return the graph creation sparql query as a string - */ - public static String createGraphQuery(String namedGraphUrl) { - String query = "CREATE GRAPH <" + namedGraphUrl + ">"; - logger.debug("query for creation of graph: " + namedGraphUrl); - logger.debug(query); - return query; + static Logger logger = LoggerFactory.getLogger(SparqlUtil.class); + + /** + * returns the sparql query for the creation of the named graph with the + * given name as a String + * + * @param namedGraphUrl + * name of the named graph to be created + * @return the graph creation sparql query as a string + */ + public static String createGraphQuery(String namedGraphUrl) { + String query = "CREATE GRAPH <" + namedGraphUrl + ">"; + logger.debug("query for creation of graph: " + namedGraphUrl); + logger.debug(query); + return query; + } + + public static String createGraphQuery(URI namedGraphUrl) { + return createGraphQuery(namedGraphUrl.toASCIIString()); + } + + /** + * returns the query deleting siltently the graph with the given name + * + * @param namedGraphUrl + * the name of the graph to be deleted + * @return the deletion query as a string + */ + public static String dropGraphQuery(String namedGraphUrl) { + String query = "DROP GRAPH <" + namedGraphUrl + ">"; + logger.debug("query for removal of graph: " + namedGraphUrl); + logger.debug(query); + return query; + } + + /** + * returns the sparql query removing all the triples in the requested graph + * as a string + * + * @param namedGraphUrl + * graph to be emptied + * @return the query for emptying the graph + */ + public static String removeAllTriplesInGraphQuery(String namedGraphUrl) { + String query = + "WITH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "DELETE" + + "\n" + + "{?s ?p ?o }" + + "\n" + + "WHERE" + + "\n" + + "{" + + "\n" + + "GRAPH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "{" + + "\n" + + "?s ?p ?o" + + "\n" + + "}" + + "\n" + + "}" + + "\n"; + logger.debug("query for removal of all triples from graph: " + namedGraphUrl); + logger.debug(query); + return query; + } + + /** + * Gets an rdf model and a named graph as arguments and returns a sparql + * query for adding the statements of the rdf model to the named graph + * + * @param namedGraphUrl + * named graph to which the statements shall be added + * @param jenaModel + * the rdf model of which statements are to be added to the named + * graph + * @return the sparql update + */ + public static String addTriplesToGraphQuery(String namedGraphUrl, Model jenaModel) { + try { + String nTripleRepresentation = RdfUtil.modelToNTriple(jenaModel); + return addTriplesToGraphQuery(namedGraphUrl, nTripleRepresentation); + } catch (IOException e) { + logger.error("Cannot append triples from the model to the query", e); + return null; } - - public static String createGraphQuery(URI namedGraphUrl) { - return createGraphQuery(namedGraphUrl.toASCIIString()); - } - - /** - * returns the query deleting siltently the graph with the given name - * - * @param namedGraphUrl - * the name of the graph to be deleted - * @return the deletion query as a string - */ - public static String dropGraphQuery(String namedGraphUrl) { - String query = "DROP GRAPH <" + namedGraphUrl + ">"; - logger.debug("query for removal of graph: " + namedGraphUrl); - logger.debug(query); - return query; + } + + public static String addTriplesToGraphQuery(URI namedGraphUrl, Model jenaModel) { + return addTriplesToGraphQuery(namedGraphUrl.toASCIIString(), jenaModel); + } + + /** + * Gets a set of statements and a named graph as arguments and returns a + * sparql query for adding the statements to the named graph + * + * @param namedGraphUrl + * named graph to which the statements shall be added + * @param triples + * statements to be added to the named graph + * @return the sparql update + */ + public static String addTriplesToGraphQuery(String namedGraphUrl, String triples) { + String query = + "INSERT DATA" + + "\n" + + "{" + + "\n" + + " GRAPH" + + " " + + "<" + + namedGraphUrl + + ">" + + "\n" + + "{" + + "\n" + + triples + + "\n" + + "}" + + "\n" + + "}"; + logger.debug("query for creation of triples in graph: " + namedGraphUrl); + logger.debug(query); + return query; + } + + /** + * For a change event return a sparql update relfecting the change event. + * + * @param changeEvent + * the change event for which the sparql update is created + * @param model + * the rdf model corresponding to the updated representation of + * the changed resource if applicable ( no rdf model is needed + * for a deletion event) + * @return the sparql update + */ + public static String getChangeEventQuery(ChangeEvent changeEvent, Model model) { + + if (changeEvent instanceof Creation) { + return getCreationEventQuery(changeEvent, model); + } else if (changeEvent instanceof Deletion) { + return getDeletionEventQuery(changeEvent); + } else if (changeEvent instanceof Modification) { + return getModificationEventQuery(changeEvent, model); } - - /** - * returns the sparql query removing all the triples in the requested graph - * as a string - * - * @param namedGraphUrl - * graph to be emptied - * @return the query for emptying the graph - */ - public static String removeAllTriplesInGraphQuery(String namedGraphUrl) { - String query = - "WITH" - + " " - + "<" - + namedGraphUrl - + ">" - + "\n" - + "DELETE" - + "\n" - + "{?s ?p ?o }" - + "\n" - + "WHERE" - + "\n" - + "{" - + "\n" - + "GRAPH" - + " " - + "<" - + namedGraphUrl - + ">" - + "\n" - + "{" - + "\n" - + "?s ?p ?o" - + "\n" - + "}" - + "\n" - + "}" - + "\n"; - logger.debug("query for removal of all triples from graph: " + namedGraphUrl); - logger.debug(query); - return query; - } - - /** - * Gets an rdf model and a named graph as arguments and returns a sparql - * query for adding the statements of the rdf model to the named graph - * - * @param namedGraphUrl - * named graph to which the statements shall be added - * @param jenaModel - * the rdf model of which statements are to be added to the named - * graph - * @return the sparql update - */ - public static String addTriplesToGraphQuery(String namedGraphUrl, Model jenaModel) { - try { - String nTripleRepresentation = RdfUtil.modelToNTriple(jenaModel); - return addTriplesToGraphQuery(namedGraphUrl, nTripleRepresentation); - } catch (IOException e) { - logger.error("Cannot append triples from the model to the query", e); - return null; - } + return null; + } + + /** + * For a modification event return a sparql update relfecting the change + * event. + * + * @param changeEvent + * the change event for which the sparql update is created + * @param model + * the rdf model corresponding to the updated representation of + * the changed resource + * @return the sparql update + */ + public static String getModificationEventQuery(ChangeEvent changeEvent, Model model) { + String result = ""; + String changeEventTarget = changeEvent.getChanged().toString(); + String dropGraphQuery = dropGraphQuery(changeEventTarget); + String addGraphQuery = createGraphQuery(changeEventTarget); + String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, model); + + result = result.concat(dropGraphQuery); + result = result.concat(";" + "\n"); + result = result.concat(addGraphQuery); + result = result.concat(";" + "\n"); + result = result.concat(addTriplesToNamedGraphQuery); + + return result; + } + + /** + * For a modification event return a sparql update relfecting the change + * event. + * + * @param changeEvent + * the change event for which the sparql update is created + * @param triples + * the rdf model in n triples corresponding to the updated + * representation of the changed resource + * @return the sparql update + */ + public static String getModificationEventQuery(ChangeEvent changeEvent, String triples) { + + String changeEventTarget = changeEvent.getChanged().toString(); + return getModificationEventQuery(changeEventTarget, triples); + } + + /** + * For a modification event target return a sparql update relfecting the + * change event. + * + * @param changeEventTarget + * the change resource for which the sparql update is created + * @param triples + * the rdf model in n triples corresponding to the updated + * representation of the changed resource + * @return the sparql update + */ + public static String getModificationEventQuery(String changeEventTarget, String triples) { + String result = ""; + String dropGraphQuery = dropGraphQuery(changeEventTarget); + String addGraphQuery = createGraphQuery(changeEventTarget); + String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, triples); + + result = result.concat(dropGraphQuery); + result = result.concat(";" + "\n"); + result = result.concat(addGraphQuery); + result = result.concat(";" + "\n"); + result = result.concat(addTriplesToNamedGraphQuery); + + return result; + } + + /** + * * For a creation event return a sparql update reflecting the change + * event. + * + * @param changeEvent + * change event for which update will be created + * @param model + * updated rdf representation of the changed resource + * @return + */ + public static String getCreationEventQuery(ChangeEvent changeEvent, Model model) { + String result = ""; + + String changeEventTarget = changeEvent.getChanged().toString(); + String addGraphQuery = createGraphQuery(changeEventTarget); + String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, model); + + result = result.concat(addGraphQuery); + result = result.concat(";" + "\n"); + result = result.concat(addTriplesToNamedGraphQuery); + + return result; + } + + /** + * For a deletion event return a sparql update relfecting the change event. + * + * @param changeEvent + * the deletion change event for which the sparql update is + * created + * @return the sparql update + */ + public static String getDeletionEventQuery(ChangeEvent changeEvent) { + String result = ""; + + String changeEventTarget = changeEvent.getChanged().toString(); + + String dropGraphQuery = dropGraphQuery(changeEventTarget); + + result = result.concat(dropGraphQuery); + + return result; + } + + /** + * create a graph creation of the graph with the specified name sparql + * update and post it to the given service url + * + * @param namedGraphUrl + * name of the graph to be created + * @param serviceUrl + * sparql update endpoint url + */ + public static void createGraph(String namedGraphUrl, String serviceUrl) { + UpdateRequest request = UpdateFactory.create(); + request.add(createGraphQuery(namedGraphUrl)); + UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); + processor.execute(); + } + + /** + * create a graph creation of the graph with the specified name sparql + * update and post it to the given service url + * + * @param namedGraphUrl + * name of the graph to be deleted + * @param serviceUrl + * sparql update endpoint url + */ + public static void dropGraph(String namedGraphUrl, String serviceUrl) { + UpdateRequest request = UpdateFactory.create(); + request.add(dropGraphQuery(namedGraphUrl)); + UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); + processor.execute(); + } + + /** + * create a spaql update adding the triples in the given rdf model to the + * graph with the given name and send it to the specified sparql update + * endpoint + * + * @param jenaModel + * the triples to be added to the named graph + * @param namedGraphUrl + * the named graph to which the triples shall be added + * @param serviceUrl + * the sparql update endpoint + */ + public static void addTriplesToNamedGraph( + Model jenaModel, String namedGraphUrl, String serviceUrl) { + UpdateRequest request = UpdateFactory.create(); + request.add(addTriplesToGraphQuery(namedGraphUrl, jenaModel)); + UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); + processor.execute(); + } + + /** + * create a spaql update removing all triples from the graph with the given + * name and send it to the specified sparql update endpoint + * + * @param namedGraphUrl + * the named graph that shall be emptied + * @param serviceUrl + * the sparql update endpoint + */ + public static void removeAllTriplesInNamedGraph(String namedGraphUrl, String serviceUrl) { + UpdateRequest request = UpdateFactory.create(); + request.add(removeAllTriplesInGraphQuery(namedGraphUrl)); + UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); + processor.execute(); + } + + /** + * create a spaql update reflecting the given change event and send it to + * the sparql update endpoint + * + * @param changeEvent + * the change event to be processed + * @param model + * the updated representation of the changed resource if + * applicable + * @param serviceUrl + * the sparql update endpoint + */ + public static void processChangeEvent(ChangeEvent changeEvent, Model model, String serviceUrl) { + String changeEventQuery = getChangeEventQuery(changeEvent, model); + processQuery(changeEventQuery, serviceUrl); + } + + /** + * Send the given sparql update to the sparql update service using the jena + * arq libraries + * + * @param query + * sparql update to be processeda + * @param serviceUrl + * sparql update endpoint for processing the sparql update + */ + public static void processQuery(String query, String serviceUrl) { + UpdateRequest request = UpdateFactory.create(); + request.add(query); + UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); + processor.execute(); + } + + /** + * Send the given sparql update to the sparql update service using the + * sesame libraries + * + * @param query + * sparql update to be processeda + * @param serviceUrl + * sparql update endpoint for processing the sparql update + * @param user + * username for authentication if applicable + * @param pwd + * password for authentication if applicable + */ + // static public void processQuery_sesame(String query, String serviceUrl, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(serviceUrl); + // repo.setUsernameAndPassword(user, pwd); + // repo.initialize(); + // RepositoryConnection rc = repo.getConnection(); + // processQuery_sesame(query, rc); + // } + + /** + * Send the given sparql update to the sparql update service using the + * sesame libraries + * + * @param query + * sparql update to be processeda + * @param conn + * the repository connection object holding credentials and the + * sparql update endpoint + */ + // static public void processQuery_sesame(String query, RepositoryConnection conn) { + // Update u = conn.prepareUpdate(query); + // u.execute(); + // } + + /** + * return the repo connection object in order to be able to use the sesame + * client libraries + * + * @param queryEndpoint + * the sparl query endpoint + * @param user + * username for authentication if applicable + * @param pwd + * password for authentication if applicable + * @return + */ + // public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(queryEndpoint); + // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { + // repo.setUsernameAndPassword("okacimi", "nohheis4ae"); + // } + // repo.initialize(); + // try { + // RepositoryConnection conn = repo.getConnection(); + // if (conn == null) { + // logger.error("error getting sparql repo connection !"); + // } + // return conn; + // } catch (Exception e) { + // logger.error("error getting sparql repo connection !", e); + // return null; + // } + // } + + /** + * return the repo connection object in order to be able to use the sesame + * client libraries + * + * @param queryEndpoint + * the sparl query endpoint + * @param user + * username for authentication if applicable + * @param pwd + * password for authentication if applicable + * @return + */ + // public static RepositoryConnection getRepoConnection(String queryEndpoint, String + // updateEndPoint, String user, + // String pwd) { + // SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); + // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && + // !user.isEmpty()) { + // repo.setUsernameAndPassword(user, pwd); + // } + // repo.initialize(); + // try { + // RepositoryConnection conn = repo.getConnection(); + // + // if (conn == null) { + // logger.error("error getting sparql repo connection !"); + // } + // return conn; + // } catch (Exception e) { + // logger.error("error getting sparql repo connection !", e); + // return null; + // } + // } + + /** + * evaluate the given sparql query against the given sparql query endpoint + * + * @param queryEndpoint + * sparql query endpoint + * @param user + * username for authentication if applicable + * @param pwd + * password for authentication if applicable + * @param query + * sparql query + * @return the result of the querie's evaluation + */ + // public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, + // String query) { + // RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); + // TupleQueryResult result = null; + // try { + // + // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } finally { + // conn.close(); + // } + // return result; + // } + + /** + * evaluate the given sparql update using the sesame repository connection + * object + * + * @param conn + * repo connection sesame object + * @param sparqlQuery + * sparql update to evaluate + */ + // public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { + // try { + // + // conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } + // } + + /** + * evaluate the given sparql query using the sesame repository connection + * object + * + * @param conn + * repo connection sesame object + * @param sparqlQuery + * sparql query to evaluate + * @return the queri's evaluation result + */ + // public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { + // TupleQueryResult result = null; + // try { + // + // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); + // + // } catch (Exception e) { + // logger.error("error during the execution of the query !", e); + // } + // + // return result; + // } + + /** + * append a sparql update to another + * + * @param appending + * the original sparql update + * @param appended + * the sparql update to be appended + * @return the concatnated sparql update + */ + public static String appendSparqldQuery(String appending, String appended) { + if (appending != null && !appending.isEmpty()) { + if (!appending.endsWith(";")) { + appending = appending.concat(";"); + } + + if (!appending.endsWith("\n")) { + appending = appending.concat("\n"); + } } - public static String addTriplesToGraphQuery(URI namedGraphUrl, Model jenaModel) { - return addTriplesToGraphQuery(namedGraphUrl.toASCIIString(), jenaModel); - } - - /** - * Gets a set of statements and a named graph as arguments and returns a - * sparql query for adding the statements to the named graph - * - * @param namedGraphUrl - * named graph to which the statements shall be added - * @param triples - * statements to be added to the named graph - * @return the sparql update - */ - public static String addTriplesToGraphQuery(String namedGraphUrl, String triples) { - String query = - "INSERT DATA" - + "\n" - + "{" - + "\n" - + " GRAPH" - + " " - + "<" - + namedGraphUrl - + ">" - + "\n" - + "{" - + "\n" - + triples - + "\n" - + "}" - + "\n" - + "}"; - logger.debug("query for creation of triples in graph: " + namedGraphUrl); - logger.debug(query); - return query; - } - - /** - * For a change event return a sparql update relfecting the change event. - * - * @param changeEvent - * the change event for which the sparql update is created - * @param model - * the rdf model corresponding to the updated representation of - * the changed resource if applicable ( no rdf model is needed - * for a deletion event) - * @return the sparql update - */ - public static String getChangeEventQuery(ChangeEvent changeEvent, Model model) { - - if (changeEvent instanceof Creation) { - return getCreationEventQuery(changeEvent, model); - } else if (changeEvent instanceof Deletion) { - return getDeletionEventQuery(changeEvent); - } else if (changeEvent instanceof Modification) { - return getModificationEventQuery(changeEvent, model); - } - return null; - } - - /** - * For a modification event return a sparql update relfecting the change - * event. - * - * @param changeEvent - * the change event for which the sparql update is created - * @param model - * the rdf model corresponding to the updated representation of - * the changed resource - * @return the sparql update - */ - public static String getModificationEventQuery(ChangeEvent changeEvent, Model model) { - String result = ""; - String changeEventTarget = changeEvent.getChanged().toString(); - String dropGraphQuery = dropGraphQuery(changeEventTarget); - String addGraphQuery = createGraphQuery(changeEventTarget); - String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, model); - - result = result.concat(dropGraphQuery); - result = result.concat(";" + "\n"); - result = result.concat(addGraphQuery); - result = result.concat(";" + "\n"); - result = result.concat(addTriplesToNamedGraphQuery); - - return result; - } - - /** - * For a modification event return a sparql update relfecting the change - * event. - * - * @param changeEvent - * the change event for which the sparql update is created - * @param triples - * the rdf model in n triples corresponding to the updated - * representation of the changed resource - * @return the sparql update - */ - public static String getModificationEventQuery(ChangeEvent changeEvent, String triples) { - - String changeEventTarget = changeEvent.getChanged().toString(); - return getModificationEventQuery(changeEventTarget, triples); - } - - /** - * For a modification event target return a sparql update relfecting the - * change event. - * - * @param changeEventTarget - * the change resource for which the sparql update is created - * @param triples - * the rdf model in n triples corresponding to the updated - * representation of the changed resource - * @return the sparql update - */ - public static String getModificationEventQuery(String changeEventTarget, String triples) { - String result = ""; - String dropGraphQuery = dropGraphQuery(changeEventTarget); - String addGraphQuery = createGraphQuery(changeEventTarget); - String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, triples); - - result = result.concat(dropGraphQuery); - result = result.concat(";" + "\n"); - result = result.concat(addGraphQuery); - result = result.concat(";" + "\n"); - result = result.concat(addTriplesToNamedGraphQuery); - - return result; - } - - /** - * * For a creation event return a sparql update reflecting the change - * event. - * - * @param changeEvent - * change event for which update will be created - * @param model - * updated rdf representation of the changed resource - * @return - */ - public static String getCreationEventQuery(ChangeEvent changeEvent, Model model) { - String result = ""; - - String changeEventTarget = changeEvent.getChanged().toString(); - String addGraphQuery = createGraphQuery(changeEventTarget); - String addTriplesToNamedGraphQuery = addTriplesToGraphQuery(changeEventTarget, model); - - result = result.concat(addGraphQuery); - result = result.concat(";" + "\n"); - result = result.concat(addTriplesToNamedGraphQuery); - - return result; - } - - /** - * For a deletion event return a sparql update relfecting the change event. - * - * @param changeEvent - * the deletion change event for which the sparql update is - * created - * @return the sparql update - */ - public static String getDeletionEventQuery(ChangeEvent changeEvent) { - String result = ""; - - String changeEventTarget = changeEvent.getChanged().toString(); - - String dropGraphQuery = dropGraphQuery(changeEventTarget); - - result = result.concat(dropGraphQuery); - - return result; - } - - /** - * create a graph creation of the graph with the specified name sparql - * update and post it to the given service url - * - * @param namedGraphUrl - * name of the graph to be created - * @param serviceUrl - * sparql update endpoint url - */ - public static void createGraph(String namedGraphUrl, String serviceUrl) { - UpdateRequest request = UpdateFactory.create(); - request.add(createGraphQuery(namedGraphUrl)); - UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); - processor.execute(); - } - - /** - * create a graph creation of the graph with the specified name sparql - * update and post it to the given service url - * - * @param namedGraphUrl - * name of the graph to be deleted - * @param serviceUrl - * sparql update endpoint url - */ - public static void dropGraph(String namedGraphUrl, String serviceUrl) { - UpdateRequest request = UpdateFactory.create(); - request.add(dropGraphQuery(namedGraphUrl)); - UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); - processor.execute(); - } - - /** - * create a spaql update adding the triples in the given rdf model to the - * graph with the given name and send it to the specified sparql update - * endpoint - * - * @param jenaModel - * the triples to be added to the named graph - * @param namedGraphUrl - * the named graph to which the triples shall be added - * @param serviceUrl - * the sparql update endpoint - */ - public static void addTriplesToNamedGraph( - Model jenaModel, String namedGraphUrl, String serviceUrl) { - UpdateRequest request = UpdateFactory.create(); - request.add(addTriplesToGraphQuery(namedGraphUrl, jenaModel)); - UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); - processor.execute(); - } - - /** - * create a spaql update removing all triples from the graph with the given - * name and send it to the specified sparql update endpoint - * - * @param namedGraphUrl - * the named graph that shall be emptied - * @param serviceUrl - * the sparql update endpoint - */ - public static void removeAllTriplesInNamedGraph(String namedGraphUrl, String serviceUrl) { - UpdateRequest request = UpdateFactory.create(); - request.add(removeAllTriplesInGraphQuery(namedGraphUrl)); - UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); - processor.execute(); - } - - /** - * create a spaql update reflecting the given change event and send it to - * the sparql update endpoint - * - * @param changeEvent - * the change event to be processed - * @param model - * the updated representation of the changed resource if - * applicable - * @param serviceUrl - * the sparql update endpoint - */ - public static void processChangeEvent(ChangeEvent changeEvent, Model model, String serviceUrl) { - String changeEventQuery = getChangeEventQuery(changeEvent, model); - processQuery(changeEventQuery, serviceUrl); - } - - /** - * Send the given sparql update to the sparql update service using the jena - * arq libraries - * - * @param query - * sparql update to be processeda - * @param serviceUrl - * sparql update endpoint for processing the sparql update - */ - public static void processQuery(String query, String serviceUrl) { - UpdateRequest request = UpdateFactory.create(); - request.add(query); - UpdateProcessor processor = UpdateExecutionFactory.createRemote(request, serviceUrl); - processor.execute(); - } - - /** - * Send the given sparql update to the sparql update service using the - * sesame libraries - * - * @param query - * sparql update to be processeda - * @param serviceUrl - * sparql update endpoint for processing the sparql update - * @param user - * username for authentication if applicable - * @param pwd - * password for authentication if applicable - */ - // static public void processQuery_sesame(String query, String serviceUrl, String user, - // String pwd) { - // SPARQLRepository repo = new SPARQLRepository(serviceUrl); - // repo.setUsernameAndPassword(user, pwd); - // repo.initialize(); - // RepositoryConnection rc = repo.getConnection(); - // processQuery_sesame(query, rc); - // } - - /** - * Send the given sparql update to the sparql update service using the - * sesame libraries - * - * @param query - * sparql update to be processeda - * @param conn - * the repository connection object holding credentials and the - * sparql update endpoint - */ - // static public void processQuery_sesame(String query, RepositoryConnection conn) { - // Update u = conn.prepareUpdate(query); - // u.execute(); - // } - - /** - * return the repo connection object in order to be able to use the sesame - * client libraries - * - * @param queryEndpoint - * the sparl query endpoint - * @param user - * username for authentication if applicable - * @param pwd - * password for authentication if applicable - * @return - */ - // public static RepositoryConnection getRepoConnection(String queryEndpoint, String user, - // String pwd) { - // SPARQLRepository repo = new SPARQLRepository(queryEndpoint); - // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty()) { - // repo.setUsernameAndPassword("okacimi", "nohheis4ae"); - // } - // repo.initialize(); - // try { - // RepositoryConnection conn = repo.getConnection(); - // if (conn == null) { - // logger.error("error getting sparql repo connection !"); - // } - // return conn; - // } catch (Exception e) { - // logger.error("error getting sparql repo connection !", e); - // return null; - // } - // } - - /** - * return the repo connection object in order to be able to use the sesame - * client libraries - * - * @param queryEndpoint - * the sparl query endpoint - * @param user - * username for authentication if applicable - * @param pwd - * password for authentication if applicable - * @return - */ - // public static RepositoryConnection getRepoConnection(String queryEndpoint, String - // updateEndPoint, String user, - // String pwd) { - // SPARQLRepository repo = new SPARQLRepository(queryEndpoint, updateEndPoint); - // if (user != null && pwd != null && !user.isEmpty() && !pwd.isEmpty() && - // !user.isEmpty()) { - // repo.setUsernameAndPassword(user, pwd); - // } - // repo.initialize(); - // try { - // RepositoryConnection conn = repo.getConnection(); - // - // if (conn == null) { - // logger.error("error getting sparql repo connection !"); - // } - // return conn; - // } catch (Exception e) { - // logger.error("error getting sparql repo connection !", e); - // return null; - // } - // } - - /** - * evaluate the given sparql query against the given sparql query endpoint - * - * @param queryEndpoint - * sparql query endpoint - * @param user - * username for authentication if applicable - * @param pwd - * password for authentication if applicable - * @param query - * sparql query - * @return the result of the querie's evaluation - */ - // public static TupleQueryResult evalQuery(String queryEndpoint, String user, String pwd, - // String query) { - // RepositoryConnection conn = getRepoConnection(queryEndpoint, user, pwd, query); - // TupleQueryResult result = null; - // try { - // - // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); - // } catch (Exception e) { - // logger.error("error during the execution of the query !", e); - // } finally { - // conn.close(); - // } - // return result; - // } - - /** - * evaluate the given sparql update using the sesame repository connection - * object - * - * @param conn - * repo connection sesame object - * @param sparqlQuery - * sparql update to evaluate - */ - // public static void evalUpdate(RepositoryConnection conn, String sparqlQuery) { - // try { - // - // conn.prepareUpdate(QueryLanguage.SPARQL, sparqlQuery).execute(); - // } catch (Exception e) { - // logger.error("error during the execution of the query !", e); - // } - // } - - /** - * evaluate the given sparql query using the sesame repository connection - * object - * - * @param conn - * repo connection sesame object - * @param sparqlQuery - * sparql query to evaluate - * @return the queri's evaluation result - */ - // public static TupleQueryResult evalQuery(RepositoryConnection conn, String sparqlQuery) { - // TupleQueryResult result = null; - // try { - // - // result = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparqlQuery).evaluate(); - // - // } catch (Exception e) { - // logger.error("error during the execution of the query !", e); - // } - // - // return result; - // } - - /** - * append a sparql update to another - * - * @param appending - * the original sparql update - * @param appended - * the sparql update to be appended - * @return the concatnated sparql update - */ - public static String appendSparqldQuery(String appending, String appended) { - if (appending != null && !appending.isEmpty()) { - if (!appending.endsWith(";")) { - appending = appending.concat(";"); - } - - if (!appending.endsWith("\n")) { - appending = appending.concat("\n"); - } - } - - appending = appending.concat(appended); - - return appending; - } - - /** - * Create a sparql update ading the triples to the named graph with the - * specified name and send it to the sparql update endpoint specified using - * the given repo connection object. Uses the sesame libraries - * - * @param conn - * sesame repo connection object - * @param triples - * triples to be added to the named graph - * @param graphName - * named graph to which the triples shall be added - */ - // public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String - // graphName) { - // String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); - // SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); - // } - - /** - * Create a triple with the link type as a predicate the src as subject and - * destination as object. This is a conveniece for enabling the creation of - * links in a ageneric way - * - * @param src - * source of the link - * @param dst - * destination of the link - * @param linkType - * type of the link - * @return the rdf triple as n triple - */ - public static String linkTriple(String src, String dst, String linkType) { - StringBuilder sb = new StringBuilder(); - sb.append("<" + src + ">"); - sb.append(" "); - sb.append("<" + linkType + ">"); - sb.append(" "); - sb.append("<" + dst + ">"); - sb.append(" ."); - return sb.toString(); - } + appending = appending.concat(appended); + + return appending; + } + + /** + * Create a sparql update ading the triples to the named graph with the + * specified name and send it to the sparql update endpoint specified using + * the given repo connection object. Uses the sesame libraries + * + * @param conn + * sesame repo connection object + * @param triples + * triples to be added to the named graph + * @param graphName + * named graph to which the triples shall be added + */ + // public void processTripleAdditionQuery(RepositoryConnection conn, String triples, String + // graphName) { + // String addTriplesToGraphQuery = SparqlUtil.addTriplesToGraphQuery(graphName, triples); + // SparqlUtil.processQuery_sesame(addTriplesToGraphQuery, conn); + // } + + /** + * Create a triple with the link type as a predicate the src as subject and + * destination as object. This is a conveniece for enabling the creation of + * links in a ageneric way + * + * @param src + * source of the link + * @param dst + * destination of the link + * @param linkType + * type of the link + * @return the rdf triple as n triple + */ + public static String linkTriple(String src, String dst, String linkType) { + StringBuilder sb = new StringBuilder(); + sb.append("<" + src + ">"); + sb.append(" "); + sb.append("<" + linkType + ">"); + sb.append(" "); + sb.append("<" + dst + ">"); + sb.append(" ."); + return sb.toString(); + } } diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java index bd55dca59..e953b87b9 100644 --- a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/TrsClientMigrationTestSuite.java @@ -24,11 +24,6 @@ * A test suite for TRS Client functionality that tests the migration from RDF4J to Lyo Store. */ @Suite -@SelectClasses({ - SparqlBatchingHandlerTest.class, - TrsConfigurationTest.class -}) +@SelectClasses({SparqlBatchingHandlerTest.class, TrsConfigurationTest.class}) @DisplayName("TRS Client Migration Test Suite") -public class TrsClientMigrationTestSuite { - -} +public class TrsClientMigrationTestSuite {} diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java index b72d36bff..fcca9c89c 100644 --- a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java @@ -19,7 +19,6 @@ import java.io.FileWriter; import java.io.IOException; import java.net.URI; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -27,126 +26,130 @@ @DisplayName("TRS Configuration Tests") public class TrsConfigurationTest { - @TempDir - File tempDir; - - @Test - @DisplayName("Test TrsConfigurationLoader handles missing trs_uri") - public void testTrsConfigurationLoaderMissingTrsUri() throws IOException { - // Create a properties file without trs_uri - File configFile = new File(tempDir, "test.properties"); - try (FileWriter writer = new FileWriter(configFile)) { - writer.write("baseAuth_user=testuser\n"); - writer.write("baseAuth_password=testpass\n"); - } - - // Loading should throw IllegalStateException - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { - TrsConfigurationLoader.loadTrsConfiguration(configFile); - }); - - assertTrue(exception.getMessage().contains("trs_uri")); - assertTrue(exception.getMessage().contains("missing")); + @TempDir File tempDir; + + @Test + @DisplayName("Test TrsConfigurationLoader handles missing trs_uri") + public void testTrsConfigurationLoaderMissingTrsUri() throws IOException { + // Create a properties file without trs_uri + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("baseAuth_user=testuser\n"); + writer.write("baseAuth_password=testpass\n"); } - @Test - @DisplayName("Test TrsConfigurationLoader with valid configuration") - public void testTrsConfigurationLoaderValid() throws IOException { - // Create a valid properties file - File configFile = new File(tempDir, "test.properties"); - try (FileWriter writer = new FileWriter(configFile)) { - writer.write("trs_uri=http://example.org/trs\n"); - writer.write("baseAuth_user=testuser\n"); - writer.write("baseAuth_password=testpass\n"); - writer.write("sparql_query_url=http://example.org/sparql/query\n"); - writer.write("sparql_update_url=http://example.org/sparql/update\n"); - writer.write("sparql_username=sparqluser\n"); - writer.write("sparql_password=sparqlpass\n"); - } - - // Loading should succeed - TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); - - assertNotNull(config); - assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); - assertEquals("testuser", config.getBasicUsername()); - assertEquals("testpass", config.getBasicPassword()); - assertEquals("http://example.org/sparql/query", config.getSparqlQueryUrl()); - assertEquals("http://example.org/sparql/update", config.getSparqlUpdateUrl()); - assertEquals("sparqluser", config.getSparqlUsername()); - assertEquals("sparqlpass", config.getSparqlPassword()); + // Loading should throw IllegalStateException + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> { + TrsConfigurationLoader.loadTrsConfiguration(configFile); + }); + + assertTrue(exception.getMessage().contains("trs_uri")); + assertTrue(exception.getMessage().contains("missing")); + } + + @Test + @DisplayName("Test TrsConfigurationLoader with valid configuration") + public void testTrsConfigurationLoaderValid() throws IOException { + // Create a valid properties file + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("trs_uri=http://example.org/trs\n"); + writer.write("baseAuth_user=testuser\n"); + writer.write("baseAuth_password=testpass\n"); + writer.write("sparql_query_url=http://example.org/sparql/query\n"); + writer.write("sparql_update_url=http://example.org/sparql/update\n"); + writer.write("sparql_username=sparqluser\n"); + writer.write("sparql_password=sparqlpass\n"); } - @Test - @DisplayName("Test TrsConfigurationLoader with minimal configuration") - public void testTrsConfigurationLoaderMinimal() throws IOException { - // Create a minimal properties file with only required trs_uri - File configFile = new File(tempDir, "test.properties"); - try (FileWriter writer = new FileWriter(configFile)) { - writer.write("trs_uri=http://example.org/trs\n"); - } - - // Loading should succeed - TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); - - assertNotNull(config); - assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); - assertNull(config.getBasicUsername()); - assertNull(config.getBasicPassword()); - assertNull(config.getSparqlQueryUrl()); - assertNull(config.getSparqlUpdateUrl()); - assertNull(config.getSparqlUsername()); - assertNull(config.getSparqlPassword()); + // Loading should succeed + TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + + assertNotNull(config); + assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); + assertEquals("testuser", config.getBasicUsername()); + assertEquals("testpass", config.getBasicPassword()); + assertEquals("http://example.org/sparql/query", config.getSparqlQueryUrl()); + assertEquals("http://example.org/sparql/update", config.getSparqlUpdateUrl()); + assertEquals("sparqluser", config.getSparqlUsername()); + assertEquals("sparqlpass", config.getSparqlPassword()); + } + + @Test + @DisplayName("Test TrsConfigurationLoader with minimal configuration") + public void testTrsConfigurationLoaderMinimal() throws IOException { + // Create a minimal properties file with only required trs_uri + File configFile = new File(tempDir, "test.properties"); + try (FileWriter writer = new FileWriter(configFile)) { + writer.write("trs_uri=http://example.org/trs\n"); } - @Test - @DisplayName("Test TrsConsumerConfiguration with null basic auth") - public void testTrsConsumerConfigurationNullAuth() { - TrsConsumerConfiguration config = new TrsConsumerConfiguration( + // Loading should succeed + TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + + assertNotNull(config); + assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); + assertNull(config.getBasicUsername()); + assertNull(config.getBasicPassword()); + assertNull(config.getSparqlQueryUrl()); + assertNull(config.getSparqlUpdateUrl()); + assertNull(config.getSparqlUsername()); + assertNull(config.getSparqlPassword()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with null basic auth") + public void testTrsConsumerConfigurationNullAuth() { + TrsConsumerConfiguration config = + new TrsConsumerConfiguration( "http://example.org/sparql/query", "http://example.org/sparql/update", "sparqluser", "sparqlpass", null, // scheduler null, // basicUsername - null // basicPassword - ); - - // getHttpClient should handle null basic auth gracefully - assertNotNull(config.getHttpClient()); - } - - @Test - @DisplayName("Test TrsConsumerConfiguration with empty basic auth") - public void testTrsConsumerConfigurationEmptyAuth() { - TrsConsumerConfiguration config = new TrsConsumerConfiguration( + null // basicPassword + ); + + // getHttpClient should handle null basic auth gracefully + assertNotNull(config.getHttpClient()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with empty basic auth") + public void testTrsConsumerConfigurationEmptyAuth() { + TrsConsumerConfiguration config = + new TrsConsumerConfiguration( "http://example.org/sparql/query", "http://example.org/sparql/update", "sparqluser", "sparqlpass", null, // scheduler - "", // empty basicUsername - "" // empty basicPassword - ); - - // getHttpClient should handle empty basic auth gracefully - assertNotNull(config.getHttpClient()); - } - - @Test - @DisplayName("Test TrsConsumerConfiguration with valid basic auth") - public void testTrsConsumerConfigurationValidAuth() { - TrsConsumerConfiguration config = new TrsConsumerConfiguration( + "", // empty basicUsername + "" // empty basicPassword + ); + + // getHttpClient should handle empty basic auth gracefully + assertNotNull(config.getHttpClient()); + } + + @Test + @DisplayName("Test TrsConsumerConfiguration with valid basic auth") + public void testTrsConsumerConfigurationValidAuth() { + TrsConsumerConfiguration config = + new TrsConsumerConfiguration( "http://example.org/sparql/query", "http://example.org/sparql/update", "sparqluser", "sparqlpass", null, // scheduler "basicuser", - "basicpass" - ); + "basicpass"); - // getHttpClient should configure basic auth - assertNotNull(config.getHttpClient()); - } + // getHttpClient should configure basic auth + assertNotNull(config.getHttpClient()); + } } diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java index 1ea80b2ae..1d79639df 100644 --- a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java @@ -19,12 +19,9 @@ import java.net.URI; import java.net.URISyntaxException; -import java.util.Date; - import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.vocabulary.RDF; -import org.eclipse.lyo.core.trs.ChangeEvent; import org.eclipse.lyo.core.trs.Creation; import org.eclipse.lyo.core.trs.Deletion; import org.eclipse.lyo.core.trs.Modification; @@ -36,166 +33,174 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; -import org.mockito.Mockito; @DisplayName("SparqlBatchingHandler Tests") public class SparqlBatchingHandlerTest { - private SparqlBatchingHandler handler; - private final String sparqlUpdateEndpoint = "http://example.org/sparql/update"; - private final String username = "testuser"; - private final String password = "testpass"; - - @BeforeEach - public void setUp() { - handler = new SparqlBatchingHandler(sparqlUpdateEndpoint, username, password); - } + private SparqlBatchingHandler handler; + private final String sparqlUpdateEndpoint = "http://example.org/sparql/update"; + private final String username = "testuser"; + private final String password = "testpass"; + + @BeforeEach + public void setUp() { + handler = new SparqlBatchingHandler(sparqlUpdateEndpoint, username, password); + } + + @Test + @DisplayName("Test SparqlBatchingHandler uses Lyo Store for finishCycle") + public void testFinishCycleUsesLyoStore() { + // Create mock Store + Store mockStore = mock(Store.class); + + // Mock StoreFactory.sparql method + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory + .when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + // Add some test operations to create queries + BaseMember baseMember = createTestBaseMember(); + handler.handleBaseMember(baseMember); + + // Call finishCycle which should use the Store + handler.finishCycle(); + + // Verify that StoreFactory.sparql was called with correct parameters + mockedStoreFactory.verify( + () -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)); + + // Verify that rawUpdateQuery was called on the store + verify(mockStore).rawUpdateQuery(anyString()); - @Test - @DisplayName("Test SparqlBatchingHandler uses Lyo Store for finishCycle") - public void testFinishCycleUsesLyoStore() { - // Create mock Store - Store mockStore = mock(Store.class); - - // Mock StoreFactory.sparql method - try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { - mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) - .thenReturn(mockStore); - - // Add some test operations to create queries - BaseMember baseMember = createTestBaseMember(); - handler.handleBaseMember(baseMember); - - // Call finishCycle which should use the Store - handler.finishCycle(); - - // Verify that StoreFactory.sparql was called with correct parameters - mockedStoreFactory.verify(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)); - - // Verify that rawUpdateQuery was called on the store - verify(mockStore).rawUpdateQuery(anyString()); - - // Verify that close was called on the store - verify(mockStore).close(); - } + // Verify that close was called on the store + verify(mockStore).close(); } + } - @Test - @DisplayName("Test handleBaseMember creates proper queries") - public void testHandleBaseMember() { - BaseMember baseMember = createTestBaseMember(); - - // This should add queries to the internal list - handler.handleBaseMember(baseMember); - - // We can't directly test the internal queries list, but we can test - // that finishCycle processes them by mocking the Store - Store mockStore = mock(Store.class); - - try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { - mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) - .thenReturn(mockStore); - - handler.finishCycle(); - - // Verify rawUpdateQuery was called with some query string - verify(mockStore).rawUpdateQuery(anyString()); - } + @Test + @DisplayName("Test handleBaseMember creates proper queries") + public void testHandleBaseMember() { + BaseMember baseMember = createTestBaseMember(); + + // This should add queries to the internal list + handler.handleBaseMember(baseMember); + + // We can't directly test the internal queries list, but we can test + // that finishCycle processes them by mocking the Store + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory + .when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + // Verify rawUpdateQuery was called with some query string + verify(mockStore).rawUpdateQuery(anyString()); } + } + + @Test + @DisplayName("Test handleChangeEvent with Creation") + public void testHandleChangeEventCreation() throws URISyntaxException { + Creation creation = new Creation(); + creation.setChanged(new URI("http://example.org/resource/1")); + creation.setOrder(1); + + Model testModel = ModelFactory.createDefaultModel(); + testModel.add( + testModel.createResource("http://example.org/resource/1"), + RDF.type, + testModel.createResource("http://example.org/TestType")); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(creation, testModel); + + handler.handleChangeEvent(eventMessage); - @Test - @DisplayName("Test handleChangeEvent with Creation") - public void testHandleChangeEventCreation() throws URISyntaxException { - Creation creation = new Creation(); - creation.setChanged(new URI("http://example.org/resource/1")); - creation.setOrder(1); - - Model testModel = ModelFactory.createDefaultModel(); - testModel.add(testModel.createResource("http://example.org/resource/1"), - RDF.type, - testModel.createResource("http://example.org/TestType")); - - ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(creation, testModel); - - handler.handleChangeEvent(eventMessage); - - // Verify by testing finishCycle - Store mockStore = mock(Store.class); - - try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { - mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) - .thenReturn(mockStore); - - handler.finishCycle(); - - verify(mockStore).rawUpdateQuery(anyString()); - } + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory + .when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + verify(mockStore).rawUpdateQuery(anyString()); } + } + + @Test + @DisplayName("Test handleChangeEvent with Deletion") + public void testHandleChangeEventDeletion() throws URISyntaxException { + Deletion deletion = new Deletion(); + deletion.setChanged(new URI("http://example.org/resource/1")); + deletion.setOrder(2); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(deletion, null); + + handler.handleChangeEvent(eventMessage); + + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory + .when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); - @Test - @DisplayName("Test handleChangeEvent with Deletion") - public void testHandleChangeEventDeletion() throws URISyntaxException { - Deletion deletion = new Deletion(); - deletion.setChanged(new URI("http://example.org/resource/1")); - deletion.setOrder(2); - - ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(deletion, null); - - handler.handleChangeEvent(eventMessage); - - // Verify by testing finishCycle - Store mockStore = mock(Store.class); - - try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { - mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) - .thenReturn(mockStore); - - handler.finishCycle(); - - verify(mockStore).rawUpdateQuery(anyString()); - } + verify(mockStore).rawUpdateQuery(anyString()); } + } - @Test - @DisplayName("Test handleChangeEvent with Modification") - public void testHandleChangeEventModification() throws URISyntaxException { - Modification modification = new Modification(); - modification.setChanged(new URI("http://example.org/resource/1")); - modification.setOrder(3); - - Model testModel = ModelFactory.createDefaultModel(); - testModel.add(testModel.createResource("http://example.org/resource/1"), - RDF.type, - testModel.createResource("http://example.org/ModifiedType")); - - ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(modification, testModel); - - handler.handleChangeEvent(eventMessage); - - // Verify by testing finishCycle - Store mockStore = mock(Store.class); - - try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { - mockedStoreFactory.when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) - .thenReturn(mockStore); - - handler.finishCycle(); - - verify(mockStore).rawUpdateQuery(anyString()); - } + @Test + @DisplayName("Test handleChangeEvent with Modification") + public void testHandleChangeEventModification() throws URISyntaxException { + Modification modification = new Modification(); + modification.setChanged(new URI("http://example.org/resource/1")); + modification.setOrder(3); + + Model testModel = ModelFactory.createDefaultModel(); + testModel.add( + testModel.createResource("http://example.org/resource/1"), + RDF.type, + testModel.createResource("http://example.org/ModifiedType")); + + ChangeEventMessageTR eventMessage = new ChangeEventMessageTR(modification, testModel); + + handler.handleChangeEvent(eventMessage); + + // Verify by testing finishCycle + Store mockStore = mock(Store.class); + + try (MockedStatic mockedStoreFactory = mockStatic(StoreFactory.class)) { + mockedStoreFactory + .when(() -> StoreFactory.sparql(null, sparqlUpdateEndpoint, username, password)) + .thenReturn(mockStore); + + handler.finishCycle(); + + verify(mockStore).rawUpdateQuery(anyString()); } + } + + private BaseMember createTestBaseMember() { + try { + URI memberUri = new URI("http://example.org/basemember/1"); + Model model = ModelFactory.createDefaultModel(); + model.add( + model.createResource(memberUri.toString()), + RDF.type, + model.createResource("http://example.org/TestResource")); - private BaseMember createTestBaseMember() { - try { - URI memberUri = new URI("http://example.org/basemember/1"); - Model model = ModelFactory.createDefaultModel(); - model.add(model.createResource(memberUri.toString()), - RDF.type, - model.createResource("http://example.org/TestResource")); - - return new BaseMember(memberUri, model); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } + return new BaseMember(memberUri, model); + } catch (URISyntaxException e) { + throw new RuntimeException(e); } + } } From 44be66f782b47b6b1e1afc701f7740d7c85dcf52 Mon Sep 17 00:00:00 2001 From: Andrew Berezovskyi Date: Thu, 17 Jul 2025 00:48:15 +0200 Subject: [PATCH 9/9] test: fix broken --- trs/client/trs-client/pom.xml | 24 ++++++++++++-- .../client/config/TrsConfigurationTest.java | 32 +++++++++---------- .../sparql/SparqlBatchingHandlerTest.java | 11 ++++--- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/trs/client/trs-client/pom.xml b/trs/client/trs-client/pom.xml index 03bf228cb..e6805fc50 100644 --- a/trs/client/trs-client/pom.xml +++ b/trs/client/trs-client/pom.xml @@ -127,8 +127,28 @@ - junit - junit + org.junit.jupiter + junit-jupiter + test + + + org.junit.platform + junit-platform-suite + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.assertj + assertj-core + test + + + org.mockito + mockito-core test diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java index fcca9c89c..d0796b61e 100644 --- a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/config/TrsConfigurationTest.java @@ -43,7 +43,7 @@ public void testTrsConfigurationLoaderMissingTrsUri() throws IOException { assertThrows( IllegalStateException.class, () -> { - TrsConfigurationLoader.loadTrsConfiguration(configFile); + TrsConfigurationLoader.from(configFile); }); assertTrue(exception.getMessage().contains("trs_uri")); @@ -58,7 +58,7 @@ public void testTrsConfigurationLoaderValid() throws IOException { try (FileWriter writer = new FileWriter(configFile)) { writer.write("trs_uri=http://example.org/trs\n"); writer.write("baseAuth_user=testuser\n"); - writer.write("baseAuth_password=testpass\n"); + writer.write("baseAuth_pwd=testpass\n"); writer.write("sparql_query_url=http://example.org/sparql/query\n"); writer.write("sparql_update_url=http://example.org/sparql/update\n"); writer.write("sparql_username=sparqluser\n"); @@ -66,16 +66,16 @@ public void testTrsConfigurationLoaderValid() throws IOException { } // Loading should succeed - TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + TrsProviderConfiguration config = TrsConfigurationLoader.from(configFile); assertNotNull(config); assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); - assertEquals("testuser", config.getBasicUsername()); - assertEquals("testpass", config.getBasicPassword()); - assertEquals("http://example.org/sparql/query", config.getSparqlQueryUrl()); - assertEquals("http://example.org/sparql/update", config.getSparqlUpdateUrl()); - assertEquals("sparqluser", config.getSparqlUsername()); - assertEquals("sparqlpass", config.getSparqlPassword()); + assertEquals("testuser", config.getBasicAuthUsername()); + assertEquals("testpass", config.getBasicAuthPassword()); +// assertEquals("http://example.org/sparql/query", config.getSparqlQueryUrl()); +// assertEquals("http://example.org/sparql/update", config.getSparqlUpdateUrl()); +// assertEquals("sparqluser", config.getSparqlUsername()); +// assertEquals("sparqlpass", config.getSparqlPassword()); } @Test @@ -88,16 +88,16 @@ public void testTrsConfigurationLoaderMinimal() throws IOException { } // Loading should succeed - TrsProviderConfiguration config = TrsConfigurationLoader.loadTrsConfiguration(configFile); + TrsProviderConfiguration config = TrsConfigurationLoader.from(configFile); assertNotNull(config); assertEquals(URI.create("http://example.org/trs"), config.getTrsUri()); - assertNull(config.getBasicUsername()); - assertNull(config.getBasicPassword()); - assertNull(config.getSparqlQueryUrl()); - assertNull(config.getSparqlUpdateUrl()); - assertNull(config.getSparqlUsername()); - assertNull(config.getSparqlPassword()); + assertNull(config.getBasicAuthUsername()); + assertNull(config.getBasicAuthPassword()); +// assertNull(config.getSparqlQueryUrl()); +// assertNull(config.getSparqlUpdateUrl()); +// assertNull(config.getSparqlUsername()); +// assertNull(config.getSparqlPassword()); } @Test diff --git a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java index 1d79639df..681149848 100644 --- a/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java +++ b/trs/client/trs-client/src/test/java/org/eclipse/lyo/trs/client/handlers/sparql/SparqlBatchingHandlerTest.java @@ -26,6 +26,7 @@ import org.eclipse.lyo.core.trs.Deletion; import org.eclipse.lyo.core.trs.Modification; import org.eclipse.lyo.store.Store; +import org.eclipse.lyo.store.StoreAccessException; import org.eclipse.lyo.store.StoreFactory; import org.eclipse.lyo.trs.client.model.BaseMember; import org.eclipse.lyo.trs.client.model.ChangeEventMessageTR; @@ -49,7 +50,7 @@ public void setUp() { @Test @DisplayName("Test SparqlBatchingHandler uses Lyo Store for finishCycle") - public void testFinishCycleUsesLyoStore() { + public void testFinishCycleUsesLyoStore() throws StoreAccessException { // Create mock Store Store mockStore = mock(Store.class); @@ -80,7 +81,7 @@ public void testFinishCycleUsesLyoStore() { @Test @DisplayName("Test handleBaseMember creates proper queries") - public void testHandleBaseMember() { + public void testHandleBaseMember() throws StoreAccessException { BaseMember baseMember = createTestBaseMember(); // This should add queries to the internal list @@ -104,7 +105,7 @@ public void testHandleBaseMember() { @Test @DisplayName("Test handleChangeEvent with Creation") - public void testHandleChangeEventCreation() throws URISyntaxException { + public void testHandleChangeEventCreation() throws URISyntaxException, StoreAccessException { Creation creation = new Creation(); creation.setChanged(new URI("http://example.org/resource/1")); creation.setOrder(1); @@ -135,7 +136,7 @@ public void testHandleChangeEventCreation() throws URISyntaxException { @Test @DisplayName("Test handleChangeEvent with Deletion") - public void testHandleChangeEventDeletion() throws URISyntaxException { + public void testHandleChangeEventDeletion() throws URISyntaxException, StoreAccessException { Deletion deletion = new Deletion(); deletion.setChanged(new URI("http://example.org/resource/1")); deletion.setOrder(2); @@ -160,7 +161,7 @@ public void testHandleChangeEventDeletion() throws URISyntaxException { @Test @DisplayName("Test handleChangeEvent with Modification") - public void testHandleChangeEventModification() throws URISyntaxException { + public void testHandleChangeEventModification() throws URISyntaxException, StoreAccessException { Modification modification = new Modification(); modification.setChanged(new URI("http://example.org/resource/1")); modification.setOrder(3);