Fuseki can be run within a larger JVM application as an embedded triplestore.
The application can safely access and modify the data published by the server if it does
so inside a transaction using an appropriate
storage choice. DatasetFactory.createTxnMem()
is a good choice for in-memory use;
TDB is a good choice for a persistent database.
To build and start the server:
Dataset ds = ...
FusekiServer server = FusekiServer.create()
.add("/rdf", ds)
.build() ;
server.start() ;
then the application can modify the dataset:
// Add some data while live.
// Write transaction.
Txn.execWrite(dsg, ()->RDFDataMgr.read(dsg, "D.trig")) ;
or read the dataset and see any updates made by remote systems:
// Query data while live
// Read transaction.
Txn.execRead(dsg, ()->{
Dataset ds = DatasetFactory.wrap(dsg) ;
try (QueryExecution qExec = QueryExecution.create("SELECT * { ?s ?o}", ds) ) {
ResultSet rs = qExec.execSelect() ;
ResultSetFormatter.out(rs) ;
}
}) ;
The full Jena API can be used provided operations (read and write) are inside a transaction.
Dependencies and Setup
To include an embedded Fuseki server in the application:
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-fuseki-main</artifactId>
<version>3.x.y</version> <!-- Set the version -->
</dependency>
This brings in enough dependencies to run Fuseki. Application writers are strongly encouraged to use a dependency manager because the number of Jetty and other dependencies is quite large and difficult to set manually.
This dependency does not include a logging setting. Fuseki uses slf4j.
If the application wishes to use a dataset with a text-index then the application will also need to include jena-text in its dependencies.
Logging
The application must set the logging provided for slf4j. Apache Jena provides helpers Apache Log4j v2.
For Apache Log4j2, call:
FusekiLogging.setLogging();
and dependency:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.13.1</version> <!-- Many versions work -->
</dependency>
See Fuseki Logging.
To silence logging from Java, try:
LogCtl.setLevel(Fuseki.serverLogName, "WARN");
LogCtl.setLevel(Fuseki.actionLogName, "WARN");
LogCtl.setLevel(Fuseki.requestLogName, "WARN");
LogCtl.setLevel(Fuseki.adminLogName, "WARN");
LogCtl.setLevel("org.eclipse.jetty", "WARN");
Building a server
A FusekiServer
is built by creating a configuration,
building the server, then running it. The application needs to start
the server.
The default port for a Fuseki embedded server is 3330. This is different for the default port for Fuseki running as a standalone server or as a webapp application.
Examples of embedded use
Example 1
Create a server on port 3330, that provides the default set of endpoints for an RDF dataset that can be updated via HTTP.
Dataset ds = DatasetFactory.createTxnMem() ;
FusekiServer server = FusekiServer.create()
.add("/ds", ds)
.build() ;
server.start() ;
...
server.stop() ;
The services are avilable on a named endpoint and also on the dataset URL itself.
URLs:
Service | Endpoint1 | Endpoint2 |
---|---|---|
SPARQL Query | http://host:3330/ds/query |
http://host:3330/ds |
SPARQL Query | http://host:3330/ds/sparql |
http://host:3330/ds |
SPARQL Update | http://host:3330/ds/update |
http://host:3330/ds |
GSP read-write | http://host:3330/ds/data |
http://host:3330/ds |
“GSP” = SPARQL Graph Store Protocol
Example 2
Create a server on port 3332, that provides the default set of endpoints for a data set that is read-only over HTTP. The application can still update the dataset.
Dataset ds = ... ;
FusekiServer server = FusekiServer.create()
.port(3332)
.add("/ds", ds, false)
.build() ;
server.start() ;
Service | Endpoint | Endpoint2 |
---|---|---|
SPARQL Query | http://host:3332/ds/query |
http://host:3332/ds |
SPARQL Query | http://host:3332/ds/sparql |
http://host:3332/ds |
GSP read-only | http://host:3332/ds/data |
http://host:3332/ds |
Example 3
Different combinations of services and endpoint names can be given using a DataService
.
DatasetGraph dsg = ... ;
DataService dataService = new DataService(dsg) ;
dataService.addEndpoint(OperationName.GSP_RW, "");
dataService.addEndpoint(OperationName.Query, "");
dataService.addEndpoint(OperationName.Update, "");
FusekiServer server = FusekiServer.create()
.port(3332)
.add("/data", dataService)
.build() ;
server.start() ;
This setup puts all the operation on the dataset URL. The Content-type
and any query
string is used to determine the operation.
Service | Endpoint |
---|---|
SPARQL Query | http://host:3332/ds |
SPARQL Update | http://host:3332/ds |
GSP read-write | http://host:3332/ds |
Example 4
Multiple datasets can be served by one server.
Dataset ds1 = ...
Dataset ds2 = ...
FusekiServer server = FusekiServer.create()
.add("/data1", ds1)
.add("/data1-readonly", ds1, true)
.add("/data2", ds2)
.build() ;
server.start() ;