Use CamelLoopIndex in Camel XML Root - java

Recently we update our version of Appache Camel.
And we used CamelLoopIndex like this in the previous version :
<loop copy="false">
<simple>${in.body.tabs.size}</simple>
<choice>
<when>
<simple>${in.body.tabs.get(property.CamelLoopIndex).code} == 'ABC'</simple>
...
</when>
</choice>
</loop>
Since the update "property.CamelLoopIndex doesn't work anymore.
Please someone have any ideas ?
I tried to change "property" into "exchangeProperty but it doesn't work...

Related

How to use method with parameters in Camel XML DSL?

I've got a problem with using method with parameters in Camel XML DSL.
What I've done is something like this:
I've created below bean before my camelContext
<bean id="properties" class="java.util.Properties"/>
The thing I would like to do is using method 'put' from HashTable, which extends Properties.
When I call a method without parameter it's working perfectly fine.
<method ref="properties" method="NAME OF METHOD THAT HAS NO PARAMETERS">
or
<bean ref="properties" method="SAME AS ABOVE"/>
Method that I'm trying to use:
public synchronized V put(K key, V value)
But when I'm trying to use something like the code below I would like to assign some parameters
I've tried a lot of possibilities, maybe it's impossible or my knowledge of syntax is poor:
<method ref="properties" method="put" argument="key_el" arugment="val_el"/>
<method ref="properties" method="put" value="key_el" value="val_el"/>
<method ref="properties" method="put?keyEl&valEl"/>
<method ref="properties" method="put">
<argument id="key" value="someKey" type="java.lang.String"/>
<argument id="value" value="someValue" type="java.lang.String"/>
</method>
There's plenty more that I've tired, some of them are just not worth of showing. I read from people apache and camel documentation, that there's possibility to make it somehow but there was no example of doing that in XML DSL.
Thanks in advance for any hints and help.
You can call beans method with arguments using method="put('key', 'value')". You can also use simple syntax there if you need values from the Exchange like body, headers or exchange properties `method="put('bodyValue', ${body})"``
This approach also works with simple language. Say if you have object stored in to message header you can call it's methods using ${headers.helloBean.hello('Tim')}
<bean id="ExampleProperties" class="java.util.Properties" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="testRoute">
<from uri="direct:testRoute" />
<bean ref="ExampleProperties" method="put('bodyValue', ${body})" />
<setBody>
<simple>${bean:ExampleProperties?method=get('bodyValue')}</simple>
</setBody>
<log message="Body value: ${body}" />
</route>
</camelContext>
Be careful when storing values to beans instead of using body, headers or exchange properties as beans persist between exchanges.

MULE ESB -> SOAP mapping - Easy Method don't work

Hi all I'm new in Mule so please go easy on me. First of all I will show you example on SOAP UI:
Here is WSDL FILE: wsdl file
Its pretty easy. I want to make exacly the same mule flow (no input data etc - payload set in code). The problem is that I simple even can't start. I read tutorial:
http://www.mulesoft.org/documentation/display/current/XML-only+SOAP+Web+Service+Example
But still I can't do dataMappings like here. Any idea what I'm doing wrong my whole flow isn't big ... now its look like this:
<flow doc:name="PostRequest" name="PostRequest">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="getPostRequest" doc:name="HTTP" />
<cxf:jaxws-client operation="PostRequest" doc:name="SOAP"
enableMuleSoapHeaders="true" clientClass="pl.execon.integration.axpppk.ws.client.XISGateway"
port="XISGatewaySoap" />
<http:outbound-endpoint address="http://localhost:8889/Service/XISGateway.asmx" />
<object-to-string-transformer doc:name="Object to String" />
</flow>
I want to use PostRequest ... Any advices ? Tutorials that can help ? Problem is that I need to make this envelope modification:
<soap:Body>
<m:PostRequest>
<m:_requestCode>Test</m:_requestCode>
<m:GetGasCustTable>
<m:XMLDocumentTime>2014-07-21T12:24:50</m:XMLDocumentTime>
<m:CustAccount>00043280</m:CustAccount>
</m:GetGasCustTable>
</m:PostRequest>
</soap:Body>
And I Simply don't know how
If want to use post and map a webservice just use pattern this is a working code for post method:
<pattern:web-service-proxy name="webserviseName">
<inbound-endpoint address="http://localhost:8081/localUWant" exchange-pattern="request-response"/>
<outbound-endpoint address="http://localhost:8889/Service/XISGateway.asmx" exchange-pattern="request-response"/>
</pattern:web-service-proxy>
As simple as that.
this is the documentation: http://www.mulesoft.org/documentation/display/current/Using+Mule+Configuration+Patterns

Spring xslt processing works on a string but not a dom

I'm using Apache Camel 2.10.4 to create xml documents. I want to view the xml as html in one use case so my Camel route (defined in Spring DSL) uses an xslt to transform the xml document to html.
The xml is generated in a Java bean and output as a DOM Document.
If I use convertBodyTo to convert the Document to a String before handing it to the xslt all is well. If I leave this out, the xslt processor doesn't find the elements in my document.
This returns an html string with a table containing a row for each schedule item in my TVAnytime xml document:
<route>
<from uri="direct:show_bn"/>
<to uri="bean:gen"/>
<convertBodyTo type="java.lang.String"/>
<to uri="xslt:tva2html.xslt"/>
<setHeader headerName="Content-Type">
<constant>text/html;</constant>
</setHeader>
</route>
This returns the html with no rows in the table:
<route>
<from uri="direct:show_bn"/>
<to uri="bean:gen"/>
<to uri="xslt:tva2html.xslt"/>
<setHeader headerName="Content-Type">
<constant>text/html;</constant>
</setHeader>
</route>
The method executed in the bean has this signature:
public org.w3c.dom.Document process();
Any idea why this is happening? I suspect something wrong with namespace aware processing when the xslt processing gets a DOM.
I just added a quick test in camel-core, I cannot reproduce the error.

Can we use parameters in oozie decision node?

I am trying to execute a decision control node in oozie 3.3.2 but getting javax.servlet.jsp.el.ELException
Encountered "{"
<decision name="decision-wf">
<switch>
<case to="another_wf">
${fs:fileSize(${OutputDir}/000000_0) gt 100 }
</case>
<default to="fail-wf"/>
</switch>
How should I pass the parameter in String format as the above mentioned FS method expects String input ?
From the document it appears,
You need to pass hardcoded i.e. enclosed in ' like in ${fs:fileSize('/usr/foo/myinputdir'/1000) gt 10 }
or
just the parameter name ${fs:fileSize(OutputDir/1000) gt 10 }
This OutputDir might be specified in the <config> sections of the workflow OR the .properties file OR passed at time of submitting the job using -D
Yes you can. In fact you can combine multiple parameters with the concat function (which, I think, would help with the original poster's question).
For example if ${location} and ${date} are two params defined in your config file:
<decision name="check-directory-exists">
<switch>
<case to="load-directory">
<!-- check if the directory at this location for this date exists -->
${fs:exists(concat(location, date))}
</case>
<!-- The directory doesn't exist, there is nothing to do -->
<default to="end" />
</switch>
</decision>
and if location and date need a '/' between them, you have to do this:
${fs:exists(concat(concat(location, "/"), date))}

How do I pass model data beween a view state and action state in Spring Web Flow 2

In the Web Flow below I bind form data to a flow variable (lifeCycleForm) on a submit event in the view state. I have verified that the name, label and description properties are all populated as expected.
However, when the expression in the action state is evaluated all three properties are null. My form bean is serializable and I am just using simple string properties.
What I am doing wrong?
I am pretty new to Spring WebFlow so I might have missed something obvious.
<var name="lifeCycleForm" class="com.btmatthews.freelancer.lifecycle.portlet.LifeCycleForm" />
<view-state id="createLifeCycle" model="lifeCycleForm">
<binder>
<binding property="name" required="true" />
<binding property="label" required="true" />
<binding property="description" required="false" />
</binder>
<transition on="submit" to="createLifeCycleAction" />
<transition on="cancel" to="lifeCycleCreationCancelled" bind="false" />
</view-state>
<action-state id="createLifeCycleAction">
<evaluate expression="lifeCycleService.createLifeCycle(lifeCycleForm.name, lifeCycleForm.label, lifeCycleForm.description, null, null)" />
<transition on="success" to="lifeCycleCreated" />
<transition on="failure" to="createLifeCycle" />
</action-state>
<end-state id="lifeCycleCreated" />
<end-state id="lifeCycleCreationCancelled" />
Update: I neglected to mention in my original posting that it was my unit tests that were failing. I have since learned that AbstractFlowExecutionTests does not implement binding of request parameters. This seems like a bit of an oversight to me. I have tried latest nightly Spring WebFlow 2.0.4 and the behaviour remains the same.
Update: My problems are that Spring WebFlow mocks do not simulate form submission.
Thanks in advance,
Brian
To much chagrin, I also recently found out that the Webflow testing mocks don't use Spring's binding. Have you tried running the flow using debugging in a container like Tomcat from within an IDE like Eclipse ? If you haven't, it'll be very useful. If you need help, I can provide further tips, but to start I'd say download the Eclipse Web Standard Tools and Web Tools Project plugins if you haven't already.
Just as a side note, if you really want to be able to unit test binding, you can also still use the Spring Webflow 1 FormActions to bind to the model object, even though it will make your flow slightly more verbose.

Categories