Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/stain/paq
Example of using PROV-AQ
https://github.com/stain/paq
Last synced: about 1 month ago
JSON representation
Example of using PROV-AQ
- Host: GitHub
- URL: https://github.com/stain/paq
- Owner: stain
- Created: 2013-03-15T16:31:55.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2013-03-27T16:29:01.000Z (almost 12 years ago)
- Last Synced: 2024-11-05T13:13:13.333Z (3 months ago)
- Language: Java
- Size: 172 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Providing provenance for a RESTful service
==========================================This is an example of how a a RESTful service, implemented using [JAX-RS and CXF](http://cxf.apache.org/docs/jax-rs-basics.html), can expose [provenance](http://www.w3.org/TR/prov-overview/) of the resources it exposes.
There are two branches in this project on https://github.com/stain/paq:
* *master* - REST service that can say hello, and return provenance of greeting
* *paq* - REST service that also provides link between greeting and its provenanceTo compile/run, you will need Java and [Maven](http://maven.apache.org/download.cgi):
PS C:\users\stain\src\paq> mvn clean jetty:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Example PROV-AQ usage 0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(..)
2013-03-25 15:39:09.419:INFO::Started [email protected]:8080
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 10 seconds.The base URI should be http://localhost:8080/paq/ unless you modified the port with
mvn -Djetty.port=9999
Check the HelloWorld REST service is working using your favourite HTTP client (e.g. browser or curl in a new terminal window).PS C:\Users\stain\src\paq> curl http://localhost:8080/paq/hello/Alice
Hello, AliceYou may replace *Alice* with any name, as long as it is URI escaped:
PS C:\Users\stain\src\paq> curl http://localhost:8080/paq/hello/Joe%20Bloggs
Hello, Joe BloggsProvenance resource
-------------------This example service provide [provenance](http://www.w3.org/TR/prov-overview/),
using the [PROV-N](http://www.w3.org/TR/prov-n/) format:PS C:\Users\stain\src\paq> curl -i http://localhost:8080/paq/provenance/hello/Alice
HTTP/1.1 200 OK
Content-Type: text/provenance-notation
Date: Mon, 25 Mar 2013 15:41:02 GMT
Content-Length: 305
Server: Jetty(6.1.26)
document
prefix hello
prefix app
entity(hello:Alice)
wasDerivedFrom(hello:Alice, name)
entity(name, [ prov:value="Alice" ])
agent(app:hello, [ prov:type=prov:SoftwareAgent ])
wasAttributedTo(hello:Alice, app:hello)
endDocument
Note that we used the
-i
parameter above to verify that the correct media-type [text/provenance-notation](http://www.iana.org/assignments/media-types/text/provenance-notation) was returned.This provenance says that the resource was derived from a name with value "Alice", and made by the (web) service .
This PROV-N trace is generated by
HelloWorld.helloProvenance()
by filling in the URIs and name in the template src/main/resources/provTemplate.txt - a more detailed provenance trace might include things like timestamps and details about who provided the name.Providing links to the provenance
---------------------------------A restful client who has requested will not magically know that there is a provenance trace at - the URI for the provenance resource could just as well have been say .
Rather than for each publisher to invent specific ways to locate the provenance resource, the W3C [PROV-AQ](http://www.w3.org/TR/prov-aq/) Note suggests a common way to find the provenance resource by using HTTP
Link:
headers according to [RFC5988](http://tools.ietf.org/html/rfc5988)Specifically, PAQ says that a [resource accessed by HTTP](http://www.w3.org/TR/2013/WD-prov-aq-20130312/#resource-accessed-by-http) can
describe its provenance trace by adding aLink}} header with the relation "http://www.w3.org/ns/prov#has_provenance". So in our case, this can be achieved with:
Link: ; rel="http://www.w3.org/ns/prov#has_provenance"
OK, so how do we provide this Link header? Our existing greeting is
quite simple thanks to [JAX-RS and CXF](http://cxf.apache.org/docs/jax-rs-basics.html):@GET
@Path("hello/{name}")
@Produces("text/plain")
public String hello(@PathParam("name") String name) {
String greeting = "Hello, " + name + "\n";
return greeting;
}Our provenance method is a bit more complicated as it [generates
the absolute URIs](http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-URIcalculationusingUriInfoandUriBuilder) for the greeting resource (depending on the name parameter) and then build the PROV-N trace - here using a simple [MessageFormat](http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html) template.@GET
@Path("provenance/hello/{name}")
@Produces("text/provenance-notation")
public String helloProvenance(@PathParam("name") String name,
@Context UriInfo ui) throws IOException {
// Get our absolute URI
// See http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-URIcalculationusingUriInfoandUriBuilder
UriBuilder appUri = ui.getBaseUriBuilder();
// Absolute URIs for resources we are to give provenance about
URI helloURI = appUri.path(getClass(), "hello").build(name);
// Prepare prefixes for PROV-N qualified names
URI appURI = appUri.build("").resolve("../");
URI helloPrefix = helloURI.resolve("./");
// The PROV-N qualified name for our /hello/{name} resource
String helloEntity = "hello:" + helloPrefix.relativize(helloURI);
// Simple PROV-N trace, see
// Here this is done in a naive way by loading a template
// from src/main/resources and do string-replace to insert
// our URIs.
String template = IOUtils.toString(getClass().getResourceAsStream("/provTemplate.txt"));
String prov = MessageFormat.format(template,
helloPrefix, appURI, helloEntity, name);
// Note: PROV-N should be be built using say the PROV Toolbox
// rather than this naive template approach!
return prov;
}So in order to provide the RESTful links we will need to insert *Link:*
headers in the hello() response. As we need to return both the greeting and HTTP headers,
we change our return to a [Response](http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/core/Response.html):@GET
@Path("hello/{name}")
@Produces("text/plain")
public Response hello(@PathParam("name") String name) {
String greeting = "Hello, " + name + "\n";
ResponseBuilder responseBuilder = Response.ok().entity(greeting);
return responseBuilder.build();
}We'll inject the same
@Context UriInfo ui
parameter as in
in order to find the absolute URI to calling the helloProvenance() method:public Response hello(@PathParam("name") String name, @Context UriInfo ui) {
URI provUri = ui.getBaseUriBuilder().path(getClass(), "helloProvenance").build(name);and then build a new [Link](http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/core/Link.html) instance:
Link provLink = Link.fromUri(provUri).rel(HAS_PROVENANCE).build();
This uses the fixed URI for the provenance relation:
private static final String HAS_PROVENANCE = "http://www.w3.org/ns/prov#has_provenance";
Finally we include the new Link header by adding it to the response builder before returning:
return responseBuilder.header(HttpHeaders.LINK, provLink).build();
The final version of hello() should then look something like:
@GET
@Path("hello/{name}")
@Produces("text/plain")
public Response hello(@PathParam("name") String name, @Context UriInfo ui) {
String greeting = "Hello, " + name + "\n";
ResponseBuilder responseBuilder = Response.ok().entity(greeting);
// TODO: Could have used Link.fromResourceMethod but it seems to return wrong URI in CXF :(
URI provUri = ui.getBaseUriBuilder().path(getClass(), "helloProvenance").build(name);
Link provLink = Link.fromUri(provUri).rel(HAS_PROVENANCE).build();
return responseBuilder.header(HttpHeaders.LINK, provLink).build();
}
You may check out thepaq
branch from https://github.com/stain/paq to see the final version.Finding the provenance links
----------------------------
If you have not followed the tutorial above, make sure you *check out* and *build*
thepaq
branch from https://github.com/stain/paq to include the PROV-AQ Link headers.