Sesame API remote mode

From Blazegraph
Jump to: navigation, search

Introduction

A sample Java application demonstrates using Blazegraph™ in remote mode with Sesame API. It uploads data from a document, located in resources, into a repository and executes SPARQL query. It was created in Eclipse IDE with Maven. You need to have a NanoSparqlServer running (see Quick Start instructions). Endpoint http://localhost:9999/blazegraph/ is used for remote repository connection in the application.

Download a sample application

You can download the sample-sesame-remote application here.

Code listing

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.bigdata.rdf.sail.webapp.SD;
import com.bigdata.rdf.sail.webapp.client.ConnectOptions;
import com.bigdata.rdf.sail.webapp.client.JettyResponseListener;
import com.bigdata.rdf.sail.webapp.client.RemoteRepository;
import com.bigdata.rdf.sail.webapp.client.RemoteRepositoryManager;

import org.apache.log4j.Logger;
import org.openrdf.model.Statement;
import org.openrdf.query.BindingSet;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.rio.RDFFormat;

public class SampleBlazegraphSesameRemote {

	protected static final Logger log = Logger
			.getLogger(SampleBlazegraphSesameRemote.class);
	private static final String sparqlEndPoint = "http://localhost:9999/blazegraph";

	public static void main(String[] args) throws Exception {

		final RemoteRepositoryManager repo = new RemoteRepositoryManager(
				sparqlEndPoint, true /* useLBS */);

		try {

			JettyResponseListener response = getStatus(repo);
			log.info(response.getResponseBody());

			// create a new namespace if not exists
			final String namespace = "newNamespace";
			final Properties properties = new Properties();
			properties.setProperty("com.bigdata.rdf.sail.namespace", namespace);
			if (!namespaceExists(repo, namespace)) {
				log.info(String.format("Create namespace %s...", namespace));
				repo.createRepository(namespace, properties);
				log.info(String.format("Create namespace %s done", namespace));
			} else {
				log.info(String.format("Namespace %s already exists", namespace));
			}

			//get properties for namespace
			log.info(String.format("Property list for namespace %s", namespace));
			response = getNamespaceProperties(repo, namespace);
			log.info(response.getResponseBody());

			/*
			 * Load data from file located in the resource folder
			 * src/main/resources/data.n3
			 */
			String resource = "/data.n3";
			loadDataFromResource(repo, namespace, resource);

			// execute query
			TupleQueryResult result = repo.getRepositoryForNamespace(namespace)
					.prepareTupleQuery("SELECT * {?s ?p ?o} LIMIT 100")
					.evaluate();
			
			//result processing
			try {
				while (result.hasNext()) {
					BindingSet bs = result.next();
					log.info(bs);
				}
			} finally {
				result.close();
			}

		} finally {
			repo.close();
		}

	}

	/*
	 * Status request.
	 */
	private static JettyResponseListener getStatus(RemoteRepositoryManager repo)
			throws Exception {

		ConnectOptions opts = new ConnectOptions(sparqlEndPoint + "/status");
		opts.method = "GET";
		return repo.doConnect(opts);

	}

	/*
	 * Check namespace already exists.
	 */
	private static boolean namespaceExists(RemoteRepositoryManager repo,
			String namespace) throws Exception {
		
		GraphQueryResult res = repo.getRepositoryDescriptions();
		try {
			while (res.hasNext()) {
				Statement stmt = res.next();
				if (stmt.getPredicate()
						.toString()
						.equals(SD.KB_NAMESPACE.stringValue())) {
					if (namespace.equals(stmt.getObject().stringValue())) {
						return true;
					}
				}
			}
		} finally {
			res.close();
		}
		return false;
	}

	/*
	 * Get namespace properties.
	 */
	private static JettyResponseListener getNamespaceProperties(
			RemoteRepositoryManager repo, String namespace) throws Exception {

		ConnectOptions opts = new ConnectOptions(sparqlEndPoint + "/namespace/"
				+ namespace + "/properties");
		opts.method = "GET";
		return repo.doConnect(opts);

	}

	/*
	 * Load data into a namespace.
	 */
	private static void loadDataFromResource(RemoteRepositoryManager repo,
			String namespace, String resource) throws Exception {
		InputStream is = SampleBlazegraphSesameRemote.class
				.getResourceAsStream(resource);
		if (is == null) {
			throw new IOException("Could not locate resource: " + resource);
		}
		try {
			repo.getRepositoryForNamespace(namespace).add(
					new RemoteRepository.AddOp(is, RDFFormat.N3));
		} finally {
			is.close();
		}
	}

}

Maven dependencies

 	<repositories>
	<repository>
	   <id>bigdata.releases</id>
	   <url>http://www.systap.com/maven/releases</url>
 	</repository>
 	</repositories>
 	
 	<dependencies>
 		<dependency>
 			<groupId>com.bigdata</groupId>
			<artifactId>bigdata</artifactId>
			<version>1.5.2</version>
 		</dependency>
 	</dependencies>

Comments

Create a remote repository connection

                final RemoteRepositoryManager repo = new RemoteRepositoryManager(
				sparqlEndPoint, true /* useLBS */);

Get namespaces

Check namespace existence:

         private static boolean namespaceExists(RemoteRepositoryManager repo,
			String namespace) throws Exception {

		GraphQueryResult res = repo.getRepositoryDescriptions();
		try {
			while (res.hasNext()) {
				Statement stmt = res.next();
				if (stmt.getPredicate()
						.toString()
						.equals(SD.KB_NAMESPACE.stringValue())) {
					if (namespace.equals(stmt.getObject().stringValue())) {
						return true;
					}

				}
			}
		} finally {
			res.close();
		}
		return false;
	}

