How to Inject String property to javax.jms.TextMessage in Spring Integration - java

I wanted to know is there any way to add properties to JMS text Message in Spring Integration.
For example if we use normal JMS code we can always set properties to it using the below code.
message.setStringProperty( "AuctionType", "Reverse" );
Edit
I tried to add the header as given in Spring document but now i am getting same message Id for each message, but as i am intended to use it as ID, so i need it to be different for each message.
Below is my snapshot of Spring configuration.
<bean class="com.learn.util.RandomMsgId" id="randomMsgId" factory-method="getRndMsgId" scope="prototype"/>
<int:header-enricher input-channel="xmlToJMS"
output-channel="xmltoJMSwithId">
<int:header name="MsgId" ref="randomMsgId"/>
</int:header-enricher>

Use a <header-enricher/> to add custom headers to the spring integration message and they will be mapped to JMS headers.
See the documentation and here.

Related

Spring Integration SFTP - Getting configurations from XML

Let say I have these configurations in my xml,
<int-sftp:outbound-channel-adapter id="sftpOutbound"
channel="sftpChannel"
auto-create-directory="true"
remote-directory="/path/to/remote/directory/"
session-factory="cachingSessionFactory">
<int-sftp:request-handler-advice-chain>
<int:retry-advice />
</int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>
How can I retrieve the attributes i.e, remote-directory in Java class ?
I tried to use context.getBean('sftpOutbound') but it returns EventDrivenConsumer class which doesn't have methods to get the configurations.
I'm using spring-integration-sftp v 4.0.0.
I am actually more concerned with why you wan to access it. I mean the remote directory and other attributes will come with the headers of each message, so you will have access to it at the Message level, but not at the level of Event Driven Consumer and that is by design, hence my question.

how to add UsernameTokenInterceptor cxf interceptor

I'm looking for a way to add security header to my soap request.
I've found the interceptor, which will solve my problem: UsernameTokenInterceptor
Could someone suggest me how to create with my arguments (password, username) this bean and correctly insert it into my jaxws client
<jaxws:client id="***" name="***" endpointName="***" serviceName="***" address="***" serviceClass="***" xmlns:tns="***">
<jaxws:outInterceptors>
<ref bean="myInterceptor" />
</jaxws:outInterceptors>
The UsernameTokenInterceptor is a policy-aware interceptor that gets automatically created if your WSDL has a security policy that matches a sp:UsernameToken (with no other security binding. If so, then a different interceptor is used. UsernameTokenInterceptor is just to insert the UsernameToken). So you only need to specify the username + password as JAX-WS properties and you're done.
If you don't have a security policy, then you want to use the WSS4JOutInterceptor instead, to manually insert a UsernameToken in the outbound security header.
For an example of a policy which will trigger the UsernameTokenInterceptor, see the policy called "DoubleItPlaintextPolicy" here:
https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=systests/ws-security-examples/src/test/resources/org/apache/cxf/systest/wssec/examples/ut/DoubleItUt.wsdl;h=c76294cb0f5900e363c0731e358449c93f925fe8;hb=HEAD
If you want to use the manual approach, there is an example in the CXF docs:
http://cxf.apache.org/docs/ws-security.html

Create Camel endpoints in java to use in xml routes

I've been trying to create endpoints in java and have those endpoints referenced in my xml routes but have been unsuccessful. I can do this in xml:
<endpoint id="kafkatopic" uri="kafka:..."/>
and have the endpoint referenced in the routes:
<route id="eventflow">
<from ref="kafkatopic" ...>
What i want to do is replace the xml endpoint declaration using java. I've tried something like:
Endpoint kafkaep = camelCtx.getEndpoint(kafkaUri);
however i'm stumped on how i can create a key "kafkatopic" to refer to the endpoint such that the xml route is able to find it. I've checked the EndpointRegistry but doesn't allow me to provide a simple name for the endpoint.
Any help is appreciated. Thanks.
Here's my camelContext:
<camelContext xmlns="http://camel.apache.org/schema/blueprint"
trace="true" id="context">
<routeBuilder ref="myRouteBuilder" />
<route id="eventflow">
<from ref="kafkatopic" ...>
My simplified RouteBuilder.configure() has below. Here i was trying to put the endpoint in the endpointRegistry hoping that it will used by the xml route. There's not a lot of docs on EndpointRegistry so i was shooting in the dark with this.
// endpoint i have formatted to be "someKey=uri"
String endPoint = getConfigs("camel-endpoint");
String [] eptoks = ep.split("=", 2);
EndpointRegistry<String> endpointRegistry = camelContext.getEndpointRegistry();
Endpoint endpoint = camelContext.getEndpoint(eptoks[1]);
endpointRegistry.put(eptoks[0], endpoint);
You could try defining the endpoint in Spring, either explicitly:
<bean id="kafkaComponent" class="org.apache.camel.component.kafka.KafkaComponent"/>
<bean id="kafkaEndpoint" class="org.apache.camel.component.kafka.KafkaEndpoint">
<constructor-arg value="kafka:..."/>
<constructor-arg ref="kafkaComponent"/>
</bean>
or using Spring factory bean and method:
http://www.javabeat.net/create-spring-beans-using-factory-methods/
The easiest way to achieve this would be to create a class which implements the
org.apache.camel.Processor
interface and configure this in the spring xml file, e.g.
<bean id="sp" class="com.mycompany.SimpleProcessor"/>
In your route you can then reference this simply using the id you gave in the bean, e.g.
<to uri="sp" />
I would say that makes it a bit confusing to read although perhaps you have a good reason but when I look at the route I want to clearly know the endpoint details unless they are referenced above somewhere. To have to look up the endpoint in a java class can be cumbersome later on.
I recently found out that you can write your entire RouteBuilder logic in java and simply let the blueprint xml call it just like any other bean? That why your routes are in java and the startup mechanism in xml.
I know it's late but here's what i did to make this work. Basically i programmatically created the endpoints simply as "direct" endpoints based on configuration and reference those direct endpoints in my camel routes xml file. That way i avoided having environment specific values like hostnames, port numbers, etc., in my xml routes file and just have one version for all environments.

