All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.rdf4j.runtime.RepositoryManagerFederator Maven / Gradle / Ivy

Go to download

The Federation SAIL allows multiple datasets to be virtually combined into a single dataset. The Federation SAIL combines multiple RDF stores that may exist on a remote server or are embedded in the same JVM. The Federation uses query optimizations to distribute sections of the query to different members based on the data contained in each of the members. These results are then joined together within the federation to provide the same result as if all the data was co-located within a single repository.

There is a newer version: 4.0.0-M1
Show newest version
/*******************************************************************************
 * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
 * 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.
 *******************************************************************************/
package org.eclipse.rdf4j.runtime;

import java.net.MalformedURLException;
import java.util.Collection;

import org.eclipse.rdf4j.RDF4JException;
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.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.LinkedHashModel;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.repository.config.RepositoryConfig;
import org.eclipse.rdf4j.repository.config.RepositoryConfigException;
import org.eclipse.rdf4j.repository.config.RepositoryConfigSchema;
import org.eclipse.rdf4j.repository.http.config.HTTPRepositoryConfig;
import org.eclipse.rdf4j.repository.http.config.HTTPRepositoryFactory;
import org.eclipse.rdf4j.repository.http.config.HTTPRepositorySchema;
import org.eclipse.rdf4j.repository.manager.RepositoryManager;
import org.eclipse.rdf4j.repository.sail.config.ProxyRepositoryFactory;
import org.eclipse.rdf4j.repository.sail.config.ProxyRepositorySchema;
import org.eclipse.rdf4j.repository.sail.config.SailRepositoryFactory;
import org.eclipse.rdf4j.repository.sail.config.SailRepositorySchema;
import org.eclipse.rdf4j.repository.sparql.config.SPARQLRepositoryConfig;
import org.eclipse.rdf4j.repository.sparql.config.SPARQLRepositoryFactory;
import org.eclipse.rdf4j.sail.config.SailConfigSchema;
import org.eclipse.rdf4j.sail.federation.config.FederationConfig;
import org.eclipse.rdf4j.sail.federation.config.FederationFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class for handling the details of federating "user repositories" managed by a
 * {@link org.eclipse.rdf4j.repository.manager.RepositoryManager}.
 *
 * @author Dale Visser
 * @deprecated since 3.1.0. This module will be replaced by the new FedX federation module.
 */
@Deprecated
public class RepositoryManagerFederator {

