-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GH-4952 - Introduce FedXConfig overrides for FedXRepositoryConfig
- Provides a subset of options
- Loading branch information
Showing
6 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
tools/federation/src/main/java/org/eclipse/rdf4j/federated/repository/FedXConfigParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Eclipse RDF4J contributors. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Distribution License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*******************************************************************************/ | ||
package org.eclipse.rdf4j.federated.repository; | ||
|
||
import static org.eclipse.rdf4j.federated.repository.FedXRepositoryConfig.NAMESPACE; | ||
|
||
import org.eclipse.rdf4j.federated.FedXConfig; | ||
import org.eclipse.rdf4j.model.BNode; | ||
import org.eclipse.rdf4j.model.IRI; | ||
import org.eclipse.rdf4j.model.Model; | ||
import org.eclipse.rdf4j.model.Resource; | ||
import org.eclipse.rdf4j.model.ValueFactory; | ||
import org.eclipse.rdf4j.model.impl.SimpleValueFactory; | ||
import org.eclipse.rdf4j.model.util.Models; | ||
import org.eclipse.rdf4j.model.util.Values; | ||
import org.eclipse.rdf4j.repository.config.RepositoryConfigException; | ||
|
||
/** | ||
* A parser & exporter of {@link FedXConfig} to fine-tune FedX repositories when configured via | ||
* {@link FedXRepositoryConfig}. | ||
* | ||
* @author Iotic Labs | ||
*/ | ||
public class FedXConfigParser { | ||
|
||
private static final ValueFactory vf = SimpleValueFactory.getInstance(); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#getEnforceMaxQueryTime()} | ||
*/ | ||
public static final IRI CONFIG_ENFORCE_MAX_QUERY_TIME = vf.createIRI(NAMESPACE, "enforceMaxQueryTime"); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#isEnableMonitoring()} | ||
*/ | ||
public static final IRI CONFIG_ENABLE_MONITORING = vf.createIRI(NAMESPACE, "enableMonitoring"); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#isLogQueryPlan()} | ||
*/ | ||
public static final IRI CONFIG_LOG_QUERY_PLAN = vf.createIRI(NAMESPACE, "logQueryPlan"); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#isDebugQueryPlan()} | ||
*/ | ||
public static final IRI CONFIG_DEBUG_QUERY_PLAN = vf.createIRI(NAMESPACE, "debugQueryPlan"); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#isLogQueries()} | ||
*/ | ||
public static final IRI CONFIG_LOG_QUERIES = vf.createIRI(NAMESPACE, "logQueries"); | ||
|
||
/** | ||
* IRI of the property populating {@link FedXConfig#getSourceSelectionCacheSpec()} | ||
*/ | ||
public static final IRI CONFIG_SOURCE_SELECTION_CACHE_SPEC = vf.createIRI(NAMESPACE, "sourceSelectionCacheSpec"); | ||
|
||
private FedXConfigParser() { | ||
} | ||
|
||
/** | ||
* Updates the provided {@link FedXConfig} with properties from the supplied model. | ||
* | ||
* @param config the configuration to be amended. | ||
* @param m the model from which to read configuration properties | ||
* @param confNode the subject against which to expect {@link FedXConfig} overrides. | ||
* | ||
* @return The updated {@link FedXConfig} | ||
* | ||
* @throws RepositoryConfigException if any of the overridden fields are deemed to be invalid | ||
*/ | ||
public static FedXConfig parse(FedXConfig config, Model m, Resource confNode) throws RepositoryConfigException { | ||
Models.objectLiteral(m.getStatements(confNode, CONFIG_ENFORCE_MAX_QUERY_TIME, null)) | ||
.ifPresent(value -> config.withEnforceMaxQueryTime(value.intValue())); | ||
|
||
Models.objectLiteral(m.getStatements(confNode, CONFIG_ENABLE_MONITORING, null)) | ||
.ifPresent(value -> config.withEnableMonitoring(value.booleanValue())); | ||
|
||
Models.objectLiteral(m.getStatements(confNode, CONFIG_LOG_QUERY_PLAN, null)) | ||
.ifPresent(value -> config.withLogQueryPlan(value.booleanValue())); | ||
|
||
Models.objectLiteral(m.getStatements(confNode, CONFIG_DEBUG_QUERY_PLAN, null)) | ||
.ifPresent(value -> config.withDebugQueryPlan(value.booleanValue())); | ||
|
||
Models.objectLiteral(m.getStatements(confNode, CONFIG_LOG_QUERIES, null)) | ||
.ifPresent(value -> config.withLogQueries(value.booleanValue())); | ||
|
||
Models.objectLiteral(m.getStatements(confNode, CONFIG_SOURCE_SELECTION_CACHE_SPEC, null)) | ||
.ifPresent(value -> config.withSourceSelectionCacheSpec(value.stringValue())); | ||
|
||
return config; | ||
} | ||
|
||
/** | ||
* Export the provided {@link FedXConfig} to its RDF representation. | ||
* | ||
* @param config the configuration to export | ||
* @param m the model to which to write configuration properties | ||
* | ||
* @return the node against which the configuration has been written | ||
*/ | ||
public static Resource export(FedXConfig config, Model m) { | ||
BNode confNode = Values.bnode(); | ||
|
||
m.add(confNode, CONFIG_ENFORCE_MAX_QUERY_TIME, vf.createLiteral(config.getEnforceMaxQueryTime())); | ||
|
||
m.add(confNode, CONFIG_ENABLE_MONITORING, vf.createLiteral(config.isEnableMonitoring())); | ||
|
||
m.add(confNode, CONFIG_LOG_QUERY_PLAN, vf.createLiteral(config.isLogQueryPlan())); | ||
|
||
m.add(confNode, CONFIG_DEBUG_QUERY_PLAN, vf.createLiteral(config.isDebugQueryPlan())); | ||
|
||
m.add(confNode, CONFIG_LOG_QUERIES, vf.createLiteral(config.isLogQueries())); | ||
|
||
if (config.getSourceSelectionCacheSpec() != null) { | ||
m.add(confNode, CONFIG_SOURCE_SELECTION_CACHE_SPEC, vf.createLiteral(config.getSourceSelectionCacheSpec())); | ||
} | ||
|
||
return confNode; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
...federation/src/test/java/org/eclipse/rdf4j/federated/repository/FedXConfigParserTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Eclipse RDF4J contributors. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Distribution License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*******************************************************************************/ | ||
package org.eclipse.rdf4j.federated.repository; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.io.InputStream; | ||
|
||
import org.eclipse.rdf4j.federated.FedXConfig; | ||
import org.eclipse.rdf4j.model.Model; | ||
import org.eclipse.rdf4j.model.Resource; | ||
import org.eclipse.rdf4j.model.impl.TreeModel; | ||
import org.eclipse.rdf4j.model.util.Models; | ||
import org.eclipse.rdf4j.model.util.Values; | ||
import org.eclipse.rdf4j.rio.RDFFormat; | ||
import org.eclipse.rdf4j.rio.Rio; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public class FedXConfigParserTest { | ||
|
||
@Test | ||
public void testParse() throws Exception { | ||
Model model = readConfig("/tests/rdf4jserver/config-fedXConfig-only.ttl"); | ||
|
||
FedXConfig config = FedXConfigParser.parse(new FedXConfig(), model, Values.iri("http://example.org/conf")); | ||
|
||
assertThat(config.getEnforceMaxQueryTime()).isEqualTo(1234); | ||
assertThat(config.isEnableMonitoring()).isTrue(); | ||
assertThat(config.isLogQueryPlan()).isTrue(); | ||
assertThat(config.isDebugQueryPlan()).isTrue(); | ||
assertThat(config.isLogQueries()).isTrue(); | ||
assertThat(config.getSourceSelectionCacheSpec()).isEqualTo("spec-goes-here"); | ||
} | ||
|
||
@Test | ||
public void testParseWithEmptyConfig() throws Exception { | ||
Model model = new TreeModel(); | ||
|
||
FedXConfig config = FedXConfigParser.parse(new FedXConfig(), model, Values.iri("http://example.org/conf")); | ||
|
||
// expecting defaults | ||
assertThat(config.getEnforceMaxQueryTime()).isEqualTo(30); | ||
assertThat(config.isEnableMonitoring()).isFalse(); | ||
assertThat(config.isLogQueryPlan()).isFalse(); | ||
assertThat(config.isDebugQueryPlan()).isFalse(); | ||
assertThat(config.isLogQueries()).isFalse(); | ||
assertThat(config.getSourceSelectionCacheSpec()).isNull(); | ||
} | ||
|
||
@Test | ||
public void testExport() throws Exception { | ||
Model model = readConfig("/tests/rdf4jserver/config-fedXConfig-only.ttl"); | ||
|
||
FedXConfig config = FedXConfigParser.parse(new FedXConfig(), model, Values.iri("http://example.org/conf")); | ||
|
||
Model export = new TreeModel(); | ||
Resource configNode = FedXConfigParser.export(config, export); | ||
|
||
assertThat(export.filter(configNode, null, null)).hasSize(6); | ||
|
||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_ENFORCE_MAX_QUERY_TIME, null))) | ||
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(1234)); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_ENABLE_MONITORING, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_LOG_QUERY_PLAN, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_DEBUG_QUERY_PLAN, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_LOG_QUERIES, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_SOURCE_SELECTION_CACHE_SPEC, null))) | ||
.hasValueSatisfying(v -> assertThat(v.stringValue()).isEqualTo("spec-goes-here")); | ||
} | ||
|
||
@Test | ||
public void testExportWithEmptyConfig() throws Exception { | ||
Model export = new TreeModel(); | ||
Resource configNode = FedXConfigParser.export(new FedXConfig(), export); | ||
|
||
// Note: 5 instead of 6 since CONFIG_SOURCE_SELECTION_CACHE_SPEC is null and thus should not be populated | ||
assertThat(export.filter(configNode, null, null)).hasSize(5); | ||
|
||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_ENFORCE_MAX_QUERY_TIME, null))) | ||
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(30)); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_ENABLE_MONITORING, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_LOG_QUERY_PLAN, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_DEBUG_QUERY_PLAN, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); | ||
assertThat( | ||
Models.objectLiteral( | ||
export.getStatements(configNode, FedXConfigParser.CONFIG_LOG_QUERIES, null))) | ||
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); | ||
} | ||
|
||
protected Model readConfig(String configResource) throws Exception { | ||
try (InputStream in = FedXRepositoryConfigTest.class.getResourceAsStream(configResource)) { | ||
return Rio.parse(in, "http://example.org/", RDFFormat.TURTLE); | ||
} | ||
} | ||
} |
Oops, something went wrong.