Copy mule variable data or mule property like payload to spring bean property

I am having a mule flow in which I am having a variable to which payload is copied as follows:
<set-variable variableName="originalPayload" value="#[payload]" doc:name="Variable" doc:description="Variable having copy of original payload present in soap request."/>
After this there is an interceptor that validates header of soap message and if validation fails then I need the above variable's data in interceptor to prepare custom fault message. Below is my configuration for Soap Proxy doing above:
<cxf:proxy-service port="XXX" namespace="XXX" service="XXX" payload="body" wsdlLocation="XXXX" doc:name="SOAP" doc:description="Soap proxy intercept soap request and apply header validation. Authentication and custom header will be validated for presence, content, and structure.">
<cxf:inInterceptors>
<spring:bean id="XXXX" parent="XXXX">
<spring:property name="sourceApplication" value="${sourceApplication}"/>
<spring:property name="originalMessage" value="#[originalPayload]"/>
</spring:bean>
</cxf:inInterceptors>
</cxf:proxy-service>
In above I need the value of originalPayload variable in originalMessage property of spring bean. If I can copy #[payload] directly it will work too. Above expression in spring property is not valid so it is not working.
Please suggest how to go for this.
Implementing Callable can be one option but I do not want to change the code written already unless there is no solution for above.
I tried to search for solution on this but could not find anything.
Thanks
Harish Kumar
The problem with your solution is that spring properties are set at configuration time whereas the #[payload] expression could be only resolved at runtime.
However within your interceptor you could retrieve the original payload from the CXF message by doing something like this:
MuleEvent event = (MuleEvent) message.getExchange().get(CxfConstants.MULE_EVENT);
Collection<Attachment> a = event.getMessage().getInvocationProperty("originalPayload");
You can refer to this interceptor as an example

Spring WS 2.1.0: Endpoint interceptors order

I have a web service on Spring WS with two endpoint interceptors. XML configuration looks like this
<sws:interceptors>
<bean class="org.someorg.security.SignatureInterceptor"/>
<bean class="org.someorg.common.LoggingInterceptor">
<constructor-arg value="logger_1"/>
</bean>
</sws:interceptors>
SignatureInterceptor verifies signature of incomming SOAP Envelope and signs outgoing SOAP Envelope.
LoggingInterceptor stores raw SOAP data (byte array) in a database.
I need SignatureInterceptor to invoke before LoggingInterceptor and writing interceptor beans this way I expected it would solve my problem. But according to log messages LoggingInterceptor invokes first, so unsigned data stores in a database.
Then I changed configuration simply swaped bean declarations and they began to work as I expected
<sws:interceptors>
<bean class="org.someorg.common.LoggingInterceptor">
<constructor-arg value="logger_1"/>
</bean>
<bean class="org.someorg.security.SignatureInterceptor"/>
</sws:interceptors>
But this case is not clear to me. How can I explicitly set the invoke order of interceptors?
The order should be the way you have specified it (except if they are mapped to a specific endpoint url, in which case they are handled last) - do note that the order in which the order in which the handleResponse is handled is opposite of handlRequest -
Ideally in your case you should see:
SignatureInterceptor.handleRequest(..)
LoggingInterceptor.handleRequest(..)
Endpoint handles request
LoggingInterceptor.handleResponse()
SignatureInterceptor.handleResponse()
I tried a small test and it works the same way for me.

Categories