From d5886d1ec3e79581dfc8b8f8d2beadeb69695e9f Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 18:46:40 -0700 Subject: [PATCH 1/9] added support for SparqlDescribeProcessor --- pom.xml | 28 ++--- .../java/org/fcrepo/camel/FedoraEndpoint.java | 2 +- .../processor/SparqlDescribeProcessor.java | 72 ++++++++++++ .../camel/SparqlDescribeProcessorTest.java | 104 ++++++++++++++++++ 4 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java create mode 100644 src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java diff --git a/pom.xml b/pom.xml index b86cddb..3ba0b37 100644 --- a/pom.xml +++ b/pom.xml @@ -169,6 +169,18 @@ + + + org.apache.jena + jena-arq + ${jena.version} + + + + org.apache.jena + jena-core + ${jena.version} + javax.ws.rs @@ -226,20 +238,6 @@ test - - org.apache.jena - jena-arq - ${jena.version} - test - - - - org.apache.jena - jena-core - ${jena.version} - test - - javax.jcr jcr @@ -275,6 +273,8 @@ **/src/main/java/** **/src/test/java/** + **/examples/fcrepo-camel-solr/src/main/java/** + **/examples/fcrepo-camel-solr-scala/src/main/scala/** target/** diff --git a/src/main/java/org/fcrepo/camel/FedoraEndpoint.java b/src/main/java/org/fcrepo/camel/FedoraEndpoint.java index 8ec3405..19c84a3 100644 --- a/src/main/java/org/fcrepo/camel/FedoraEndpoint.java +++ b/src/main/java/org/fcrepo/camel/FedoraEndpoint.java @@ -28,7 +28,7 @@ */ public class FedoraEndpoint extends DefaultEndpoint { - public static final String FCREPO_BASEURL = "FCREPO_BASEURL"; + public static final String FCREPO_BASE_URL = "FCREPO_BASE_URL"; public static final String FCREPO_IDENTIFIER = "FCREPO_IDENTIFIER"; diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java new file mode 100644 index 0000000..01717c1 --- /dev/null +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java @@ -0,0 +1,72 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.processor; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; + +import org.apache.camel.Processor; +import org.apache.camel.Exchange; +import org.apache.camel.Message; + + +/** + * Represents a Processor class that formulates a Sparql DESCRIBE query + * that is ready to be POSTed to a Sparql endpoint. + * + * The processor expects the following headers: + * org.fcrepo.jms.identifier + * org.fcrepo.jms.baseURL + * each of which can be overridden with the following: + * FCREPO_IDENTIFIER + * FCREPO_BASE_URL + * + * @author Aaron Coburn + * @since November 6, 2014 + */ +public class SparqlDescribeProcessor implements Processor { + /** + * Define how this message should be processed + */ + public void process(final Exchange exchange) throws Exception { + + final Message in = exchange.getIn(); + + String subject = null; + + if (in.getHeader(FCREPO_BASE_URL) != null) { + subject = in.getHeader(FCREPO_BASE_URL, String.class); + } else if (in.getHeader(BASE_URL_HEADER_NAME) != null) { + subject = in.getHeader(BASE_URL_HEADER_NAME, String.class); + } else { + throw new Exception("No baseURL header available!"); + } + + if (in.getHeader(FCREPO_IDENTIFIER) != null) { + subject += in.getHeader(FCREPO_IDENTIFIER); + } else if (in.getHeader(IDENTIFIER_HEADER_NAME) != null) { + subject += in.getHeader(IDENTIFIER_HEADER_NAME); + } + + exchange.getIn().setBody("query=DESCRIBE <" + subject + ">"); + exchange.getIn().setHeader(HTTP_METHOD, "POST"); + exchange.getIn().setHeader(CONTENT_TYPE, "application/x-www-form-urlencoded"); + } +} diff --git a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java new file mode 100644 index 0000000..42e66b7 --- /dev/null +++ b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java @@ -0,0 +1,104 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.integration; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.fcrepo.camel.integration.FedoraTestUtils.getFcrepoEndpointUri; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Produce; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.builder.xml.Namespaces; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.fcrepo.camel.processor.SparqlDescribeProcessor; +import org.junit.Test; +import org.springframework.test.context.ContextConfiguration; + +/** + * Test adding a non-RDF resource + * @author Aaron Coburn + * @since November 7, 2014 + */ +public class SparqlDescribeProcessorTest extends CamelTestSupport { + + @EndpointInject(uri = "mock:result") + protected MockEndpoint resultEndpoint; + + @Produce(uri = "direct:start") + protected ProducerTemplate template; + + @Test + public void testDescribe() throws IOException, InterruptedException { + final String base = "http://localhost/rest"; + final String path = "/path/a/b/c/d"; + + // Assertions + resultEndpoint.expectedBodiesReceived("query=DESCRIBE <" + base + path + ">"); + resultEndpoint.expectedHeaderReceived("Content-Type", "application/x-www-form-urlencoded"); + resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); + + // Test + final Map headers = new HashMap<>(); + headers.put(FCREPO_BASE_URL, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(null, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(null, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(null, headers); + + headers.clear(); + headers.put(FCREPO_BASE_URL, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(null, headers); + + // Confirm that assertions passed + resultEndpoint.expectedMessageCount(4); + resultEndpoint.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws IOException { + + final String fcrepo_uri = getFcrepoEndpointUri(); + + from("direct:start") + .process(new SparqlDescribeProcessor()) + .log("${body}") + .to("mock:result"); + } + }; + } +} From c322bc8c5c57f9506622c884f126007d46f5e0a9 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 18:51:40 -0700 Subject: [PATCH 2/9] remove unnecessary import declarations --- .../org/fcrepo/camel/processor/SparqlDescribeProcessor.java | 1 - src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java index 01717c1..8307dae 100644 --- a/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java @@ -26,7 +26,6 @@ import org.apache.camel.Exchange; import org.apache.camel.Message; - /** * Represents a Processor class that formulates a Sparql DESCRIBE query * that is ready to be POSTed to a Sparql endpoint. diff --git a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java index 42e66b7..e96e4ac 100644 --- a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java +++ b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java @@ -30,12 +30,10 @@ import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.builder.xml.Namespaces; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; import org.fcrepo.camel.processor.SparqlDescribeProcessor; import org.junit.Test; -import org.springframework.test.context.ContextConfiguration; /** * Test adding a non-RDF resource From 1a0201b1d03f08adf5b158ed6f7746fd70044c91 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 23:03:31 -0700 Subject: [PATCH 3/9] added commons-lang3 dependency --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 3ba0b37..982c05b 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ UTF-8 4.0.0-beta-04-SNAPSHOT 2.14.0 + 3.3.2 4.3.5 0.2.3 2.12.1 @@ -147,6 +148,12 @@ ${httpclient.version} + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + org.glassfish.jersey.core jersey-common From 1e75c9b36dee0f30b76d15b148248d5e89e82143 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 23:04:16 -0700 Subject: [PATCH 4/9] minor code cleanup --- .../fcrepo/camel/SparqlDescribeProcessorTest.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java index e96e4ac..b91316e 100644 --- a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java +++ b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java @@ -16,11 +16,11 @@ package org.fcrepo.camel.integration; import static org.apache.camel.Exchange.HTTP_METHOD; -import static org.fcrepo.camel.integration.FedoraTestUtils.getFcrepoEndpointUri; -import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; -import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.apache.camel.Exchange.CONTENT_TYPE; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; import java.io.IOException; import java.util.HashMap; @@ -55,7 +55,7 @@ public void testDescribe() throws IOException, InterruptedException { // Assertions resultEndpoint.expectedBodiesReceived("query=DESCRIBE <" + base + path + ">"); - resultEndpoint.expectedHeaderReceived("Content-Type", "application/x-www-form-urlencoded"); + resultEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/x-www-form-urlencoded"); resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); // Test @@ -89,12 +89,8 @@ protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { @Override public void configure() throws IOException { - - final String fcrepo_uri = getFcrepoEndpointUri(); - from("direct:start") .process(new SparqlDescribeProcessor()) - .log("${body}") .to("mock:result"); } }; From d70e778232c503a0517f447be0067515b609d2c8 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 23:06:09 -0700 Subject: [PATCH 5/9] added support for generating Sparql DELETE WHERE queries --- .../processor/SparqlDeleteProcessor.java | 118 ++++++++++++++++++ .../camel/SparqlDeleteProcessorTest.java | 105 ++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java create mode 100644 src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java new file mode 100644 index 0000000..dfeb6eb --- /dev/null +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java @@ -0,0 +1,118 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.processor; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; +import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel; + +import org.apache.camel.Processor; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.commons.lang3.StringUtils; + +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.Node_URI; +import com.hp.hpl.jena.update.UpdateRequest; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.StmtIterator; + +import java.io.InputStream; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; + + +/** + * Represends a message processor that deletes objects from an + * external triplestore. + * + * @author Aaron Coburn + * @since Nov 8, 2014 + */ +public class SparqlDeleteProcessor implements Processor { + /** + * Define how the message should be processed. + */ + public void process(final Exchange exchange) throws Exception { + + final Message in = exchange.getIn(); + final Model model = createDefaultModel().read(in.getBody(InputStream.class), null, "N-TRIPLE"); + final StmtIterator triples = model.listStatements(); + String subject = null; + + if (in.getHeader(FCREPO_BASE_URL) != null) { + subject = in.getHeader(FCREPO_BASE_URL, String.class); + } else if (in.getHeader(BASE_URL_HEADER_NAME) != null) { + subject = in.getHeader(BASE_URL_HEADER_NAME, String.class); + } else { + throw new Exception("No baseURL header available!"); + } + + if (in.getHeader(FCREPO_IDENTIFIER) != null) { + subject += in.getHeader(FCREPO_IDENTIFIER); + } else if (in.getHeader(IDENTIFIER_HEADER_NAME) != null) { + subject += in.getHeader(IDENTIFIER_HEADER_NAME); + } + + // build list of triples to delete + final Set uris = new HashSet(); + while ( triples.hasNext() ) { + final Triple triple = triples.next().asTriple(); + + // add subject uri, if it is part of this object + if ( triple.getSubject().isURI() ) { + final String uri = ((Node_URI)triple.getSubject()).getURI(); + + if ( matches(subject, uri) ) { + uris.add(uri); + } + } + + // add object uri, if it is part of this object + if ( triple.getObject().isURI() ) { + final String uri = ((Node_URI)triple.getObject()).getURI(); + if ( matches(subject, uri) ) { + uris.add(uri); + } + } + } + + // build update commands + final List del = new ArrayList(); + for (final String uri : uris) { + del.add("DELETE WHERE { <" + uri + "> ?p ?o }"); + } + + exchange.getIn().setBody(StringUtils.join(del, ";\n")); + exchange.getIn().setHeader(HTTP_METHOD, "POST"); + exchange.getIn().setHeader(CONTENT_TYPE, "application/sparql-update"); + } + + private boolean matches( final String resource, final String candidate) { + // All triples that will match this logic are ones that: + // - have a candidate subject or object that equals the target resource of removal, or + // - have a candidate subject or object that is prefixed with the resource of removal + // (therefore catching all children). + return resource.equals(candidate) || candidate.startsWith(resource + "/") + || candidate.startsWith(resource + "#"); + } +} diff --git a/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java new file mode 100644 index 0000000..60229d8 --- /dev/null +++ b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java @@ -0,0 +1,105 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.integration; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Produce; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.fcrepo.camel.processor.SparqlDeleteProcessor; +import org.junit.Test; + +/** + * Test adding a non-RDF resource + * @author Aaron Coburn + * @since November 7, 2014 + */ +public class SparqlDeleteProcessorTest extends CamelTestSupport { + + @EndpointInject(uri = "mock:result") + protected MockEndpoint resultEndpoint; + + @Produce(uri = "direct:start") + protected ProducerTemplate template; + + @Test + public void testDelete() throws IOException, InterruptedException { + final String base = "http://localhost/rest"; + final String path = "/path/book3"; + final String incomingDoc = "_:B7a2aea322baa0335ba565419d128bd9e \"J.K. Rowling\" .\n" + + "_:B7a2aea322baa0335ba565419d128bd9e _:B4b31ccfac030360126a91c43e8ca732b .\n" + + "_:B4b31ccfac030360126a91c43e8ca732b \"Rowling\" .\n" + + "_:B4b31ccfac030360126a91c43e8ca732b \"Joanna\" .\n" + + "<" + base + path + "> \"Harry Potter and the Prisoner Of Azkaban\" .\n" + + "<" + base + path + "> <" + base + path + "/appendix> .\n" + + "<" + base + path + "> _:B7a2aea322baa0335ba565419d128bd9e ."; + + // Assertions + resultEndpoint.expectedBodiesReceived("DELETE WHERE { <" + base + path + "> ?p ?o };\nDELETE WHERE { <" + base + path + "/appendix> ?p ?o }"); + resultEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/sparql-update"); + resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); + + // Test + final Map headers = new HashMap<>(); + headers.put(FCREPO_BASE_URL, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(incomingDoc, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(incomingDoc, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(incomingDoc, headers); + + headers.clear(); + headers.put(FCREPO_BASE_URL, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(incomingDoc, headers); + + // Confirm that assertions passed + resultEndpoint.expectedMessageCount(4); + resultEndpoint.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws IOException { + from("direct:start") + .process(new SparqlDeleteProcessor()) + .to("mock:result"); + } + }; + } +} From 5195c6b2c87876c1011a4e48ae7ba34c3372b2f6 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 23:11:26 -0700 Subject: [PATCH 6/9] checkstyle formatting --- .../processor/SparqlDeleteProcessor.java | 6 ++---- .../camel/SparqlDeleteProcessorTest.java | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java index dfeb6eb..b96fbe8 100644 --- a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java @@ -30,7 +30,6 @@ import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.graph.Node_URI; -import com.hp.hpl.jena.update.UpdateRequest; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.StmtIterator; @@ -40,7 +39,6 @@ import java.util.List; import java.util.ArrayList; - /** * Represends a message processor that deletes objects from an * external triplestore. @@ -101,12 +99,12 @@ public void process(final Exchange exchange) throws Exception { for (final String uri : uris) { del.add("DELETE WHERE { <" + uri + "> ?p ?o }"); } - + exchange.getIn().setBody(StringUtils.join(del, ";\n")); exchange.getIn().setHeader(HTTP_METHOD, "POST"); exchange.getIn().setHeader(CONTENT_TYPE, "application/sparql-update"); } - + private boolean matches( final String resource, final String candidate) { // All triples that will match this logic are ones that: // - have a candidate subject or object that equals the target resource of removal, or diff --git a/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java index 60229d8..220cfb1 100644 --- a/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java +++ b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java @@ -52,16 +52,19 @@ public class SparqlDeleteProcessorTest extends CamelTestSupport { public void testDelete() throws IOException, InterruptedException { final String base = "http://localhost/rest"; final String path = "/path/book3"; - final String incomingDoc = "_:B7a2aea322baa0335ba565419d128bd9e \"J.K. Rowling\" .\n" + - "_:B7a2aea322baa0335ba565419d128bd9e _:B4b31ccfac030360126a91c43e8ca732b .\n" + - "_:B4b31ccfac030360126a91c43e8ca732b \"Rowling\" .\n" + - "_:B4b31ccfac030360126a91c43e8ca732b \"Joanna\" .\n" + - "<" + base + path + "> \"Harry Potter and the Prisoner Of Azkaban\" .\n" + + final String incomingDoc = + "_:B1 \"George Elliot\" .\n" + + "_:B1 _:B2 .\n" + + "_:B2 \"George\" .\n" + + "_:B2 \"Elliot\" .\n" + + "<" + base + path + "> \"Middlemarch\" .\n" + "<" + base + path + "> <" + base + path + "/appendix> .\n" + - "<" + base + path + "> _:B7a2aea322baa0335ba565419d128bd9e ."; - + "<" + base + path + "> _:B1 ."; + // Assertions - resultEndpoint.expectedBodiesReceived("DELETE WHERE { <" + base + path + "> ?p ?o };\nDELETE WHERE { <" + base + path + "/appendix> ?p ?o }"); + resultEndpoint.expectedBodiesReceived( + "DELETE WHERE { <" + base + path + "> ?p ?o };\n" + + "DELETE WHERE { <" + base + path + "/appendix> ?p ?o }"); resultEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/sparql-update"); resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); From 06f072c12b7032fefdd72d52860c8369349c9aa1 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sat, 8 Nov 2014 23:46:12 -0700 Subject: [PATCH 7/9] renamed variables for clarity --- .../camel/processor/SparqlDeleteProcessor.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java index b96fbe8..ef8bc59 100644 --- a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java @@ -28,8 +28,8 @@ import org.apache.camel.Message; import org.apache.commons.lang3.StringUtils; -import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.graph.Node_URI; +import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.StmtIterator; @@ -80,7 +80,7 @@ public void process(final Exchange exchange) throws Exception { if ( triple.getSubject().isURI() ) { final String uri = ((Node_URI)triple.getSubject()).getURI(); - if ( matches(subject, uri) ) { + if (uriMatches(subject, uri) ) { uris.add(uri); } } @@ -88,24 +88,24 @@ public void process(final Exchange exchange) throws Exception { // add object uri, if it is part of this object if ( triple.getObject().isURI() ) { final String uri = ((Node_URI)triple.getObject()).getURI(); - if ( matches(subject, uri) ) { + if (uriMatches(subject, uri) ) { uris.add(uri); } } } - // build update commands - final List del = new ArrayList(); + // build delete commands + final List commands = new ArrayList(); for (final String uri : uris) { - del.add("DELETE WHERE { <" + uri + "> ?p ?o }"); + commands.add("DELETE WHERE { <" + uri + "> ?p ?o }"); } - exchange.getIn().setBody(StringUtils.join(del, ";\n")); + exchange.getIn().setBody(StringUtils.join(commands, ";\n")); exchange.getIn().setHeader(HTTP_METHOD, "POST"); exchange.getIn().setHeader(CONTENT_TYPE, "application/sparql-update"); } - private boolean matches( final String resource, final String candidate) { + private static boolean uriMatches(final String resource, final String candidate) { // All triples that will match this logic are ones that: // - have a candidate subject or object that equals the target resource of removal, or // - have a candidate subject or object that is prefixed with the resource of removal From 721df40162e3c73f3e853009ed9ce90f6267b4d6 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Sun, 9 Nov 2014 18:49:58 -0700 Subject: [PATCH 8/9] added support for INSERT DATA {} processor --- .../processor/SparqlInsertProcessor.java | 60 +++++++++ .../camel/SparqlInsertProcessorTest.java | 119 ++++++++++++++++++ .../camel/integration/FedoraTestUtils.java | 8 ++ 3 files changed, 187 insertions(+) create mode 100644 src/main/java/org/fcrepo/camel/processor/SparqlInsertProcessor.java create mode 100644 src/test/java/org/fcrepo/camel/SparqlInsertProcessorTest.java diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlInsertProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlInsertProcessor.java new file mode 100644 index 0000000..2b41002 --- /dev/null +++ b/src/main/java/org/fcrepo/camel/processor/SparqlInsertProcessor.java @@ -0,0 +1,60 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.processor; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.apache.camel.Exchange.CONTENT_TYPE; +import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel; + +import org.apache.camel.Processor; +import org.apache.camel.Exchange; +import org.apache.camel.Message; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sparql.modify.request.QuadDataAcc; +import com.hp.hpl.jena.sparql.modify.request.UpdateDataInsert; +import com.hp.hpl.jena.update.UpdateRequest; + +import java.io.InputStream; + +/** + * Represents a processor for creating the sparql-update message to + * be passed to an external triplestore. + * + * @author Aaron Coburn + * @since Nov 8, 2014 + */ +public class SparqlInsertProcessor implements Processor { + /** + * Define how the message is processed. + */ + public void process(final Exchange exchange) throws Exception { + + final Message in = exchange.getIn(); + final Model model = createDefaultModel().read(in.getBody(InputStream.class), null, "N-TRIPLE"); + final StmtIterator triples = model.listStatements(); + final QuadDataAcc add = new QuadDataAcc(); + while (triples.hasNext()) { + add.addTriple(triples.nextStatement().asTriple()); + } + final UpdateRequest request = new UpdateRequest(new UpdateDataInsert(add)); + + exchange.getIn().setBody(request.toString()); + exchange.getIn().setHeader(HTTP_METHOD, "POST"); + exchange.getIn().setHeader(CONTENT_TYPE, "application/sparql-update"); + } +} diff --git a/src/test/java/org/fcrepo/camel/SparqlInsertProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlInsertProcessorTest.java new file mode 100644 index 0000000..fbca3cc --- /dev/null +++ b/src/test/java/org/fcrepo/camel/SparqlInsertProcessorTest.java @@ -0,0 +1,119 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.integration; + +import static org.apache.camel.Exchange.HTTP_METHOD; +import static org.apache.commons.lang3.StringUtils.normalizeSpace; +import static org.apache.commons.lang3.StringUtils.join; +import static org.apache.commons.lang3.ArrayUtils.reverse; +import static org.fcrepo.camel.integration.FedoraTestUtils.getFcrepoEndpointUri; +import static org.fcrepo.camel.integration.FedoraTestUtils.getN3Document; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; +import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; +import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; +import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.Produce; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.fcrepo.camel.processor.SparqlInsertProcessor; +import org.junit.Test; + +/** + * Test adding a non-RDF resource + * @author Aaron Coburn + * @since November 7, 2014 + */ +public class SparqlInsertProcessorTest extends CamelTestSupport { + + @EndpointInject(uri = "mock:result") + protected MockEndpoint resultEndpoint; + + @Produce(uri = "direct:start") + protected ProducerTemplate template; + + @Test + public void testDescribe() throws IOException, InterruptedException { + final String base = "http://localhost/rest"; + final String path = "/path/a/b/c/d"; + final String document = getN3Document(); + + // Reverse the lines as the RDF is serialized in opposite order + final String[] lines = document.split("\n"); + reverse(lines); + + // Assertions + resultEndpoint.expectedBodiesReceived("INSERT DATA { " + join(lines, " ") + " }"); + resultEndpoint.expectedHeaderReceived("Content-Type", "application/sparql-update"); + resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); + + // Test + final Map headers = new HashMap<>(); + headers.put(FCREPO_BASE_URL, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(document, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(document, headers); + + headers.clear(); + headers.put(BASE_URL_HEADER_NAME, base); + headers.put(FCREPO_IDENTIFIER, path); + template.sendBodyAndHeaders(document, headers); + + headers.clear(); + headers.put(FCREPO_BASE_URL, base); + headers.put(IDENTIFIER_HEADER_NAME, path); + template.sendBodyAndHeaders(document, headers); + + // Confirm that assertions passed + resultEndpoint.expectedMessageCount(4); + resultEndpoint.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws IOException { + + final String fcrepo_uri = getFcrepoEndpointUri(); + + from("direct:start") + .process(new SparqlInsertProcessor()) + // Normalize the whitespace to make it easier to compare + .process(new Processor() { + public void process(final Exchange exchange) throws Exception { + final String payload = exchange.getIn().getBody(String.class); + exchange.getIn().setBody(normalizeSpace(payload)); + } + }) + .to("mock:result"); + } + }; + } +} diff --git a/src/test/java/org/fcrepo/camel/integration/FedoraTestUtils.java b/src/test/java/org/fcrepo/camel/integration/FedoraTestUtils.java index a5f6054..e930f95 100644 --- a/src/test/java/org/fcrepo/camel/integration/FedoraTestUtils.java +++ b/src/test/java/org/fcrepo/camel/integration/FedoraTestUtils.java @@ -64,6 +64,14 @@ public static String getTurtleDocument() { "<> dc:title \"some title\" ."; } + /** + * Retrieve an N3 document + */ + public static String getN3Document() { + return " \"Author\" .\n" + + " \"Title\" ."; + } + /** * Retrieve a simple text document */ From a1593858c50343c259355e446070c126ad59a493 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Tue, 11 Nov 2014 21:38:52 -0700 Subject: [PATCH 9/9] added integration tests for triplestore processors --- .../processor/SparqlDeleteProcessor.java | 2 +- .../processor/SparqlDescribeProcessor.java | 2 + .../camel/SparqlDeleteProcessorTest.java | 24 +++- .../camel/SparqlDescribeProcessorTest.java | 2 + .../camel/integration/FedoraSparqlIT.java | 124 ++++++++++++++++++ 5 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 src/test/java/org/fcrepo/camel/integration/FedoraSparqlIT.java diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java index ef8bc59..3cdef86 100644 --- a/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDeleteProcessor.java @@ -53,7 +53,7 @@ public class SparqlDeleteProcessor implements Processor { public void process(final Exchange exchange) throws Exception { final Message in = exchange.getIn(); - final Model model = createDefaultModel().read(in.getBody(InputStream.class), null, "N-TRIPLE"); + final Model model = createDefaultModel().read(in.getBody(InputStream.class), null); final StmtIterator triples = model.listStatements(); String subject = null; diff --git a/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java index 8307dae..d034206 100644 --- a/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java +++ b/src/main/java/org/fcrepo/camel/processor/SparqlDescribeProcessor.java @@ -17,6 +17,7 @@ import static org.apache.camel.Exchange.HTTP_METHOD; import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.apache.camel.Exchange.ACCEPT_CONTENT_TYPE; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME; @@ -66,6 +67,7 @@ public void process(final Exchange exchange) throws Exception { exchange.getIn().setBody("query=DESCRIBE <" + subject + ">"); exchange.getIn().setHeader(HTTP_METHOD, "POST"); + exchange.getIn().setHeader(ACCEPT_CONTENT_TYPE, "application/rdf+xml"); exchange.getIn().setHeader(CONTENT_TYPE, "application/x-www-form-urlencoded"); } } diff --git a/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java index 220cfb1..b210816 100644 --- a/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java +++ b/src/test/java/org/fcrepo/camel/SparqlDeleteProcessorTest.java @@ -53,13 +53,23 @@ public void testDelete() throws IOException, InterruptedException { final String base = "http://localhost/rest"; final String path = "/path/book3"; final String incomingDoc = - "_:B1 \"George Elliot\" .\n" + - "_:B1 _:B2 .\n" + - "_:B2 \"George\" .\n" + - "_:B2 \"Elliot\" .\n" + - "<" + base + path + "> \"Middlemarch\" .\n" + - "<" + base + path + "> <" + base + path + "/appendix> .\n" + - "<" + base + path + "> _:B1 ."; + "" + + " " + + " Middlemarch" + + " " + + " " + + " George Elliot" + + " " + + " Elliot" + + " George" + + " " + + " " + + " " + + ""; // Assertions resultEndpoint.expectedBodiesReceived( diff --git a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java index b91316e..ab19ed6 100644 --- a/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java +++ b/src/test/java/org/fcrepo/camel/SparqlDescribeProcessorTest.java @@ -17,6 +17,7 @@ import static org.apache.camel.Exchange.HTTP_METHOD; import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.apache.camel.Exchange.ACCEPT_CONTENT_TYPE; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_IDENTIFIER; import static org.fcrepo.camel.FedoraEndpoint.FCREPO_BASE_URL; import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME; @@ -57,6 +58,7 @@ public void testDescribe() throws IOException, InterruptedException { resultEndpoint.expectedBodiesReceived("query=DESCRIBE <" + base + path + ">"); resultEndpoint.expectedHeaderReceived(CONTENT_TYPE, "application/x-www-form-urlencoded"); resultEndpoint.expectedHeaderReceived(HTTP_METHOD, "POST"); + resultEndpoint.expectedHeaderReceived(ACCEPT_CONTENT_TYPE, "application/rdf+xml"); // Test final Map headers = new HashMap<>(); diff --git a/src/test/java/org/fcrepo/camel/integration/FedoraSparqlIT.java b/src/test/java/org/fcrepo/camel/integration/FedoraSparqlIT.java new file mode 100644 index 0000000..86ab1d8 --- /dev/null +++ b/src/test/java/org/fcrepo/camel/integration/FedoraSparqlIT.java @@ -0,0 +1,124 @@ +/** + * Copyright 2014 DuraSpace, Inc. + * + * 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 org.fcrepo.camel.integration; + +import static org.apache.camel.Exchange.CONTENT_TYPE; +import static org.apache.camel.Exchange.HTTP_METHOD; +import static java.lang.System.getProperty; + +import java.util.Map; +import java.util.HashMap; +import java.io.IOException; + +import org.fcrepo.camel.processor.SparqlInsertProcessor; +import org.fcrepo.camel.processor.SparqlDescribeProcessor; +import org.fcrepo.camel.processor.SparqlDeleteProcessor; + +import org.apache.camel.Produce; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.EndpointInject; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.builder.xml.XPathBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.runner.RunWith; +import org.junit.Test; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Represents an integration test for interacting with an external triplestore. + * + * @author Aaron Coburn + * @since Nov 8, 2014 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/spring-test/test-container.xml"}) +public class FedoraSparqlIT extends CamelTestSupport { + + @EndpointInject(uri = "mock:result") + protected MockEndpoint resultEndpoint; + + @Produce(uri = "direct:start") + protected ProducerTemplate template; + + @Test + public void testSparql() throws Exception { + // Assertions + resultEndpoint.expectedMessageCount(1); + + // Setup + final Map headers = new HashMap(); + headers.put(HTTP_METHOD, "POST"); + headers.put(CONTENT_TYPE, "text/turtle"); + + final String fullPath = template.requestBodyAndHeaders( + "direct:setup", FedoraTestUtils.getTurtleDocument(), headers, String.class); + + final String identifier = fullPath.replaceAll(FedoraTestUtils.getFcrepoBaseUrl(), ""); + + // Test + final Map testHeaders = new HashMap(); + testHeaders.put("FCREPO_IDENTIFIER", identifier); + testHeaders.put("org.fcrepo.jms.baseURL", "http://localhost:8080/fcrepo4/rest"); + template.sendBodyAndHeaders(null, testHeaders); + + // Teardown + final Map teardownHeaders = new HashMap(); + teardownHeaders.put(Exchange.HTTP_METHOD, "DELETE"); + teardownHeaders.put("FCREPO_IDENTIFIER", identifier); + template.sendBodyAndHeaders("direct:teardown", null, teardownHeaders); + + // Confirm that the assertions passed + resultEndpoint.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws IOException { + + final String fcrepo_uri = FedoraTestUtils.getFcrepoEndpointUri(); + final String fuseki_url = "localhost:" + getProperty("test.fuseki.port", "3030"); + final Processor sparqlInsert = new SparqlInsertProcessor(); + final XPathBuilder titleXpath = new XPathBuilder("/rdf:RDF/rdf:Description/dc:title/text()"); + titleXpath.namespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + titleXpath.namespace("dc", "http://purl.org/dc/elements/1.1/"); + + from("direct:setup") + .to(fcrepo_uri); + + from("direct:start") + .process(new SparqlDescribeProcessor()) + .to("http4:" + fuseki_url + "/test/query") + //.log("${body}") + .process(new SparqlDeleteProcessor()) + .to("http4:" + fuseki_url + "/test/update") + .setHeader(Exchange.HTTP_METHOD).constant("GET") + .to(fcrepo_uri + "?accept=application/n-triples") + .process(new SparqlInsertProcessor()) + .to("http4:" + fuseki_url + "/test/update") + .to("mock:result"); + + from("direct:teardown") + .to(fcrepo_uri) + .to(fcrepo_uri + "?tombstone=true"); + } + }; + } +}