How to use method with parameters in Camel XML DSL? - java

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.

Related

Spring ActiveDirectoryLdapAuthenticationProvider setSearchFilter method

I have a working setup for SpringFramework Security 4.0.0 with my AD server. This was working fine with the default search filter until I discovered that the users in the AD database are much more twisted than expected originally.
My setup was as follow for the ActiveDirectoryLdapAuthenticationProvider bean in the namespace:
<b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="subdom1.dom1.com" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:constructor-arg value="dc=fsapps,dc=company,dc=uni" />
<b:property name="searchFilter" value="(&(userPrincipalName={0})(objectClass=user))" />
<b:property name="userDetailsContextMapper">
<b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
</b:property>
<b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
</b:bean>
I then moved to the following setup instead to remove the dependency on the domain:
<b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:constructor-arg value="dc=fsapps,dc=company,dc=uni" />
<b:property name="searchFilter" value="(&(sAMAccountName={0})(objectClass=user))" />
<b:property name="userDetailsContextMapper">
<b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
</b:property>
<b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
</b:bean>
The problem now is the {0} substitution in the searchFilter accordingly to the SpringFramework Security 4.0.0 documentation is substituting username#domain where domain seems to be the default domain of the AD server itself, which in this case is fsapps.company.uni since my first constructor argument is empty. SpringFramework Security 4.0.0 Class ActiveDirectoryLdapAuthenticationProvider's documentation
Question: Is there a way to substitute only username rather than username#domain? Any other suggestions how I can circumvent this problem?
NOTE: After looking at the source code. It seems the expected behavior should be as follow: if the domain argument for the constructor of the class ActiveDirectoryLdapAuthenticationProvider is an empty string or an all white spaces string, it is set to null. When the domain is set to null, the substitution of the {0} pattern should be the username only without the domain appended to it and this should do exactly what I want it to do: search for the sAMAccountName attribute equals to the username alone and a record of objectClass user. So, why does it fail to find users which are not in the rootDN as a domain (third constructor's argument fsapps.company.com in my example)? I have no problem to match users which would have a userPrincipalName of the form: username#fsapps.company.com while I cannot match users with a userPrincipalName of the form: username#whatever.domain ?
NOTE 2: I found the problem, not yet the solution. Actually, my search filter is perfectly fine and Spring Security is using it correctly. The problem is the authentication is performed by a bind to the AD server and to bind to the server I must use username#fsapps.company.com (if authorized) or either username#domain.in.constructor.arg.1. The sAMAccountName attribute is checked against a username with a domain rather than a username without a domain. If the domain is added, there is no sAMAccountName matching the value passed as an argument.
An alternative is using (sAMAccountName={1}) based on this fix.
A working solution is to rely on the first shown configuration using the userPrincipalName and emptying the first constructor's argument to pass an empty string to the constructor. This way, nothing will be appended to the username and instead of typing a simple username, the users have to type their complete usernames with the domain specified. So, instead of logging in with username, the use username#domain.
Another solution would be to investigate if it is possible to bind to the AD database with a generic and authorized user to perform all the queries on its behalf. I haven't investigate if it is feasible (it is done with plain LDAP) and how much effort it requires. If anyone experiment this solution, it would be nice to post the results here to share this solution.

Mule db component Input payload from another db query

I need a basic Mule flow in order to select rows from one database, transform the payload and call a procedure in another database. I don't want to use DataMapper component, I would like to use Java Transformer instead.
My XML flow:
<set-variable variableName="currentOrder" value="#[payload.increment_id]" doc:name="Variable"/>
<db:select config-ref="MySQL_Configuration" doc:name="GET ORDER">
<db:parameterized-query><![CDATA[select id from sales where id=#[currentOrder]]]></db:parameterized-query>
</db:select>
<custom-transformer class="com.mycompany.transformers.TargerProc" doc:name="Java"/>
<db:stored-procedure config-ref="Oracle_Configuration" doc:name="PROC1">
<db:parameterized-query><![CDATA[call proc1(:P1,:P2)]]></db:parameterized-query>
<db:in-param name="P1" type="NUMERIC" value="#[payload.id]"/>
<db:out-param name="P2" type="NUMERIC" value=""/>
</db:stored-procedure>
First problem:
Message payload is of type: CaseInsensitiveHashMap
Could someone shed some light on this? I think it is really simple to achieve this.
Thanks in advance!
Try this <db:parameterized-query>{ call proc1(:P1,:P2) }</db:parameterized-query> :-
<set-variable variableName="currentOrder" value="#[payload.increment_id]" doc:name="Variable"/>
<db:select config-ref="MySQL_Configuration" doc:name="GET ORDER">
<db:parameterized-query><![CDATA[select id from sales where id=#[currentOrder]]]></db:parameterized-query>
</db:select>
<custom-transformer class="com.mycompany.transformers.TargerProc" doc:name="Java"/>
<db:stored-procedure config-ref="Oracle_Configuration" doc:name="PROC1">
<db:parameterized-query>{ call proc1(:P1,:P2) }</db:parameterized-query>
<db:in-param name="P1" type="NUMERIC" value="#[payload.id]"/>
<db:out-param name="P2" type="NUMERIC" value=""/>
</db:stored-procedure>

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.

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