Commit 32602d55 authored by acoburn's avatar acoburn
Browse files

Merge branch 'acrepo-template'

parents eedffd7b e3c00e39
......@@ -9,3 +9,7 @@ jsonld.context=https://acdc.amherst.edu/jsonld/context.json"
# Repository Base URL
fcrepo.baseUrl=localhost:8080/fcrepo/rest
# Riak settings
riak.host=localhost:8098
riak.bucket=fcrepo
......@@ -23,20 +23,19 @@ public class RiakKeyBuilder implements Processor {
final Message in = exchange.getIn();
final CamelContext ctx = exchange.getContext();
final StringBuilder key = new StringBuilder();
final StringBuilder key = new StringBuilder("/buckets/");
try {
final String prefix = ctx.resolvePropertyPlaceholders("{{riak.prefix}}");
final String prefix = ctx.resolvePropertyPlaceholders("{{riak.bucket}}");
key.append(prefix);
if (!prefix.endsWith("/")) {
key.append("/");
}
} catch (final Exception ex) {
throw new RuntimeCamelException("Could not resolve properties", ex);
}
key.append("/keys/");
key.append(URLEncoder.encode(
in.getHeader(FcrepoHeaders.FCREPO_IDENTIFIER, String.class), "UTF-8"));
in.removeHeader(Exchange.HTTP_URL);
in.setHeader(Exchange.HTTP_PATH, key.toString());
}
}
......
......@@ -17,7 +17,7 @@
<cm:property name="jsonld.context" value="https://acdc.amherst.edu/jsonld/context.json"/>
<cm:property name="fcrepo.baseUrl" value="localhost:8080/fcrepo/rest"/>
<cm:property name="riak.host" value="localhost:8098"/>
<cm:property name="riak.prefix" value="/buckets/fcrepo/keys"/>
<cm:property name="riak.bucket" value="fcrepo"/>
</cm:default-properties>
</cm:property-placeholder>
......
......@@ -99,4 +99,20 @@
<configfile finalname="/etc/edu.amherst.acdc.jsonld.cache.cfg">mvn:edu.amherst.acdc/acrepo-jsonld-cache/${project.version}/cfg/configuration</configfile>
</feature>
<feature name="acrepo-template-mustache" version="${project.version}" resolver="(orb)" start-level="50">
<details>Installs a sample JSON-LD-based template rendering service</details>
<feature version="${camel.version}">camel</feature>
<feature version="${camel.version}">camel-blueprint</feature>
<feature version="${camel.version}">camel-mustache</feature>
<feature version="${camel.version}">camel-jetty9</feature>
<feature version="${camel.version}">camel-http4</feature>
<feature version="${fcrepo-camel.version}">fcrepo-camel</feature>
<feature version="${project.version}">acrepo-jsonld-cache</feature>
<bundle>mvn:edu.amherst.acdc/acrepo-template-mustache/${project.version}</bundle>
<configfile finalname="/etc/edu.amherst.acdc.template.mustache.cfg">mvn:edu.amherst.acdc/acrepo-template-mustache/${project.version}/cfg/configuration</configfile>
</feature>
</features>
Amherst College XML-based metadata transformation service
=========================================================
This service implements a translation service from Fedora RDF-based metadata
to either a DC/XML or MODS/XML serialization. This translation relies on
pluggable XSLT 2.0 documents.
The service becomes available over HTTP on the configured port. For example,
in order to retrieve a MODS version of the resource `a/b/c`:
curl localhost:9070/mods/a/b/c
And the DC version:
curl localhost:9070/dc/a/b/c
Building
--------
To build this project use
mvn install
To run the project you can execute the following Maven goal
mvn camel:run
Deploying in OSGi
-----------------
This project can be deployed in an OSGi container. For example using
[Apache Karaf](http://karaf.apache.org) version 4.x and above, you can run the following
command from its shell:
feature:repo-add mvn:edu.amherst.acdc/repository-services/LATEST/xml/features
feature:install acrepo-xml-metadata
Or by copying the compiled bundle into `$KARAF_HOME/deploy`.
Configuration
-------------
The application can be configured by creating the following configuration
file `$KARAF_HOME/etc/edu.amherst.acdc.xml.metadata.cfg`. The following values
are available for configuration:
In the event of failure, the maximum number of times a redelivery will be attempted.
error.maxRedeliveries=10
The location of the XSLT document for MODS. This can be a file path (using the `file:` prefix)
or an external URL (e.g. using a `http:` scheme). Without a prefix, the XSL file will
be loaded from the classpath.
mods.xslt=edu/amherst/acdc/xml/metadata/rdf2mods.xsl
The location of the XSLT document for DC. This can be a file path (using the `file:` prefix)
or an external URL (e.g. using a `http:` scheme). Without a prefix, the XSL file will
be loaded from the classpath.
dc.xslt=edu/amherst/acdc/xml/metadata/rdf2dc.xsl
The port on which the service is available
rest.port=9070
The fedora baseUrl value
fcrepo.baseUrl=localhost:8080/fcrepo/rest
By editing this file, any currently running routes will be immediately redeployed
with the new values.
For more help see the [Apache Camel](http://camel.apache.org) documentation
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>edu.amherst.acdc</groupId>
<artifactId>repository-services</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>acrepo-template-mustache</artifactId>
<packaging>bundle</packaging>
<name>A template rendering service, based on JSON-LD documents</name>
<properties>
<osgi.private.packages>edu.amherst.acdc.template.mustache</osgi.private.packages>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty9</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-blueprint</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mustache</artifactId>
</dependency>
<dependency>
<groupId>org.fcrepo.camel</groupId>
<artifactId>fcrepo-camel</artifactId>
</dependency>
<dependency>
<groupId>edu.amherst.acdc</groupId>
<artifactId>acrepo-jsonld-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>edu.amherst.acdc</groupId>
<artifactId>acrepo-jsonld-cache</artifactId>
<version>${project.version}</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- Testing & Camel Plugin -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-blueprint</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<!-- to generate the MANIFEST-FILE of the bundle -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
<!-- to run the example using mvn camel:run -->
<plugin>
<groupId>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
</plugin>
<!-- add configuration file to artifact set for OSGi deployment -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>src/main/cfg/edu.amherst.acdc.template.mustache.cfg</file>
<type>cfg</type>
<classifier>configuration</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
# The maximum number or redeliveries for any message
error.maxRedeliveries=10
# The port on which the service is made available
rest.port=13433
# The fedora baseUrl
fcrepo.baseUrl=localhost:8080/fcrepo/rest
# The host and prefix of the riak cluster
riak.host=localhost:8098
riak.bucket=fcrepo
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.amherst.acdc.template.mustache;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
import static org.apache.camel.Exchange.HTTP_URL;
import static org.apache.camel.Exchange.HTTP_URI;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER;
import org.apache.camel.builder.RouteBuilder;
import edu.amherst.acdc.jsonld.cache.RiakKeyBuilder;
/**
* @author Aaron Coburn
*/
public class EventRouter extends RouteBuilder {
/**
* Configure the message route workflow.
*/
public void configure() throws Exception {
/**
* A generic error handler (specific to this RouteBuilder)
*/
onException(Exception.class)
.maximumRedeliveries("{{error.maxRedeliveries}}")
.log("Event Routing Error: ${routeId}");
from("jetty:http://0.0.0.0:{{rest.port}}/template?" +
"matchOnUriPrefix=true&httpMethodRestrict=GET&sendServerVersion=false")
.routeId("TemplateTransformation")
.log("PATH: ${headers[CamelHttpPath]}")
.setHeader(FCREPO_IDENTIFIER).simple("${headers[CamelHttpPath]}")
.removeHeader("breadcrumbId")
.removeHeader("Accept")
.removeHeader("User-Agent")
.to("direct:getFromCache")
.choice()
.when(header(HTTP_RESPONSE_CODE).isEqualTo(200)).to("direct:template")
.otherwise().to("direct:getFromFedora");
from("direct:getFromCache")
.routeId("FetchFromCache")
.removeHeader(HTTP_URL)
.removeHeader(HTTP_URI)
.process(new RiakKeyBuilder())
.to("http4:{{riak.host}}?throwExceptionOnFailure=false");
from("direct:getFromFedora")
.routeId("FetchFromRepository")
.to("fcrepo:{{fcrepo.baseUrl}}?accept=application/ld+json&throwExceptionOnFailure=false")
.filter(header(HTTP_RESPONSE_CODE).isEqualTo(200))
.to("direct:compact")
.to("direct:template");
from("direct:template")
.routeId("TemplateRoute")
.to("mustache:{{mustache.template}}");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<!-- OSGI blueprint property placeholder -->
<cm:property-placeholder persistent-id="edu.amherst.acdc.template.mustache" update-strategy="reload">
<cm:default-properties>
<cm:property name="error.maxRedeliveries" value="10"/>
<cm:property name="rest.port" value="13433"/>
<cm:property name="mustache.template" value="edu/amherst/acdc/template/mustache/template.mustache"/>
<cm:property name="jsonld.context" value="https://acdc.amherst.edu/jsonld/context.json"/>
<cm:property name="fcrepo.baseUrl" value="localhost:8080/fcrepo/rest"/>
<cm:property name="riak.host" value="localhost:8098"/>
<cm:property name="riak.bucket" value="fcrepo"/>
</cm:default-properties>
</cm:property-placeholder>
<reference id="jsonldService" interface="edu.amherst.acdc.jsonld.JsonLdService" filter="(osgi.jndi.service.name=jsonld)" />
<camelContext xmlns="http://camel.apache.org/schema/blueprint" streamCache="false">
<package>edu.amherst.acdc.template.mustache</package>
<route id="JsonLdCompaction">
<from uri="direct:compact"/>
<setHeader headerName="JsonLdContext">
<simple>{{jsonld.context}}</simple>
</setHeader>
<setBody>
<method ref="jsonldService" method="compact(${body}, ${header[JsonLdContext]})"/>
</setBody>
</route>
</camelContext>
</blueprint>
package edu.amherst.acdc.template.mustache;
import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
import org.junit.Test;
/**
* @author acoburn
*/
public class RouteTest extends CamelBlueprintTestSupport {
@Override
protected String getBlueprintDescriptor() {
return "/OSGI-INF/blueprint/blueprint.xml";
}
@Test
public void testRoute() throws Exception {
getMockEndpoint("mock:result").expectedMinimumMessageCount(0);
// assert expectations
assertMockEndpointsSatisfied();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n</pattern>
</encoder>
</appender>
<logger name="edu.amherst.acdc.template.mustache" additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.apache.camel" additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.fcrepo.camel" additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</logger>
<root additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
......@@ -52,6 +52,7 @@
<module>acrepo-xml-metadata</module>
<module>acrepo-jsonld-service</module>
<module>acrepo-jsonld-cache</module>
<module>acrepo-template-mustache</module>
</modules>
<dependencyManagement>
......@@ -66,6 +67,11 @@
<artifactId>camel-blueprint</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mustache</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty9</artifactId>
......@@ -206,4 +212,4 @@
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
</project>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment