...
Camel makes use of "components" to integrate various services using a terse, domain specific language that can be expressed in JAVA, XML, Scala or Groovy. There exists one such component designed to work specifically with a Fedora4 repository. This makes it possible to model Solr indexing in only a few lines of code like so:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
XPathBuilder xpath = new XPathBuilder("/rdf:RDF/rdf:Description/rdf:type[@rdf:resource='http://fedora.info/definitions/v4/rest-api#indexable']") xpath.namespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") from("activemq:topic:fedora") .to("fcrepo:localhost:8080/fedora/rest") .filter(xpath) .to("fcrepo:localhost:8080/fedora/rest?accept=application/json&transform=default") .to("http4:localhost:8080/solr/core/update"); |
...
This same logic can also be expressed using the Spring XML extensions:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<route> <from uri="activemq:topic:fedora"/> <to uri="fcrepo:localhost:8080/fedora/rest"/> <filter> <xpath>/rdf:RDF/rdf:Description/rdf:type[@rdf:resource='http://fedora.info/definitions/v4/rest-api#indexable']</xpath> <to uri="fcrepo:localhost:8080/fedora/rest?accept=application/json&transform=default"/> <to uri="http4:localhost:8080/solr/core/update"/> </filter> </route> |
Or, in Scala:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
val xpath = new XPathBuilder("/rdf:RDF/rdf:Description/rdf:type[@rdf:resource='http://fedora.info/definitions/v4/rest-api#indexable']") xpath.namespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") "activemq:topic:fedora" ==> { to("fcrepo:localhost:8080/fedora/rest") filter(xpath) { to("fcrepo:localhost:8080/fedora/rest?accept=application/json&transform=default") to("http4:localhost:8080/solr/core/update") } } |
...
If an fcr:transform
program has been installed as mytransform
, you can generate a JSON representation of an object and send it to a low-latency, highly available document store, such as Riak: Riak. The following route determines if an object has been removed or simply added/updated. It then routes the message appropriately to a load-balancer sitting in front of the Riak HTTP endpoint.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
val riakKeyProcessor = (exchange: Exchange) => { exchange.getIn.setHeader( Exchange.HTTP_PATH, "/buckets/fcrepo/keys/" + URLEncoder.encode(exchange.getIn.getHeader("org.fcrepo.jms.identifier", classOf[String])) ) } "activemq:topic:fedora" ==> { choice() { when(_.in("org.fcrepo.jms.eventType") == "http://fedora.info/definitions/v4/repository#NODE_REMOVED") { setHeader(Exchange.HTTP_METHOD, constant("DELETE")) process(riakKeyProcessor) to("http4:localhost:8098") } otherwise() { to("fcrepo:localhost:8080/fedora/rest") filter(xpathFilter) { to("fcrepo:localhost:8080/fedora/rest?accept=application/json&transform=mytransform") setHeader(Exchange.HTTP_METHOD, constant("PUT")) process((exchange: Exchange) => { exchange.getIn.setHeader( Exchange.HTTP_PATH, "/buckets/fcrepo/keys/" + URLEncoder.encode(exchange.getIn.getHeader("org.fcrepo.jms.identifier", classOf[String])) ) }) process(riakKeyProcessor) to("http4:localhost:8098") } } } } |
External Triplestore
Some additional processing must be done to transform an application/n-triples
response into a valid application/sparql-update
payload before sending to Fuseki or Sesame. The fcrepo component contains some processors in org.fcrepo.camel.processor
to handle this case.
...