Load data

The application uploads data from /src/main/resources/data.n3 using the procedure below:

private static void loadDataFromResource(RemoteRepositoryManager repo,
			String namespace, String resource) throws Exception {
		InputStream is = SampleBlazegraphSesameRemote.class
				.getResourceAsStream(resource);
		if (is == null) {
			throw new IOException("Could not locate resource: " + resource);
		}
		try {
			repo.getRepositoryForNamespace(namespace).add(
					new RemoteRepository.AddOp(is, RDFFormat.N3));
		} finally {
			is.close();
		}
	}

File data.n3 contains some RDF statements in notation3:

PREFIX : <http://blazegraph.com/>
PREFIX schema: <http://schema.org/>


:systap a schema:Organization ;
		schema:owns :blazegraph .
:blazegraph a schema:Product ;
			schema:brand :systap;
			:productOf <http://systap.com/>;
			:implements <http://rdf4j.org>, <http://blueprints.tinkerpop.com> .

Query data

           TupleQueryResult result = repo.getRepositoryForNamespace(namespace)
					.prepareTupleQuery("SELECT * {?s ?p ?o} LIMIT 100")
					.evaluate();

Query result iteration

                	try {
				while (result.hasNext()) {
					BindingSet bs = result.next();
					log.info(bs);
				}
			} finally {
				result.close();
			}               

Program output

New service class org.openrdf.query.resultio.sparqljson.SPARQLResultsJSONWriterFactory replaces existing service class com.bigdata.rdf.rio.json.BigdataSPARQLResultsJSONWriterFactory
New service class org.openrdf.query.resultio.sparqljson.SPARQLResultsJSONParserFactory replaces existing service class com.bigdata.rdf.rio.json.BigdataSPARQLResultsJSONParserFactory
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><title>bigdata®</title
></head
><body><p>Build Version=<span id="buildVersion">1.5.1</span
></p
><p>Accepted query count=<span id="accepted-query-count">132</span
></p
><p>Running query count=<span id="running-query-count">0</span
></p
><p>Show <a href="http://localhost:9999/blazegraph/status?showQueries" id="show-queries">queries</a
>, <a href="http://localhost:9999/blazegraph/status?showQueries=details" id="show-query-details">query details</a
>.</p
><p id="counter-set">
/blockedWorkQueueCount=0
/blockedWorkQueueRunningTotal=0
/deadlineQueueSize=0
/operatorActiveCount=0
/operatorHaltCount=258
/operatorStartCount=258
/operatorTasksPerQuery=2.1147540983606556
/queriesPerSecond=500.0
/queryDoneCount=122
/queryErrorCount=0
/queryStartCount=122</p
></body
></html
>
Create namespace newNamespace...
Create namespace newNamespace done
Property list for namespace newNamespace
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="com.bigdata.namespace.kb.spo.com.bigdata.btree.BTree.branchingFactor">1024</entry>
<entry key="com.bigdata.relation.container">newNamespace</entry>
<entry key="com.bigdata.journal.AbstractJournal.bufferMode">DiskRW</entry>
<entry key="com.bigdata.journal.AbstractJournal.file">bigdata.jnl</entry>
<entry key="com.bigdata.journal.AbstractJournal.initialExtent">209715200</entry>
<entry key="com.bigdata.rdf.store.AbstractTripleStore.vocabularyClass">com.bigdata.rdf.vocab.DefaultBigdataVocabulary</entry>
<entry key="com.bigdata.rdf.store.AbstractTripleStore.textIndex">true</entry>
<entry key="com.bigdata.btree.BTree.branchingFactor">128</entry>
<entry key="com.bigdata.namespace.kb.lex.com.bigdata.btree.BTree.branchingFactor">400</entry>
<entry key="com.bigdata.rdf.store.AbstractTripleStore.axiomsClass">com.bigdata.rdf.axioms.NoAxioms</entry>
<entry key="com.bigdata.service.AbstractTransactionService.minReleaseAge">1</entry>
<entry key="com.bigdata.rdf.sail.truthMaintenance">false</entry>
<entry key="com.bigdata.journal.AbstractJournal.maximumExtent">209715200</entry>
<entry key="com.bigdata.rdf.sail.namespace">newNamespace</entry>
<entry key="com.bigdata.relation.class">com.bigdata.rdf.store.LocalTripleStore</entry>
<entry key="com.bigdata.rdf.store.AbstractTripleStore.quads">false</entry>
<entry key="com.bigdata.search.FullTextIndex.fieldsEnabled">false</entry>
<entry key="com.bigdata.relation.namespace">newNamespace</entry>
<entry key="com.bigdata.btree.writeRetentionQueue.capacity">4000</entry>
<entry key="com.bigdata.rdf.store.AbstractTripleStore.statementIdentifiers">false</entry>
</properties>

[p=http://blazegraph.com/implements;s=http://blazegraph.com/blazegraph;o=http://blueprints.tinkerpop.com]
[p=http://blazegraph.com/implements;s=http://blazegraph.com/blazegraph;o=http://rdf4j.org]
[p=http://blazegraph.com/productOf;s=http://blazegraph.com/blazegraph;o=http://systap.com/]
[p=http://schema.org/brand;s=http://blazegraph.com/blazegraph;o=http://blazegraph.com/systap]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;s=http://blazegraph.com/blazegraph;o=http://schema.org/Product]
[p=http://schema.org/owns;s=http://blazegraph.com/systap;o=http://blazegraph.com/blazegraph]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;s=http://blazegraph.com/systap;o=http://schema.org/Organization]