Context
Despite the number of questions/answers on the subject, I'm stil having trouble to configure Apache Jena Fuseki...
I'm trying to configure an Apache Jena Fuseki instance with TDB and OWL reasoner activated, for testing my application. I need to create a dataset, execute my tests, and delete the dataset programatically.
Setup
I use stain/jena-fuseki
docker image to run Apache Jena Fuseki.
I run Jena Fuseki in version 3.10.0.
bash-4.3# ./fuseki-server -version
Jena: VERSION: 3.10.0
Jena: BUILD_DATE: 2018-12-30T15:45:57+0000
TDB: VERSION: 3.10.0
TDB: BUILD_DATE: 2018-12-30T15:45:57+0000
Fuseki: VERSION: 3.10.0
Fuseki: BUILD_DATE: 2018-12-30T15:45:57+0000
Base Configuration
I use folowing shiro.ini
file.
I allow full access for everyone this is only a test instance.
bash-4.3# cat /fuseki/shiro.ini
[main]
# Development
ssl.enabled = false
plainMatcher=org.apache.shiro.authc.credential.SimpleCredentialsMatcher
iniRealm.credentialsMatcher = $plainMatcher
[users]
admin=mysupersecurepassword
[roles]
[urls]
## Control functions open to anyone
/$/status = anon
/$/ping = anon
# Everything else
/**=anon
I use the default config.ttl
file:
bash-4.3# cat /fuseki/config.ttl
# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
## Fuseki Server configuration file.
@prefix : <#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
[] rdf:type fuseki:Server ;
.
What I'm tring to do ?
For testing my application I'm trying to create a dataset, execute tests, and delete the dataset programatically. For this purpose I use Fuseki HTTP Administration Protocol.
I follow these steps:
POST /$/datasets
to create dataset.POST /dataset_name/data
to upload data files.- (Execute my application tests)
POST /dataset_name?update=DROP+ALL
to remove data.DELETE /$/datasets/dataset_name
to delete dataset.
Step 1:
Using curl :
curl -F 'files[][email protected]' http://localhost:3030/$/datasets
I use following dataset.ttl
file:
@prefix fuseki: <http://jena.apache.org/fuseki#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix : <#> .
# Custom code
tdb:GraphTDB rdfs:subClassOf ja:Model .
# Setup service
:service rdf:type fuseki:Service ;
rdfs:label "TDB dataset_name" ;
fuseki:name "dataset_name" ;
fuseki:dataset :dataset ;
fuseki:serviceQuery "query", "sparql" ;
fuseki:serviceUpdate "update" ;
fuseki:serviceUpload "upload" ;
fuseki:serviceReadWriteGraphStore "data" ;
fuseki:serviceReadGraphStore "get" ;
.
# Setup Assembler model with reasoner
:dataset rdf:type ja:RDFDataset;
ja:defaultGraph :modelInf ;
.
:modelInf rdf:type ja:InfModel;
ja:baseModel :tdbGraph ;
ja:reasoner [
ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>
] ;
.
# TDB dataset used for RDF storage
:tdbGraph rdf:type tdb:GraphTDB;
tdb:location "/fuseki/databases/dataset_name" ;
.
Jena Fuseki logs
[2019-10-23 14:41:00] Admin INFO [6] POST http://localhost:3030/$/datasets
[2019-10-23 14:41:00] Admin INFO [6] Filename: dataset.ttl, Content-Type=application/octet-stream, Charset=null => Turtle : Count=19 Triples=19 Quads=0
[2019-10-23 14:41:00] Admin INFO [6] Create database : name = /dataset_name
[2019-10-23 14:41:02] Admin INFO [6] 200 OK (1.894 s)
Everything is OK :P
Step 2:
Using curl :
curl -F 'files[][email protected]' http://localhost:3030/dataset_name/data
{
"count" : 1524 ,
"tripleCount" : 1524 ,
"quadCount" : 0
}
Jena Fuseki logs
[2019-10-23 14:44:52] Fuseki INFO [7] POST http://localhost:3030/dataset_name/data
[2019-10-23 14:44:53] Fuseki INFO [7] Filename: data.rdf, Content-Type=application/octet-stream, Charset=null => RDF/XML : Count=1524 Triples=1524 Quads=0
[2019-10-23 14:44:54] Fuseki INFO [7] 200 OK (1.858 s)
Everything is OK :P
Step 3 :
Testing my application (useless here)
Step 4:
Using curl :
curl -d "update=DROP+ALL" -X POST http://localhost:3030/dataset_name/update
...
Update succeeded
...
Jena Fuseki logs
[2019-10-23 15:04:13] Fuseki INFO [67] POST http://localhost:3030/dataset_name/update
[2019-10-23 15:04:14] Fuseki INFO [67] 200 OK (268 ms)
Everything is OK :P
Step 5:
Using curl :
curl -X DELETE http://localhost:3030/$/datasets/dataset_name
Jena Fuseki logs
[2019-10-23 15:10:17] Admin INFO [92] DELETE http://localhost:3030/$/datasets/dataset_name
[2019-10-23 15:10:17] Admin INFO [92] DELETE ds=/dataset_name
[2019-10-23 15:10:17] Server INFO Shutting down data service for [, data, upload, query, get, update, sparql]
[2019-10-23 15:10:17] Admin WARN [92] RC = 500 : Not in a transaction
org.apache.jena.tdb.transaction.TDBTransactionException: Not in a transaction
at org.apache.jena.tdb.transaction.DatasetGraphTransaction.get(DatasetGraphTransaction.java:140)
at org.apache.jena.tdb.transaction.DatasetGraphTransaction.getDatasetGraphToQuery(DatasetGraphTransaction.java:86)
at org.apache.jena.tdb.store.GraphTxnTDB.getDatasetGraphTDB(GraphTxnTDB.java:51)
at org.apache.jena.tdb.store.GraphTDB.sync(GraphTDB.java:128)
at org.apache.jena.tdb.store.GraphTDB.close(GraphTDB.java:133)
at org.apache.jena.reasoner.BaseInfGraph.close(BaseInfGraph.java:445)
at org.apache.jena.reasoner.rulesys.BasicForwardRuleInfGraph.close(BasicForwardRuleInfGraph.java:360)
at org.apache.jena.reasoner.rulesys.FBRuleInfGraph.close(FBRuleInfGraph.java:710)
at org.apache.jena.sparql.core.DatasetGraphMapLink.close(DatasetGraphMapLink.java:199)
at org.apache.jena.fuseki.server.DataService.expel(DataService.java:223)
at org.apache.jena.fuseki.server.DataService.shutdown(DataService.java:199)
at org.apache.jena.fuseki.mgt.ActionDatasets.execDeleteItem(ActionDatasets.java:360)
at org.apache.jena.fuseki.ctl.ActionContainerItem.execDelete(ActionContainerItem.java:105)
at org.apache.jena.fuseki.ctl.ActionContainerItem.perform(ActionContainerItem.java:64)
at org.apache.jena.fuseki.ctl.ActionCtl.executeLifecycle(ActionCtl.java:68)
at org.apache.jena.fuseki.ctl.ActionCtl.executeAction(ActionCtl.java:62)
at org.apache.jena.fuseki.ctl.ActionCtl.execCommonWorker(ActionCtl.java:53)
at org.apache.jena.fuseki.servlets.ActionBase.doCommon(ActionBase.java:74)
at org.apache.jena.fuseki.ctl.ActionContainerItem.doDelete(ActionContainerItem.java:52)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655)
at org.apache.jena.fuseki.servlets.FusekiFilter.doFilter(FusekiFilter.java:101)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.apache.jena.fuseki.servlets.CrossOriginFilter.handle(CrossOriginFilter.java:285)
at org.apache.jena.fuseki.servlets.CrossOriginFilter.doFilter(CrossOriginFilter.java:248)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:690)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:503)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:745)
[2019-10-23 15:10:17] Admin INFO [92] 500 Not in a transaction (65 ms)
Here is the problem. Anyone can help solving this ?
Thoughts / Tries
I try same procedure with the default dataset configuration file and get no error. So I asume this come from the dataset configuration file.
Here what I called default dataset configuration file:
@prefix : <http://base/#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix tdb2: <http://jena.apache.org/2016/tdb#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
:service_tdb_all a fuseki:Service ;
rdfs:label "TDB2 dataset_name" ;
fuseki:dataset :tdb_dataset_readwrite ;
fuseki:name "dataset_name" ;
fuseki:serviceQuery "query" , "sparql" ;
fuseki:serviceReadGraphStore "get" ;
fuseki:serviceReadWriteGraphStore "data" ;
fuseki:serviceUpdate "update" ;
fuseki:serviceUpload "upload" .
:tdb_dataset_readwrite a tdb2:DatasetTDB2 ;
tdb2:location "/fuseki/databases/dataset_name" .
I don't find any clear enought for me documentation on how to properly configure Jena Fuseki. Lots of exemples can be found but dated from some years, don't know if they are still uptodate. And no explanation on how they really works so it is hard to addapt to a specific case.
If any docs / tutorial to explain what are "ja:RDFDataset", "ja:InfModel" and other "ja:things" and how they works would be much appreciated.
I'm still starting with ontology/triplestores/linked data and thoses docs are not the easiest to read :
- https://jena.apache.org/documentation/assembler/
- https://jena.apache.org/documentation/javadoc/jena/org/apache/jena/assembler/JA.html
I tried different configuration examples and always get errors either on steps 1 or 5.
Example
Config:
@prefix : <#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
[] rdf:type fuseki:Server ;
fuseki:services (
<#service>
) .
## ---------------------------------------------------------------
## Service with only SPARQL query on an inference model.
## Inference model base data in TDB.
<#service> rdf:type fuseki:Service ;
fuseki:name "dataset_name" ;
fuseki:serviceQuery "query" , "sparql" ;
fuseki:serviceUpdate "update" ;
fuseki:serviceUpload "upload" ;
fuseki:serviceReadWriteGraphStore "data" ;
fuseki:serviceReadGraphStore "get" ;
fuseki:dataset <#dataset> ;
.
<#dataset> rdf:type ja:RDFDataset ;
ja:defaultGraph <#model> ;
.
<#model> rdf:type ja:InfModel ;
ja:baseModel <#tdbGraph> ;
ja:reasoner [
ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner> ;
] ;
.
<#tdbGraph> rdf:type tdb:GraphTDB ;
tdb:dataset <#tdbDataset> ;
.
<#tdbDataset> rdf:type tdb:DatasetTDB ;
tdb:location "/fuseki/databases/dataset_name" ;
.
Error on step 1.
Fuseki log:
[2019-10-23 15:20:51] Admin INFO [93] POST http://localhost:3030/$/datasets
[2019-10-23 15:20:51] Admin INFO [93] Filename: dataset.ttl, Content-Type=text/turtle, Charset=null => Turtle : Count=23 Triples=23 Quads=0
[2019-10-23 15:20:51] Admin INFO [93] Create database : name = /dataset_name
[2019-10-23 15:20:51] Admin WARN [93] RC = 500 : cannot find a most specific type for :tdbGraph, which has as possibilities: ja:Model tdb:GraphTDB.
org.apache.jena.assembler.exceptions.AmbiguousSpecificTypeException: cannot find a most specific type for :tdbGraph, which has as possibilities: ja:Model tdb:GraphTDB.