Quaestor demo

This is a demo of the reasoning capabilities described elsewhere. To work through the demo, you need to have a Quaestor service running inside a Tomcat server: I'll take that to be running at http://localhost:8080/quaestor. You need at least Quaestor v0.5.

The Quaestor interface is documented on the front page of the Quaestor server. It uses the HTTP protocol commands to manipulate then query the server, so you need curl or some other tool which can generate HTTP GET, PUT and POST commands (the wget program can do POST, but not PUT). Or write a Java client. Or you can just talk HTTP yourself, using telnet to port 8080.

The HTTP demo

First, create a new knowledgebase, with a PUT command, as follows. Call the knowledgebase `testing', and upload a simple bit of RDF, contained in the file kb-metadata.ttl:

% curl --upload-file kb-metadata.ttl \
    --header content-type:text/turtle \

Note that we have to tell Quaestor that the input is Turtle, and not the default RDF/XML. It is also possible to POST a plain text description at this point (it's equivalent to adding metadata with only a dc:description property), but that won't do here, as the work we want to do below requires us to use a reasoner within the knowledgebase, and so we must tell Quaestor to configure this, within the kb-metadata.ttl file.

The backslashes in this command, by the way, let us break the command onto multiple lines – omit them if you type the command on a single line.

If you add the --verbose flag to the curl command line, you will see (instructive?) protocol chatter, as well as the 204 (no content) return code from the server.

Retrieving the URL http://localhost:8080/quaestor/kb, either using curl or in a web browser, will show you that you have created this knowledgebase.

Now you can add to the knowledgebase the three sets of assertions contained in files access-control.owl, instances.ttl and identity.ttl. Add these to the knowledgebase submodels ontology, people and identities respectively (the names are arbitrary, and you can use alternatives if you wish).

% curl --upload-file access-control.owl \
% curl --upload-file instances.ttl \
    'http://localhost:8080/quaestor/kb/testing/people?instances' \
    --header content-type:text/turtle
% curl --upload-file identity.ttl \
    http://localhost:8080/quaestor/kb/testing/identities \
    --header content-type:text/turtle

The two .ttl files are written in Turtle; this is equivalent (in this context) to Notation 3, which you may otherwise have heard of. Since this is not the default MIME type which Quaestor expects, we must include a Content-Type header. The access-control.owl file, however, is written in the default RDF/XML serialisation, so we do not need to add a Content-Type header to the upload, though it is not wrong, and generally better, to include it anyway. The instances.ttl file is uploaded with a ?instances query attached – this tells the reasoner that these are assertions about individuals rather than types; this distinction is currently important.

The access-control.owl file expresses an access policy (you can read it more legibly in the file access-control.ttl, and see the class hierarchy, but not the relevant class definitions, in the image access-control.png, obtained from Protégé). The intent is that both members of UK instititions and members of the X Collaboration can see all of the data, and that members of African countries can see a flagged subset of the data.

If you now look again at http://localhost:8080/quaestor/kb you will see the knowledgebase and its submodels listed.

You can retrieve the individual submodels from the Quaestor service:

% curl http://localhost:8080/quaestor/kb/testing/people

will respond with the contents of the people submodel in the default RDF/XML format (MIME type application/rdf+xml), and if you add --header accept:text/turtle to the curl command, you'll get it in Turtle again. If you retrieve http://localhost:8080/quaestor/kb/testing you'll get the union of the three submodels.

There are several SPARQL queries in the demo for you to try. The query access-all.rq is:

prefix : <http://eurovotech.org/access-control.owl#>
select ?person
where { ?person a :CanSeeAllData }

You can post this file with an HTTP POST request:

% curl --header content-type:application/sparql-query \
    --data-binary @access-all.rq \

This should respond with an XML document which conforms to the SPARQL response scheme. If you add --header accept:text/plain or --header accept:text/csv to the command, the reasoner will produce a response in the corresponding format. For example:

curl --header content-type:application/sparql-query \
     --data-binary @access-all.rq \
     http://localhost:8080/quaestor/kb/testing \
    --header accept:text/csv

Compare this with the contents of the instances.ttl file. Individuals urn:example#Norman and urn:example#Guy can see all the data because they are members of UK institutions; mailto:norman@astro.gla.ac.uk can see all the data because he is asserted to be identical with urn:example#Norman; Nelson and Jonathan can see all of the data because they are members of the collaboration; Markus, Sébastien and Tutankhamun are locked out (sorry!).

There are several other queries you can try:

This query asks which individuals are in the flagged-data group. If you run this query, you see that everyone who can see all of the data can also see the flagged subset (which makes sense), but that urn:example#Tutankhamun can also see the subset, because he’s at an African institution.
This query asks the yes/no question of whether norman@astro.gla.ac.uk is allowed to see all the data (the answer is ‘yes’). Note that text/csv isn't an acceptable response format for an ASK query, so you'll have to use either application/sparql-results+xml, which is the default, or text/plain.
This uses a SPARQL construct query to obtain a query result in RDF. Only one or other of the RDF types is acceptable as a response format (the default is, as usual, RDF/XML).
This query is malformed (there's a missing angle bracket). The reasoner responds with an HTTP 400 status.

Finally, you can delete the knowledgebase with the HTTP DELETE command, which you can produce using curl as follows:

% curl -X DELETE http://localhost:8080/quaestor/kb/testing

The XML-RPC demo

Quaestor also has an XML-RPC interface, with an endpoint at http://localhost:8080/quaestor/xmlrpc, though it has rather less functionality at present.

The file xmlrpc-get-model.xml contains an XML-RPC method call:


You can post this to the server as follows:

% curl --header content-type:text/xml \
    --data-binary @xmlrpc-get-model.xml \

and get a response which simply indicates that you should dereference another URL.

Slightly more useful is the query-model method, illustrated in xmlrpc-query-model.xml. This makes a SPARQL query against the model, and returns a temporary URL which can be dereferenced to pick up the query results.


There are SPARQL tutorials at http://www-128.ibm.com/developerworks/xml/library/j-sparql/ and http://jena.sourceforge.net/ARQ/Tutorial/.

The (rather informal) XML-RPC spec is at http://www.xmlrpc.com/spec.

Thanks to Tom Doherty for his painstaking debugging of this walkthrough; his pain is your gain!

Norman Gray
2008 October