package ats.emvo.routing;
public class routingpath {
public String RoutingPathToXml() {
String requestLogPath ="file:///d:/in"; //(String) AtsBundleActivator.atsEmvoRoutingProperties.get("requestlogpath");
return requestLogPath;
}
}
i want to get this return string to bean in jboss fuse as route path
up to now i called it like below in camel cxml,but i dont get the return value here.
<?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" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<camelContext id="cbr-example-context" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="bean:routingInInterceptor"/>
<to id="_to2" uri="file:///d:/out"/>
</route>
</camelContext>
<bean class="ats.emvo.routing.routingpath" id="routingInInterceptor"/>
</blueprint>
I will propose another approaches if you want to follow.
According to Camel, "the bean: component binds beans to Camel message exchanges". So if you after a bean call print the Exchange message body you will see the contents coming form bean.
...
<uri="bean:routingInInterceptor"/>
<log message=Contents of bean: ${body}/> <!-- "file:///d:/in" -->
...
So information is put in Exchange.
In your case, you want to start your route "from" not from a hard-coded endpoint URI.
Approach 1
For that reason you can use property placeholders in endpoint URIs. So after you set up properties place holders you can have something like
<?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" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
<!-- add file your-configuration-file.cfg with your properties under etc/ -->
<cm:property-placeholder persistent-id="your-configuration-file">
<cm:default-properties>
<cm:property name="your.property" value="file:///d:/in"/>
</cm:default-properties>
</cm:property-placeholder>
<camelContext id="cbr-example-context" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="{{your.property}}"/>
<to id="_to2" uri="file:///d:/out"/>
</route>
</camelContext>
<!-- Actually bean is not needed since you will get the endpoint from properties file -->
<bean class="ats.emvo.routing.routingpath" id="routingInInterceptor"/>
</blueprint>
More details about properties component http://camel.apache.org/properties.html.
Approach 2
Another aproach is to have dynamics endpoints with toD tag, to evaluate the endpoints on runtime. So, you can have something like
<route id="_route1">
<from id="_from1" uri="${header.dynamicUri}}"/>
<to id="_to2" uri="file:///d:/out"/>
</route>
More deatils about are in http://camel.apache.org/message-endpoint.html at section Dynamic To.
Related
I want to handle errors depending on the http code response.
I would also like to know how to enable *throwExceptionOnFailure* on my route. For example, if the response code is 500x, send the message to the queue "redmine_errors"
UPDATE 4:
my blueprint after add exception from answer #fg78nc (don't work)
<?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"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
">
<bean id="tfsToRedmineMapper"
class="com.stackabuse.example.TfsToRedmineMapper" />
<bean id="myBean" class="com.stackabuse.example.MyBean" />
<camelContext
xmlns="http://camel.apache.org/schema/blueprint">
<onException>
<exception>org.apache.camel.http.common.HttpOperationFailedException
</exception>
<onWhen>
<method ref="myBean" method="parseException" />
</onWhen>
<handled>
<constant>true</constant>
</handled>
<to uri="log:redmine_errors" />
</onException>
<route>
<from uri="jetty:http://0.0.0.0:8082/test" />
<inOnly uri="activemq://from_tfs" />
</route>
<route>
<from uri="activemq://from_tfs" />
<process ref="tfsToRedmineMapper" />
<to uri="activemq://for_redmine" />
</route>
<route>
<from uri="activemq://for_redmine" />
<setHeader headerName="Content-Type">
<constant>application/json; charset=utf-8</constant>
</setHeader>
<setHeader headerName="X-Redmine-API-Key">
<constant>my_redmine_api_token</constant>
</setHeader>
<toD uri="${header.url}" />
</route>
ERROR:
2019-02-15 09:35:12,103 | ERROR | mix-7.0.1/deploy | BlueprintCamelContext | 40 - org.apache.camel.camel-blueprint - 2.16.5 | Error occurred during starting Camel: CamelContext(camel-32) due Failed to create route route48 at: >>> OnException[null When[bean{} -> []] -> [To[activemq://redmine_errors]]] <<< in route: Route(route48)[[From[jetty:http://0.0.0.0:8082/test]] -> [On... because of org.apache.camel.http.common.HttpOperationFailedException
org.apache.camel.FailedToCreateRouteException: Failed to create route route48 at: >>> OnException[null When[bean{} -> []] -> [To[activemq://redmine_errors]]] <<< in route: Route(route48)[[From[jetty:http://0.0.0.0:8082/test]] -> [On... because of org.apache.camel.http.common.HttpOperationFailedException
enter image description here
enter image description here
Unfortunately, Camel does not set correctly Http status code.
Solution below is a little bit convoluted, but it works.
It can also be solved within XML with the simple language predicate, but somehow it did not work for me, so I used Java for predicate.
Blueprint :
<bean id="myBean" class="com.example.MyBean" />
<onException>
<exception>org.apache.camel.http.common.HttpOperationFailedException</exception>
<onWhen>
<method ref="myBean" method="parseException" />
</onWhen>
<handled>
<constant>true</constant>
</handled>
<to uri="jms:redmine_errors"/>
</onException>
Java :
package com.example;
public class MyBean {
public boolean parseException(Exchange exchange){
return exchange.getProperty("CamelExceptionCaught")
.toString().contains("statusCode: 500");
}
}
<bean class="ats.emvo.transform.TransformXml" id="trsnformbean"/>
<camelContext id="cbr-example-context" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="file:///d:/in"/>
<to id="_to2" uri="file:///E:/out"/>
</route>
</camelContext>
i want to Transform XMl to another xml format. assume i have a logic in ats.emvo.transform.TransformXml java file how do i integrated to transform tis in camel context input (file:///d:/in) is xml file and i want to save it as another location as xml. i already add this file as bean class to camel
You can invoke your bean directly in your routing logic. Just make sure your bean is correctly referenced. With Spring XML, the syntax looks like this:
<route id="_route1">
<from id="_from1" uri="file:///d:/in"/>
<bean ref="myBeanName" method="doTransform"/>
<to id="_to2" uri="file:///E:/out"/>
</route>
You may also want to check the Apache Camel documentation on the matter:
http://camel.apache.org/message-translator.html
I am using Apache camel and jboss fuse, I have created a sample route blue print listed below in, i have sucessfully handling exceptions in all my routes now the problem is i can not find any example of throttling in routes as i have defined. in apache camel documentation, they have given simple DSL throttling and in stackoverflow i have found rabbitMq throttling which is not my case. how to throttle routes like this in apache camel
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<cxf:rsServer address="/testservice" id="testserver" serviceClass="com.company.HelloBean">
<camelContext id="testContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<route id="testRoute" >
<throttle timePeriodMillis="10000">
<constant>3</constant>
<from id="_from1" uri="cxfrs:bean:testserver"/>
<bean beanType="com.company.HelloBean"
id="_bean1" method="hello"/>
</throttle>
</route>
</camelContext>
</blueprint>
this give error when in deploy application in jboss fuse. that can not find service
hy, all you need is you are currently defining your from endpoint in throttle tag which is wrong you need to define the throttling tag only in TO tag like this
<throttle id="_throttle1" rejectExecution="true" timePeriodMillis="10000">
<constant>1</constant>
<bean beanType="com.company.HelloBean"
id="_bean1" method="hello"/>
</throttle>
when requests come to an end point from, you will throttle while requests are going TO another end point you are using beans so, you can do something like this
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<cxf:rsServer address="/testservice" id="testserver" serviceClass="com.evampsaanga.gethomepage.GetHomePageDataLand">
<cxf:providers>
<bean class="com.evampsaanga.restresponses.ExceptionHandler" id="securityException"/>
</cxf:providers>
</cxf:rsServer>
<!-- <bean class="com.saanga.servicetest.THR" id="myPolicy"/> -->
<camelContext id="testContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<route id="testRoute" >
<from id="_from1" uri="cxfrs:bean:testserver"/>
<log id="_log1" message="header : ${headers}"/>
<setHeader headerName="headerbalance" id="_setHeader1">
<simple>${headers}</simple>
</setHeader>
<setBody id="_setBody1">
<simple>${body}</simple>
</setBody>
<throttle id="_throttle1" rejectExecution="true" timePeriodMillis="10000">
<constant>1</constant>
<bean beanType="com.evampsaanga.gethomepage.GetHomePageDataLand"
id="_bean1" method="Get"/>
</throttle>
</route>
</camelContext>
</blueprint>
So, now I am attempting to import routes from an XML file into the Java DSL.
I've been attempting to start with this link but since it's such a simple example, it doesn't really help me and doesn't point me to a more complicated example.
My problem is that my Camel routes use beans. Beans for the PropertiesComponent and FileIdempotentRepository and others are defined within the XML file for use by the routes in the XML file.
My original Spring configuration looked something like the following:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="bean1" class="class1" />
<bean id="bean2" class="class2" />
<bean id="bean3" class="FileIdempotentRepository"> [...] </bean>
<bean id="properties" class="PropertiesComponent"> [...] </bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="{{someplace}}&filter=#bean1" />
<setHeader headerName="FileRepoKey">
<simple>${file:name}-${file:modified}</simple>
</setHeader>
<idempotentConsumer messageIdRepositoryRef="bean3">
<header>FileRepoKey</header>
<process ref="bean2" />
<to uri="{{otherplace}}"/>
</idempotentConsumer>
</route>
</camelContext>
</beans>
So how do I convert this mess into something usable by the Java DSL to import routes from?
I understand from looking at that link that I need to do something like convert <camelContext> to <routes>. But leaving in the beans gives me an error along the lines of:
Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.springframework.org/schema/beans", local:"beans"). Expected elements are [...]
What do I need to change? Or can I not have beans in the XML file in order for it to be imported by the Java used in the link?
I guess I should've asked this a different way and maybe someone would have thought of this way.
It may give you all nightmares, I'm not sure. Be warned.
So since the concept is "have things potentially run from an XML file alongside Java" the following end result came about:
public static void main(String[] args) throws Exception {
Main main = new Main();
//the XML file has a CamelContext in it.
main.setApplicationContextUri("myRoutes.xml");
main.start();//instantiates the CamelContext so we can use it in Java
List<CamelContext> camelContexts = main.getCamelContexts(); //should only have 1 item in the list
CamelContext context = camelContexts.get(0);
//in order to add a component to the registry the following is needed for set up
// afterwards, should just be able to add anything to the registry with registry.put("name", object)
final SimpleRegistry registry = new SimpleRegistry();
final CompositeRegistry compositeRegistry = new CompositeRegistry();
compositeRegistry.addRegistry(context.getRegistry());
compositeRegistry.addRegistry(registry);
((DefaultCamelContext) context).setRegistry(compositeRegistry);
final FileIdempotentRepository myFileStore = new FileIdempotentRepository();
File myFile = new File("idempotentRepoFiles/myFileStore.txt");
final TimeStampFileFilter<?> myFileFilter = new TimeStampFileFilter<Object>(0L);
registry.put("myFileFilter", myFileFilter);
//512MB
myFileStore.setMaxFileStoreSize(536870912L);
myFileStore.setFileStore(myFile);
myFileStore.setCacheSize(100000);
//add a route to the CamelContext that was initially created in the XML file
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
onException(myException.class)
.handled(true);
onException(GenericFileOperationFailedException.class)
.onException(SocketException.class)
.maximumRedeliveries(2)
.redeliveryDelay(5000L)
;
Processor myProcessor = new myProcessor();
from("{{myStart}}&filter=#myFileFilter")
.setHeader("myFileRepoKey", simple("${file:name}-${file:modified}"))
.idempotentConsumer(header("myFileRepoKey"), myFileStore)
.process(myProcessor)
.to("{{myEnd}}")
;
}
});
context.start();
main.run();
}
Basically: create a CamelContext in the Spring XML file, initialize it, grab it, modify it to include routes built in Java.
Route definition in Camel can be XML based (Spring DSL or Blueprint DSL) or Java based (Java DSL). A route definition can be expressed equally in both languages.
In a Spring application you can define your beans in a file and your routes in other files which you import. Routes defined in external files can refer to beans defined in your main file.
spring-main.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="bean1" class="class1" />
<bean id="bean2" class="class2" />
<bean id="bean3" class="FileIdempotentRepository"> [...] </bean>
<bean id="properties" class="PropertiesComponent"> [...] </bean>
<import resource="camel-routes.xml"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="ExternalRoutes"/>
</camelContext>
</beans>
camel-routes.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<routeContext id="ExternalRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="ARoute">
<from uri="direct:startHere" />
<to uri="bean:bean3" />
</route>
</routeContext>
</beans>
You can import more than one external file, of course. Just name each RouteContext differently.
If you modify one of the RouteContexts you must then restart your application. If you need a more dynamic application, try using an OSGi container to run your Camel routes, so you can easily modularize your application and add/remove features at runtime.
I am trying to have a camel route, which would accept a payload on a http endpoint and then write that payload to a JMS queue.
The route that I have so far is below. But an empty message gets delivered to the jms queue. A message gets there, but it has no body.
Heres the route:
<route >
<from uri="jetty:http://0.0.0.0:8050/add/Customer"/>
<inOnly uri="jms:queue:Q.Customer" />
</route>
Heres the payload that I'm sending into to 'http://0.0.0.0:8050/add/Customer' endpoint:
<Customer xmlns="http://www.openapplications.org/9" xmlns:lw="http://www.org/9">
<Name>John</Name>
<Gender>Female</Gender>
</Customer>
Any inputs on why the message body is not being written to the jms queue?
Thanks...
Your routes worked as expected. I tested it with following setup:
<broker xmlns="http://activemq.apache.org/schema/core" useJmx="true" persistent="false">
<transportConnectors>
<transportConnector uri="tcp://localhost:61616" />
</transportConnectors>
</broker>
<bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="failover:tcp://localhost:61616" />
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route >
<from uri="jetty:http://0.0.0.0:8050/add/Customer"/>
<inOnly uri="jms:queue:Q.Customer" />
</route>
<route>
<from uri="jms:queue:Q.Customer" />
<log message="Body: ${body}" />
</route>
</camelContext>
I tested the route using the org.apache.camel.spring.Main helper class:
Main main = new Main();
main.setApplicationContextUri("META-INF/spring/jms-inout-producer.xml"); // change this
main.start();
final Object body = "<Customer xmlns=\"http://www.openapplications.org/9\" xmlns:lw=\"http://www.org/9\"><Name>John</Name><Gender>Female</Gender></Customer>";
final ProducerTemplate template = main.getCamelTemplate();
template.requestBody("http://localhost:8050/add/Customer", body);
This lead to following output:
INFO Body: <Customer xmlns="http://www.openapplications.org/9" xmlns:lw="http://www.org/9"><Name>John</Name><Gender>Female</Gender></Customer>