Skip to content

Commit

Permalink
Expose loader as an extension
Browse files Browse the repository at this point in the history
Self-load and expose as a repository-scoped service, bound to the
repository root resource.

Resolves fcrepo4-labs#84
  • Loading branch information
birkland authored and emetsger committed Nov 8, 2016
1 parent 254723f commit 94dfc6a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 23 deletions.
5 changes: 5 additions & 0 deletions fcrepo-api-x-binding/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
<groupId>org.fcrepo.client</groupId>
<artifactId>fcrepo-java-client</artifactId>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

package org.fcrepo.apix.binding.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -34,6 +37,7 @@
import org.fcrepo.client.FcrepoClient;
import org.fcrepo.client.FcrepoResponse;

import org.apache.commons.io.IOUtils;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Reference;
Expand Down Expand Up @@ -118,20 +122,32 @@ public Collection<Extension> getExtensionsFor(final WebResource resource) {
public Collection<Extension> getExtensionsFor(final WebResource resource,
final Collection<Extension> extensions) {

final Set<URI> rdfTypes = extensions.stream()
.map(Extension::getResource)
.peek(r -> LOG.debug("Examinining the ontology closure of extension {}", r.uri()))
.map(ontologySvc::parseOntology)
.flatMap(o -> ontologySvc.inferClasses(resource.uri(), resource, o).stream())
.peek(rdfType -> LOG.debug("Instance {} is of class {}", resource.uri(), rdfType))
.collect(Collectors.toSet());

return extensions.stream()
.peek(e -> LOG.debug("Extension {} binds to instances of {}", e.uri(), e.bindingClass()))
.filter(e -> rdfTypes.contains(e.bindingClass()))
.peek(e -> LOG.debug("Extension {} bound to instance {} via {}", e.uri(), resource.uri(), e
.bindingClass()))
.collect(Collectors.toList());
try (final InputStream resourceContent = resource.representation()) {

final byte[] content = IOUtils.toByteArray(resourceContent);

final Set<URI> rdfTypes = extensions.stream()
.map(Extension::getResource)
.peek(r -> LOG.debug("Examinining the ontology closure of extension {}", r.uri()))
.map(ontologySvc::parseOntology)
.flatMap(o -> ontologySvc.inferClasses(resource.uri(), cached(resource, content), o).stream())
.peek(rdfType -> LOG.debug("Instance {} is of class {}", resource.uri(), rdfType))
.collect(Collectors.toSet());

return extensions.stream()
.peek(e -> LOG.debug("Extension {} binds to instances of {}", e.uri(), e.bindingClass()))
.filter(e -> rdfTypes.contains(e.bindingClass()))
.peek(e -> LOG.debug("Extension {} bound to instance {} via {}", e.uri(), resource.uri(), e
.bindingClass()))
.collect(Collectors.toList());
} catch (final IOException e) {
throw new RuntimeException(e);
}
}

private WebResource cached(final WebResource initial, final byte[] content) {
return WebResource.of(new ByteArrayInputStream(content), initial.contentType(), initial.uri(), initial
.name());
}

/** Just does a dumb dereference and lookup */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.fcrepo.apix.loader.impl;

import static org.apache.camel.Exchange.CONTENT_TYPE;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;

import java.io.InputStream;
Expand All @@ -44,6 +45,8 @@ public class LoaderRoutes extends RouteBuilder {

private static final String ROUTE_NO_SERVICE = "direct:no_service";

private static final String ROUTE_OPTIONS = "direct:options";

LoaderService loaderService;

/**
Expand All @@ -57,14 +60,26 @@ public void setLoaderService(final LoaderService svc) {

@Override
public void configure() throws Exception {
restConfiguration().component("jetty").host("0.0.0.0").port("{{loader.port}}");

rest("/load")
.get()
.produces("text/html").to("language:simple:resource:classpath:form.html")
from("jetty:http://0.0.0.0:{{loader.port}}/load" +
"?matchOnUriPrefix=true&sendServerVersion=false&httpMethodRestrict=GET,OPTIONS,POST")
.id("loader-http")
.choice()

.when(header(Exchange.HTTP_METHOD).isEqualTo("GET"))
.setHeader("Content-Type", constant("text/html"))
.to("language:simple:resource:classpath:form.html")

.when(header(Exchange.HTTP_METHOD).isEqualTo("POST"))
.to(ROUTE_PREPARE_LOAD)

.otherwise().to(ROUTE_OPTIONS);

.post().consumes("application/x-www-form-urlencoded, text/plain")
.to(ROUTE_PREPARE_LOAD);
from(ROUTE_OPTIONS).id("respond-options")
.setHeader(CONTENT_TYPE).constant("text/turtle")
.setHeader("Allow").constant("GET,OPTIONS,POST")
.setHeader("Accept-Post").constant("application/x-www-form-urlencoded,text/plain")
.to("language:simple:resource:classpath:options.ttl");

from(ROUTE_PREPARE_LOAD).id("load-prepare")
.choice().when(header("Content-Type").isEqualTo("text/plain"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,26 @@
<property name="loaderService" ref="loaderService" />
</bean>

<camel:camelContext id="apix-loader">
<camel:routeBuilder ref="loaderRoutes" />
</camel:camelContext>

<camelContext id="apix-loader"
xmlns="http://camel.apache.org/schema/blueprint">
<routeBuilder ref="loaderRoutes" />

<!-- Self-register the loader service as an extension -->
<route id="load-extension">
<from uri="timer:register?repeatCount=1" />
<onException>
<exception>java.lang.Exception</exception>
<redeliveryPolicy maximumRedeliveries="10" logRetryAttempted="true" retryAttemptedLogLevel="INFO"/>
</onException>
<setHeader headerName="Content-Type">
<constant>text/plain</constant>
</setHeader>
<setBody>
<simple>http://localhost:{{loader.port}}/load</simple>
</setBody>
<to
uri="jetty:http://localhost:{{loader.port}}/load?okStatusCodeRange=200-399" />
</route>
</camelContext>
</blueprint>
10 changes: 10 additions & 0 deletions fcrepo-api-x-loader/src/main/resources/options.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@prefix apix:<http://fedora.info/definitions/v4/api-extension#> .
@prefix fedora:<http://fedora.info/definitions/v4/repository#> .
@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> .

<> a apix:Extension;
rdfs:label "Extension loader service";
rdfs:comment "A service that automates loading and registration of extensions and services";
apix:exposesService apix:LoaderService;
apix:exposesServiceAt "/apix:load";
apix:bindsTo fedora:RepositoryRoot .

0 comments on commit 94dfc6a

Please sign in to comment.