Commit ffd50b4a authored by Aaron Coburn's avatar Aaron Coburn
Browse files

remove dependency on fcrepo-camel

parent 5affc003
......@@ -4,9 +4,6 @@ description = 'Message Broadcaster'
dependencies {
compile group: 'org.apache.camel', name: 'camel-core', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-blueprint', version: camelVersion
compile(group: 'org.fcrepo.camel', name: 'fcrepo-camel', version: fcrepoCamelVersion) {
exclude(module: 'slf4j-log4j12')
}
testCompile group: 'org.apache.camel', name: 'camel-test-blueprint', version: camelVersion
testCompile group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion
}
......
......@@ -7,9 +7,8 @@ dependencies {
compile group: 'org.apache.camel', name: 'camel-sql', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-jetty9', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-blueprint', version: camelVersion
compile(group: 'org.fcrepo.camel', name: 'fcrepo-camel', version: fcrepoCamelVersion) {
exclude(module: 'slf4j-log4j12')
}
compile group: 'org.apache.camel', name: 'camel-jackson', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-http4', version: camelVersion
compile group: 'org.codehaus.woodstox', name: 'woodstox-core-asl', version: woodstoxVersion
testCompile project(':acrepo-services-mint')
......
/*
* Copyright 2016 Amherst College
*
* 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.connector.idiomatic;
import static java.util.Collections.singletonList;
import static java.util.Objects.nonNull;
import static java.util.stream.Collectors.toList;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
/**
* Converts a Fedora Message into camel-based headers.
*
* @author acoburn
*/
public class EventProcessor implements Processor {
private static final String FCREPO_AGENT = "CamelFcrepoAgent";
private static final String FCREPO_DATE_TIME = "CamelFcrepoDateTime";
private static final String FCREPO_EVENT_ID = "CamelFcrepoEventId";
private static final String FCREPO_EVENT_TYPE = "CamelFcrepoEventType";
private static final String FCREPO_RESOURCE_TYPE = "CamelFcrepoResourceType";
private static final String FCREPO_URI = "CamelFcrepoUri";
private static final Set<String> singleValuedFields = new HashSet<>();
static {
singleValuedFields.add(FCREPO_URI);
singleValuedFields.add(FCREPO_DATE_TIME);
singleValuedFields.add(FCREPO_EVENT_ID);
}
/**
* Process the Fedora message
*
* @param exchange the current camel message exchange
*/
public void process(final Exchange exchange) throws IOException {
final Map<String, List<String>> data = new HashMap<>();
data.putAll(getValuesFromMap(exchange.getIn().getBody(Map.class)));
data.entrySet().stream().filter(entry -> nonNull(entry.getValue())).filter(entry -> !entry.getValue().isEmpty())
.forEach(entry -> exchange.getIn().setHeader(entry.getKey(), getValue(entry)));
}
private static Object getValue(final Map.Entry<String, List<String>> entry) {
if (singleValuedFields.contains(entry.getKey())) {
return entry.getValue().get(0);
}
return entry.getValue();
}
@SuppressWarnings("unchecked")
private static Map<String, List<String>> getValuesFromMap(final Map body) {
final Map<String, Object> values = (Map<String, Object>)body;
final Map<String, List<String>> data = new HashMap<>();
if (values.containsKey("@id")) {
data.put(FCREPO_URI, singletonList((String)values.get("@id")));
}
if (values.containsKey("id")) {
data.putIfAbsent(FCREPO_URI, singletonList((String)values.get("id")));
}
if (values.containsKey("@type")) {
data.put(FCREPO_RESOURCE_TYPE, (List<String>)values.get("@type"));
}
if (values.containsKey("type")) {
data.putIfAbsent(FCREPO_RESOURCE_TYPE, (List<String>)values.get("type"));
}
final Map<String, Object> wasGeneratedBy = (Map<String, Object>)values.get("wasGeneratedBy");
if (wasGeneratedBy != null) {
if (wasGeneratedBy.containsKey("type")) {
data.put(FCREPO_EVENT_TYPE, (List<String>)wasGeneratedBy.get("type"));
}
data.put(FCREPO_EVENT_ID, singletonList((String)wasGeneratedBy.get("identifier")));
data.put(FCREPO_DATE_TIME, singletonList((String)wasGeneratedBy.get("atTime")));
}
final List<Map<String, String>> wasAttributedTo = (List<Map<String, String>>)values.get("wasAttributedTo");
if (wasAttributedTo != null) {
data.put(FCREPO_AGENT,
wasAttributedTo.stream().map(agent -> agent.get("name")).collect(toList()));
}
return data;
}
}
......@@ -18,15 +18,15 @@ package edu.amherst.acdc.connector.idiomatic;
import static edu.amherst.acdc.connector.idiomatic.IdiomaticHeaders.FEDORA;
import static edu.amherst.acdc.connector.idiomatic.IdiomaticHeaders.ID;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
import static org.apache.camel.Exchange.HTTP_URI;
import static org.apache.camel.builder.PredicateBuilder.not;
import static org.apache.camel.model.dataformat.JsonLibrary.Jackson;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
import java.util.List;
import java.util.Map;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.fcrepo.camel.processor.EventProcessor;
/**
* A message router for handling ID mappings.
......@@ -35,6 +35,8 @@ import org.fcrepo.camel.processor.EventProcessor;
*/
public class IdRouter extends RouteBuilder {
private static final String FCREPO_URI = "CamelFcrepoUri";
/**
* Configure the message route workflow.
*/
......@@ -51,9 +53,17 @@ public class IdRouter extends RouteBuilder {
* Process a message via JMS
*/
from("{{input.stream}}").routeId("IdMappingRouter")
.unmarshal().json(Jackson, Map.class)
.process(new EventProcessor())
.log(LoggingLevel.INFO, "IdMapping Event: ${headers[CamelFcrepoUri]}")
.to("fcrepo:{{fcrepo.baseUrl}}?preferOmit=PreferContainment&accept=application/ld+json")
.to("direct:fetch");
from("direct:fetch").routeId("IdFetchResource")
.removeHeaders("CamelHttp*")
.setHeader(HTTP_URI).simple("${headers.CamelFcrepoUri}")
.setHeader("Prefer").constant("return=representation; omit=\"http://www.w3.org/ns/ldp#PreferContainment\"")
.setHeader("Accept").constant("application/ld+json")
.to("http4:localhost?username={{fcrepo.authUsername}}&password={{fcrepo.authPassword}}")
.unmarshal().json(Jackson, List.class)
.split(simple("${body}"))
.filter(simple("${body[@id]} == ${header.CamelFcrepoUri}"))
......
......@@ -17,6 +17,8 @@
<cm:property name="rest.port" value="9101"/>
<cm:property name="id.property" value="http://purl.org/dc/elements/1.1/identifier"/>
<cm:property name="fcrepo.baseUrl" value="http://localhost:8080/fcrepo/rest"/>
<cm:property name="fcrepo.authUsername" value=""/>
<cm:property name="fcrepo.authPassword" value=""/>
</cm:default-properties>
</cm:property-placeholder>
......
......@@ -15,7 +15,7 @@
*/
package edu.amherst.acdc.connector.idiomatic;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
import static org.apache.camel.util.ObjectHelper.loadResourceAsStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
......@@ -36,9 +36,8 @@ import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.component.seda.SedaComponent;
import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
import org.apache.camel.util.KeyValueHolder;
import org.apache.camel.util.ObjectHelper;
import org.apache.derby.jdbc.EmbeddedDataSource;
import org.apache.commons.io.IOUtils;
import org.apache.derby.jdbc.EmbeddedDataSource;
import org.junit.Test;
/**
......@@ -110,8 +109,8 @@ public class RouteTest extends CamelBlueprintTestSupport {
getMockEndpoint("mock:result").expectedMessageCount(2);
template.sendBody("direct:minter", null);
template.sendBody("direct:minter", null);
template.sendBody("direct:minter", "{}");
template.sendBody("direct:minter", "{}");
final String id1 = resultEndpoint.getExchanges().get(0).getIn().getBody(String.class);
final String id2 = resultEndpoint.getExchanges().get(1).getIn().getBody(String.class);
......@@ -125,11 +124,11 @@ public class RouteTest extends CamelBlueprintTestSupport {
@Test
public void testEvent() throws Exception {
context.getRouteDefinition("IdMappingRouter").adviceWith(context, new AdviceWithRouteBuilder() {
context.getRouteDefinition("IdFetchResource").adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
replaceFromWith("direct:start");
mockEndpointsAndSkip("fcrepo*");
mockEndpointsAndSkip("http*");
mockEndpoints("direct:update");
}
});
......@@ -149,9 +148,8 @@ public class RouteTest extends CamelBlueprintTestSupport {
"http://localhost/foo/bar", "http://localhost/foo/bar");
getMockEndpoint("mock:direct:update").expectedHeaderValuesReceivedInAnyOrder(IdiomaticHeaders.ID,
"http://example.org/object/1", "http://example.org/object/2");
template.sendBodyAndHeader(
IOUtils.toString(ObjectHelper.loadResourceAsStream("indexable.json"),
"UTF-8"), FCREPO_URI, "http://localhost/foo/bar");
template.sendBodyAndHeader(IOUtils.toString(loadResourceAsStream("indexable.json"), "UTF-8"),
"CamelFcrepoUri", "http://localhost/foo/bar");
assertMockEndpointsSatisfied();
}
......
......@@ -5,9 +5,7 @@ dependencies {
compile group: 'org.apache.camel', name: 'camel-core', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-http4', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-blueprint', version: camelVersion
compile(group: 'org.fcrepo.camel', name: 'fcrepo-camel', version: fcrepoCamelVersion) {
exclude(module: 'slf4j-log4j12')
}
compile group: 'org.apache.jena', name: 'jena-osgi', version: jenaVersion
}
jar {
......@@ -17,7 +15,7 @@ jar {
vendor project.vendor
license project.license
instruction 'Import-Package', "org.apache.camel,org.fcrepo.camel,org.apache.camel.component.http4,${defaultOsgiImports}"
instruction 'Import-Package', "org.apache.camel,${defaultOsgiImports}"
instruction 'Export-Package', "edu.amherst.acdc.connector.triplestore;version=${projectOsgiVersion}"
}
}
......
......@@ -5,8 +5,7 @@ input.stream=broker:queue:fedora
error.maxRedeliveries=10
# Control prefer headers
prefer.omit=http://www.w3.org/ns/ldp#PreferContainment
prefer.include=
prefer.header=return=representation; omit="http://www.w3.org/ns/ldp#PreferContainment"; include=""
# The Camel URI for handling reindexing events
triplestore.reindex.stream=broker:queue:triplestore.reindex
......
/*
* Copyright 2016 Amherst College
*
* 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.connector.triplestore;
import static java.util.Collections.singletonList;
import static java.util.Objects.nonNull;
import static java.util.stream.Collectors.toList;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
/**
* Converts a Fedora Message into camel-based headers.
*
* @author acoburn
*/
public class EventProcessor implements Processor {
private static final String FCREPO_AGENT = "CamelFcrepoAgent";
private static final String FCREPO_DATE_TIME = "CamelFcrepoDateTime";
private static final String FCREPO_EVENT_ID = "CamelFcrepoEventId";
private static final String FCREPO_EVENT_TYPE = "CamelFcrepoEventType";
private static final String FCREPO_RESOURCE_TYPE = "CamelFcrepoResourceType";
private static final String FCREPO_URI = "CamelFcrepoUri";
private static final Set<String> singleValuedFields = new HashSet<>();
static {
singleValuedFields.add(FCREPO_URI);
singleValuedFields.add(FCREPO_DATE_TIME);
singleValuedFields.add(FCREPO_EVENT_ID);
}
/**
* Process the Fedora message
*
* @param exchange the current camel message exchange
*/
public void process(final Exchange exchange) throws IOException {
final Map<String, List<String>> data = new HashMap<>();
data.putAll(getValuesFromMap(exchange.getIn().getBody(Map.class)));
data.entrySet().stream().filter(entry -> nonNull(entry.getValue())).filter(entry -> !entry.getValue().isEmpty())
.forEach(entry -> exchange.getIn().setHeader(entry.getKey(), getValue(entry)));
}
private static Object getValue(final Map.Entry<String, List<String>> entry) {
if (singleValuedFields.contains(entry.getKey())) {
return entry.getValue().get(0);
}
return entry.getValue();
}
@SuppressWarnings("unchecked")
private static Map<String, List<String>> getValuesFromMap(final Map body) {
final Map<String, Object> values = (Map<String, Object>)body;
final Map<String, List<String>> data = new HashMap<>();
if (values.containsKey("@id")) {
data.put(FCREPO_URI, singletonList((String)values.get("@id")));
}
if (values.containsKey("id")) {
data.putIfAbsent(FCREPO_URI, singletonList((String)values.get("id")));
}
if (values.containsKey("@type")) {
data.put(FCREPO_RESOURCE_TYPE, (List<String>)values.get("@type"));
}
if (values.containsKey("type")) {
data.putIfAbsent(FCREPO_RESOURCE_TYPE, (List<String>)values.get("type"));
}
final Map<String, Object> wasGeneratedBy = (Map<String, Object>)values.get("wasGeneratedBy");
if (wasGeneratedBy != null) {
if (wasGeneratedBy.containsKey("type")) {
data.put(FCREPO_EVENT_TYPE, (List<String>)wasGeneratedBy.get("type"));
}
data.put(FCREPO_EVENT_ID, singletonList((String)wasGeneratedBy.get("identifier")));
data.put(FCREPO_DATE_TIME, singletonList((String)wasGeneratedBy.get("atTime")));
}
final List<Map<String, String>> wasAttributedTo = (List<Map<String, String>>)values.get("wasAttributedTo");
if (wasAttributedTo != null) {
data.put(FCREPO_AGENT,
wasAttributedTo.stream().map(agent -> agent.get("name")).collect(toList()));
}
return data;
}
}
......@@ -16,28 +16,28 @@
package edu.amherst.acdc.connector.triplestore;
import static java.net.URLEncoder.encode;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static org.apache.camel.Exchange.CONTENT_TYPE;
import static org.apache.camel.Exchange.HTTP_METHOD;
import static org.apache.camel.Exchange.HTTP_URI;
import static org.apache.camel.builder.PredicateBuilder.in;
import static org.apache.camel.builder.PredicateBuilder.not;
import static org.apache.camel.builder.PredicateBuilder.or;
import static org.apache.camel.util.ExchangeHelper.getMandatoryHeader;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_NAMED_GRAPH;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
import static org.fcrepo.camel.processor.ProcessorUtils.tokenizePropertyPlaceholder;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.List;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.NoSuchHeaderException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.jena.util.URIref;
import org.fcrepo.camel.processor.EventProcessor;
import org.slf4j.Logger;
/**
......@@ -51,6 +51,9 @@ public class TriplestoreRouter extends RouteBuilder {
private static final String RESOURCE_DELETION = "http://fedora.info/definitions/v4/event#ResourceDeletion";
private static final String DELETE = "https://www.w3.org/ns/activitystreams#Delete";
private static final String FCREPO_EVENT_TYPE = "CamelFcrepoEventType";
private static final String FCREPO_NAMED_GRAPH = "CamelFcrepoNamedGraph";
private static final String FCREPO_URI = "CamelFcrepoUri";
/**
* Configure the message route workflow.
......@@ -107,15 +110,20 @@ public class TriplestoreRouter extends RouteBuilder {
header(FCREPO_URI).isEqualTo(constant(uri))))
.collect(toList()))))
.removeHeaders("CamelHttp*")
.to("fcrepo:{{fcrepo.baseUrl}}?accept=application/n-triples" +
"&preferOmit={{prefer.omit}}&preferInclude={{prefer.include}}")
.setHeader(HTTP_URI).header(FCREPO_URI)
.setHeader("Accept").constant("application/n-triples")
.setHeader("Prefer").simple("{{prefer.header}}")
.to("http4://localhost?username={{fcrepo.authUsername}}&password={{fcrepo.authPassword}}"
+ "&useSystemProperties=true")
.log(LoggingLevel.INFO, LOGGER, "Indexing Triplestore Object ${headers[CamelFcrepoUri]}")
.removeHeaders("CamelHttp*")
.setHeader(HTTP_METHOD).constant("POST")
.setHeader(CONTENT_TYPE).constant("application/x-www-form-urlencoded; charset=utf-8")
.setHeader(HTTP_URI).simple("{{triplestore.baseUrl}}")
.process(e -> e.getIn().setBody(sparqlUpdate(deleteAll(graph(e)) +
"INSERT DATA { GRAPH <" + graph(e) + "> {" +
e.getIn().getBody(String.class) + "} };")))
.to("{{triplestore.baseUrl}}?useSystemProperties=true");
.to("http4:localhost?useSystemProperties=true");
}
private static String deleteAll(final String graphName) {
......@@ -133,4 +141,15 @@ public class TriplestoreRouter extends RouteBuilder {
throw new UncheckedIOException(ex);
}
}
private static List<String> tokenizePropertyPlaceholder(final CamelContext context, final String property,
final String token) {
try {
return stream(context.resolvePropertyPlaceholders(property).split(token)).map(String::trim)
.filter(val -> !val.isEmpty()).collect(toList());
} catch (final Exception ex) {
LOGGER.debug("No property value found for {}", property);
return emptyList();
}
}
}
......@@ -12,8 +12,7 @@
<cm:default-properties>
<cm:property name="input.stream" value="broker:queue:fedora" />
<cm:property name="error.maxRedeliveries" value="10" />
<cm:property name="prefer.omit" value="http://www.w3.org/ns/ldp#PreferContainment" />
<cm:property name="prefer.include" value="" />
<cm:property name="prefer.header" value="return=representation;omit=&quot;http://www.w3.org/ns/ldp#PreferContainment&quot;;include=&quot;&quot;" />
<cm:property name="triplestore.reindex.stream" value="broker:queue:triplestore.reindex" />
<cm:property name="triplestore.baseUrl" value="http://localhost:8080/fuseki/test/update" />
<cm:property name="filter.containers" value="" />
......@@ -25,16 +24,6 @@
<reference id="broker" interface="org.apache.camel.Component" filter="(osgi.jndi.service.name=fcrepo/Broker)"/>
<bean id="http" class="org.apache.camel.component.http4.HttpComponent"/>
<bean id="https" class="org.apache.camel.component.http4.HttpComponent"/>
<!-- configuration of fcrepo component -->
<bean id="fcrepo" class="org.fcrepo.camel.FcrepoComponent">
<property name="authUsername" value="${fcrepo.authUsername}"/>
<property name="authPassword" value="${fcrepo.authPassword}"/>
<property name="baseUrl" value="${fcrepo.baseUrl}"/>
</bean>
<camelContext id="AcrepoConnectorTriplestore" xmlns="http://camel.apache.org/schema/blueprint">
<package>edu.amherst.acdc.connector.triplestore</package>
</camelContext>
......
......@@ -5,9 +5,6 @@ dependencies {
compile group: 'org.apache.camel', name: 'camel-core', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-blueprint', version: camelVersion
compile group: 'org.apache.camel', name: 'camel-jetty9', version: camelVersion
compile(group: 'org.fcrepo.camel', name: 'fcrepo-camel', version: fcrepoCamelVersion) {
exclude(module: 'slf4j-log4j12')
}
compile group: 'org.apache.jena', name: 'jena-osgi', version: jenaVersion
compile project(':acrepo-services-entailment')
}
......@@ -19,7 +16,7 @@ jar {
vendor project.vendor
license project.license
instruction 'Import-Package', "org.apache.camel,org.fcrepo.camel,edu.amherst.acdc.services.entailment,${defaultOsgiImports}"
instruction 'Import-Package', "org.apache.camel,edu.amherst.acdc.services.entailment,${defaultOsgiImports}"
instruction 'Export-Package', "edu.amherst.acdc.exts.entailment;version=${projectOsgiVersion}"
}
}
......
......@@ -9,8 +9,7 @@ fcrepo.authUsername=
fcrepo.authPassword=
# Control repository prefer headers
prefer.omit=http://www.w3.org/ns/ldp#PreferContainment
prefer.include=
prefer.header=return=representation; omit="http://www.w3.org/ns/ldp#PreferContainment"
# API-X configuration
extension.load=false
......
......@@ -19,8 +19,7 @@ import static java.util.Optional.ofNullable;
import static org.apache.camel.Exchange.CONTENT_TYPE;
import static org.apache.camel.Exchange.HTTP_METHOD;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
import static org.apache.camel.Exchange.HTTP_URI;
import java.util.Optional;
......@@ -38,6 +37,8 @@ public class EntailmentRouter extends RouteBuilder {
private final static String DEFAULT_CONTENT_TYPE = "text/turtle";
private final static String HTTP_QUERY_CONTEXT = "context";
private final static String ENTAILMENT_ACCEPT = "CamelEntailmentAccept";
private final static String FCREPO_URI = "CamelFcrepoUri";
private final static String FCREPO_BASE_URL = "CamelFcrepoBaseUrl";
/**
* Configure the message route workflow.
......@@ -69,9 +70,12 @@ public class EntailmentRouter extends RouteBuilder {
from("direct:get").routeId("EntailementGetTriples")
.log("Building RDFS Entailment Info")
.setHeader("Accept").constant(DEFAULT_CONTENT_TYPE)
.to("fcrepo:{{fcrepo.baseUrl}}?throwExceptionOnFailure=false" +
"&preferOmit={{prefer.omit}}&preferInclude={{prefer.include}}")
.removeHeaders("CamelHttp*")