FedXRepositoryConfigTest.java
/*******************************************************************************
* Copyright (c) 2019 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 static org.eclipse.rdf4j.model.util.Models.subject;
import java.io.InputStream;
import org.eclipse.rdf4j.federated.FedXConfig;
import org.eclipse.rdf4j.federated.util.Vocabulary.FEDX;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.impl.TreeModel;
import org.eclipse.rdf4j.model.util.Models;
import org.eclipse.rdf4j.repository.config.RepositoryConfigSchema;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
public class FedXRepositoryConfigTest {
@Test
public void testParseConfig() throws Exception {
Model model = readConfig("/tests/rdf4jserver/config.ttl");
FedXRepositoryConfig config = new FedXRepositoryConfig();
config.parse(model, implNode(model));
Assertions.assertNull(config.getDataConfig());
Assertions.assertNull(config.getConfig());
Model members = config.getMembers();
assertThat(members.filter(null, FEDX.STORE, null).size()).isEqualTo(2);
assertThat(members.filter(null, FEDX.REPOSITORY_NAME, null).objects().stream().map(Value::stringValue))
.containsExactly("endpoint1", "endpoint2");
}
@Test
public void testParseConfig_DataConfig() throws Exception {
Model model = readConfig("/tests/rdf4jserver/config-withDataConfig.ttl");
FedXRepositoryConfig config = new FedXRepositoryConfig();
config.parse(model, implNode(model));
Assertions.assertEquals("dataConfig.ttl", config.getDataConfig());
Assertions.assertNull(config.getMembers());
}
@Test
public void testExport() throws Exception {
Model model = readConfig("/tests/rdf4jserver/config.ttl");
FedXRepositoryConfig config = new FedXRepositoryConfig();
config.parse(model, implNode(model));
// export into model
Model export = new TreeModel();
Resource implNode = config.export(export);
assertThat(export.filter(implNode, FedXRepositoryConfig.MEMBER, null).size()).isEqualTo(2);
assertThat(export.filter(implNode, FedXRepositoryConfig.FEDX_CONFIG, null)).isEmpty();
assertThat(export.filter(null, FEDX.REPOSITORY_NAME, null).objects().stream().map(Value::stringValue))
.containsExactly("endpoint1", "endpoint2");
}
protected Model readConfig(String configResource) throws Exception {
try (InputStream in = FedXRepositoryConfigTest.class.getResourceAsStream(configResource)) {
return Rio.parse(in, "http://example.org/", RDFFormat.TURTLE);
}
}
protected Resource implNode(Model model) {
return subject(model.filter(null, RepositoryConfigSchema.REPOSITORYTYPE, null)).get();
}
@Nested
class FedXConfigParsing {
@Test
public void testParse() throws Exception {
Model model = readConfig("/tests/rdf4jserver/config-withFedXConfig.ttl");
FedXRepositoryConfig repoConfig = new FedXRepositoryConfig();
repoConfig.parse(model, implNode(model));
FedXConfig config = repoConfig.getConfig();
assertThat(config.getEnforceMaxQueryTime()).isEqualTo(105);
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 testParseConfigOverridesExistingConfig() throws Exception {
Model model = readConfig("/tests/rdf4jserver/config-withFedXConfig.ttl");
FedXRepositoryConfig repoConfig = new FedXRepositoryConfig();
repoConfig.setConfig(new FedXConfig().withEnforceMaxQueryTime(33));
repoConfig.parse(model, implNode(model));
FedXConfig config = repoConfig.getConfig();
assertThat(config.getEnforceMaxQueryTime()).isEqualTo(105);
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 = readConfig("/tests/rdf4jserver/config.ttl");
FedXRepositoryConfig repoConfig = new FedXRepositoryConfig();
repoConfig.setConfig(new FedXConfig());
repoConfig.parse(model, implNode(model));
FedXConfig config = repoConfig.getConfig();
// 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-withFedXConfig.ttl");
FedXRepositoryConfig repoConfig = new FedXRepositoryConfig();
repoConfig.parse(model, implNode(model));
// export into model
Model export = new TreeModel();
Resource implNode = repoConfig.export(export);
Resource configNode = Models
.objectResource(export.getStatements(implNode, FedXRepositoryConfig.FEDX_CONFIG, null))
.orElse(null);
assertThat(configNode).isNotNull();
assertThat(export.filter(configNode, null, null)).hasSize(15);
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_JOIN_WORKER_THREADS, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(101));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_UNION_WORKER_THREADS, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(102));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LEFT_JOIN_WORKER_THREADS,
null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(103));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_BOUND_JOIN_BLOCK_SIZE, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(104));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENFORCE_MAX_QUERY_TIME, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(105));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_SERVICE_AS_BOUND_JOIN,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_OPTIONAL_AS_BIND_JOIN,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_MONITORING, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERY_PLAN, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERIES, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_DEBUG_QUERY_PLAN, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_INCLUDE_INFERRED_DEFAULT,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_SOURCE_SELECTION_CACHE_SPEC,
null)))
.hasValueSatisfying(v -> assertThat(v.stringValue()).isEqualTo("spec-goes-here"));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_PREFIX_DECLARATIONS,
null)))
.hasValueSatisfying(v -> assertThat(v.stringValue()).isEqualTo("prefixes-go-here"));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_CONSUMING_ITERATION_MAX,
null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(106));
}
@Test
public void testExportWithEmptyConfig() throws Exception {
FedXRepositoryConfig repoConfig = new FedXRepositoryConfig();
// Set to force export of defaults
repoConfig.setConfig(new FedXConfig());
// export into model
Model export = new TreeModel();
Resource implNode = repoConfig.export(export);
Resource configNode = Models
.objectResource(export.getStatements(implNode, FedXRepositoryConfig.FEDX_CONFIG, null))
.orElse(null);
assertThat(configNode).isNotNull();
// Note: 13 instead of 15 since CONFIG_SOURCE_SELECTION_CACHE_SPEC & CONFIG_PREFIX_DECLARATIONS are null
// and thus should not be populated
assertThat(export.filter(configNode, null, null)).hasSize(13);
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_JOIN_WORKER_THREADS, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_UNION_WORKER_THREADS, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LEFT_JOIN_WORKER_THREADS,
null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(10));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_BOUND_JOIN_BLOCK_SIZE, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(25));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENFORCE_MAX_QUERY_TIME, null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(30));
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_SERVICE_AS_BOUND_JOIN,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_OPTIONAL_AS_BIND_JOIN,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_MONITORING, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERY_PLAN, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERIES, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_DEBUG_QUERY_PLAN, null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_INCLUDE_INFERRED_DEFAULT,
null)))
.hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue());
assertThat(
Models.objectLiteral(
export.getStatements(configNode, FedXRepositoryConfig.CONFIG_CONSUMING_ITERATION_MAX,
null)))
.hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(1000));
}
}
}