	private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryManagerFederator.class);

	private final RepositoryManager manager;

	private final ValueFactory valueFactory;

	/**
	 * Create an instance capable of federating "user repositories" within the given
	 * {@link org.eclipse.rdf4j.repository.manager.RepositoryManager}.
	 *
	 * @param manager must manage the repositories to be added to new federations, and becomes the manager of any
	 *                created federations
	 */
	public RepositoryManagerFederator(RepositoryManager manager) {
		this.manager = manager;
		this.valueFactory = SimpleValueFactory.getInstance();
	}

	/**
	 * Adds a new repository to the {@link org.eclipse.rdf4j.repository.manager.RepositoryManager}, which is a
	 * federation of the given repository id's, which must also refer to repositories already managed by the
	 * {@link org.eclipse.rdf4j.repository.manager.RepositoryManager}.
	 *
	 * @param fedID       the desired identifier for the new federation repository
	 * @param description the desired description for the new federation repository
	 * @param members     the identifiers of the repositories to federate, which must already exist and be managed by
	 *                    the {@link org.eclipse.rdf4j.repository.manager.RepositoryManager}
	 * @param readonly    whether the federation is read-only
	 * @param distinct    whether the federation enforces distinct results from its members
	 * @throws MalformedURLException if the {@link org.eclipse.rdf4j.repository.manager.RepositoryManager} has a
	 *                               malformed location
	 * @throws RDF4JException        if a problem otherwise occurs while creating the federation
	 */
	public void addFed(String fedID, String description, Collection members, boolean readonly, boolean distinct)
			throws MalformedURLException, RDF4JException {
		if (members.contains(fedID)) {
			throw new RepositoryConfigException("A federation member may not have the same ID as the federation.");
		}
		Model graph = new LinkedHashModel();
		BNode fedRepoNode = valueFactory.createBNode();
		LOGGER.debug("Federation repository root node: {}", fedRepoNode);
		addToGraph(graph, fedRepoNode, RDF.TYPE, RepositoryConfigSchema.REPOSITORY);
		addToGraph(graph, fedRepoNode, RepositoryConfigSchema.REPOSITORYID, valueFactory.createLiteral(fedID));
		addToGraph(graph, fedRepoNode, RDFS.LABEL, valueFactory.createLiteral(description));
		addImplementation(members, graph, fedRepoNode, readonly, distinct);
		RepositoryConfig fedConfig = RepositoryConfig.create(graph, fedRepoNode);
		fedConfig.validate();
		manager.addRepositoryConfig(fedConfig);
	}

	private void addImplementation(Collection members, Model graph, BNode fedRepoNode, boolean readonly,
			boolean distinct) throws RDF4JException, MalformedURLException {
		BNode implRoot = valueFactory.createBNode();
		addToGraph(graph, fedRepoNode, RepositoryConfigSchema.REPOSITORYIMPL, implRoot);
		addToGraph(graph, implRoot, RepositoryConfigSchema.REPOSITORYTYPE,
				valueFactory.createLiteral(SailRepositoryFactory.REPOSITORY_TYPE));
		addSail(members, graph, implRoot, readonly, distinct);
	}

	private void addSail(Collection members, Model graph, BNode implRoot, boolean readonly, boolean distinct)
			throws RDF4JException, MalformedURLException {
		BNode sailRoot = valueFactory.createBNode();
		addToGraph(graph, implRoot, SailRepositorySchema.SAILIMPL, sailRoot);
		addToGraph(graph, sailRoot, SailConfigSchema.SAILTYPE, valueFactory.createLiteral(FederationFactory.SAIL_TYPE));
		addToGraph(graph, sailRoot, FederationConfig.READ_ONLY, valueFactory.createLiteral(readonly));
		addToGraph(graph, sailRoot, FederationConfig.DISTINCT, valueFactory.createLiteral(distinct));
		for (String member : members) {
			addMember(graph, sailRoot, member);
		}
	}

	private void addMember(Model graph, BNode sailRoot, String identifier)
			throws RDF4JException, MalformedURLException {
		LOGGER.debug("Adding member: {}", identifier);
		BNode memberNode = valueFactory.createBNode();
		addToGraph(graph, sailRoot, FederationConfig.MEMBER, memberNode);
		String memberRepoType = manager.getRepositoryConfig(identifier).getRepositoryImplConfig().getType();
		if (!(SPARQLRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType)
				|| HTTPRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType))) {
			memberRepoType = ProxyRepositoryFactory.REPOSITORY_TYPE;
		}
		addToGraph(graph, memberNode, RepositoryConfigSchema.REPOSITORYTYPE,
				valueFactory.createLiteral(memberRepoType));
		addToGraph(graph, memberNode, getLocationPredicate(memberRepoType),
				getMemberLocator(identifier, memberRepoType));
		LOGGER.debug("Added member {}: ", identifier);
	}

	private IRI getLocationPredicate(String memberRepoType) {
		IRI predicate;
		if (SPARQLRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType)) {
			predicate = SPARQLRepositoryConfig.QUERY_ENDPOINT;
		} else if (HTTPRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType)) {
			predicate = HTTPRepositorySchema.REPOSITORYURL;
		} else {
			predicate = ProxyRepositorySchema.PROXIED_ID;
		}
		return predicate;
	}

	private Value getMemberLocator(String identifier, String memberRepoType)
			throws MalformedURLException, RepositoryConfigException, RDF4JException {
		Value locator;
		if (HTTPRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType)) {
			locator = valueFactory.createIRI(
					((HTTPRepositoryConfig) manager.getRepositoryConfig(identifier).getRepositoryImplConfig())
							.getURL());
		} else if (SPARQLRepositoryFactory.REPOSITORY_TYPE.equals(memberRepoType)) {
			locator = valueFactory.createIRI(
					((SPARQLRepositoryConfig) manager.getRepositoryConfig(identifier).getRepositoryImplConfig())
							.getQueryEndpointUrl());
		} else {
			locator = valueFactory.createLiteral(identifier);
		}
		return locator;
	}

	private static void addToGraph(Model graph, Resource subject, IRI predicate, Value object) {
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug(subject + " " + predicate + " " + object);
		}
		graph.add(subject, predicate, object);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy