How can I get spring property in flow? - spring

I work with Mule. And I have spring bean
<spring:bean id="`MyPropertiesSaver`" name="MyPropertiesSaver" class="MyPropertiesSaver">
<spring:property name="prop_name" value="${PROP_VALUE}"/>
</spring:bean>
Also I work with file in flow
<flow name="Handler" doc:name="Handler">
<file:inbound-endpoint `path="${PROP_VALUE}"` moveToPattern="#[header:originalFilename].txt" responseTimeout="10000" doc:name="File"/>
...
</flow>
So I get PROP_VALUE from system variables. I want to change path of file while programm is running. I change prop_name of class MyPropertiesSaver using MX4J. But path="${PROP_VALUE}" does not change. That's why I want to get prop_name from MyPropertiesSaver. Somthing like this
path="MyPropertiesSaver.prop_name"
How can I do that?

You need to extend the file message receiver to allow to externally set of the fileDir and disconnect-connect when this happens. Then in your connector use a service-override to use that customised message receiver.

Having a Dynamic Endpoint for File Inbound is not possible.
File Inbound should know where to look for when the flow is started.
If your usecase demands a dynamic file location and reading you can try the workaround with Mule Requester module.
Read throubh the following link for more details.
Unable to create dynamic file inbound endpoint in mule
Hope this helps.

Related

Global Variable in Spring Integration?

I have one transformer who's output is input for one of my http:outbound-gateway and the output channel of this outbound-gateway is input for my one of activator. My requirement is to get some of data from my Transformer to my activator.
Something like below.
<int:transformer ref="jsonToXmlTransformer" input-channel="replyChannel" output-channel="someObj"/>
<http:outbound-gateway
request-channel="someObj"
expected-response-type="o.s.h.ResponseEntity"
reply-channel="replyChannel"
url="{someurl}"
http-method="POST"
extract-request-payload="true">
</http:outbound-gateway>
<int:service-activator id="expressionConverter" input-channel="replyChannel"
ref="lastActivator"/>
Dont focus on this config. I mean, I am at home and tried my best to recall my configs as office one. Nothing wrong with that. Only that I am not getting my expected data from my transformer to my last activator. Which is nothing but like an endpoint for application flow.
Consider to transfer required data in headers. Add it into headers after transformer before outbound Gateways and get it from there in the activator.

read message from queue/topic in mule

I want to implement a consumer kind behaviour using Mule, ActiveMQ which can read JMS messages....there is some third party queue/topic. need to subscribe to them and start listening. How can I achieve that in mule?
Follow the instructions in this blog post to get a working connector. If you are using JMS1.1 you don't even need to specify queue or topic, they will behave the same. If you are using 1.0b, please make sure you specify the correct type.
Then, instead of using an outbound endpoint use an inbound endpoint:
<jms:inbound-endpoint topic="myTopic" connector-ref="Active_MQ" />
I do, however, recommend to use Anypoint Studio, that will provide you a very simple interface for this kind of configurations.
To read a message from activemq queue ot topic, can simply put in your flow for example:
<flow name="insert-operation" doc:name="insert-operation" doc:description="">
<jms:inbound-endpoint connector-ref="Active_MQ" exchange-pattern="request-response" queue="insert-jms" doc:name="JMS">
<idempotent-redelivery-policy idExpression="#[message.inboundProperties['JMSMessageID']]" />
<xa-transaction action="ALWAYS_BEGIN" />
</jms:inbound-endpoint>
...
</flow>

Spring Integration/RabbitMQ/AMQP: How do I create outbound-channel-adapters for dynamic input channels?

I'm working on abstracting out any sort of messaging framework for some code I'm working on. Basically, I'm using a combination of Spring AOP and Spring Integration to generate messages without the Java code knowing anything about RabbitMQ, JMS, or even Spring Integration. That said, what I'm using to generate the messages is contained in its own .jar, and it re-used by several other areas of the application. I currently have the messaging system set up such that the channels on which messages are sent are specified by the code that calls the system (i.e., channels are generated automatically based on the external method invocation) by specifying the channel name in the message header and using a header-value router to create the channels if they don't exist. My issue comes in on the endpoint of these channels - the intention of the current structure is to allow Spring to change to any messaging structure as requirements specify or change. I know how to take a static channel and use outbound channel converters/gateways to send it to a pre-specified RabbitMQ/JMS queue and process from there; what I'm struggling with is how to tell Spring that I need every channel created by the router to have a RabbitMQ (or whatever other messaging system gets implemented) outbound channel adapter that's dynamically generated based on the channel name since we don't know channel names beforehand.
Is this possible? And if not, would you mind providing input as to what could perhaps be a better way?
Thanks ahead of time!
Here's a basic template of what my config file looks like - I have an initial channel ("messageChannel") which gets sent to a publish-subscribe-channel and queuing channel depending on one of the message headers and is routed from there.
<!--Header value based channel configurations-->
<int:channel id="messageChannel" />
<int:channel id="queue" />
<int:publish-subscribe-channel id="topic" />
<!--Header-based router to route to queue or topic channels-->
<int:header-value-router input-channel="messageChannel"
header-name="#{ T(some.class.with.StringConstants).CHANNEL_TYPE}" />
<!--Re-routes messages according to their destination and messaging type-->
<int:header-value-router input-channel="queue"
header-name="#{ T(some.class.with.StringConstants).MESSAGE_DESTINATION}" />
<int:header-value-router input-channel="topic"
header-name="#{ T(some.class.with.StringConstants).MESSAGE_DESTINATION}" />
<!--AOP configuration - picks up on any invocation of some.class.which.generates.Messages.generateMessage()
from a Spring-managed context.-->
<aop:config>
<aop:pointcut id="eventPointcut"
expression="execution(* some.class.which.generates.Messages.generateMessage(..))" />
<aop:advisor advice-ref="interceptor" pointcut-ref="eventPointcut"/>
</aop:config>
<int:publishing-interceptor id="interceptor" default-channel="messageChannel">
<int:method pattern="generateMessage" payload="#return" channel="messageChannel" />
</int:publishing-interceptor>
See the dynamic-ftp sample; it uses a dynamic router that creates new outbound endpoints/channels on demand.

mule jms connector

I am new to Mule and JMS. Just trying to figure out how to add a JMS end-point with a connector. Is there any JMS implementation provided by Mule or do I need to use an external JMS provider.
A simple example will be :-
<jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
To send a message to a queue :-
<flow name="JmsSendFlow" doc:name="JmsSendFlow" >
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
<set-payload value="Test Data" />
<jms:outbound-endpoint queue="StudioOUT" connector-ref="Active_MQ" doc:name="JMS"/>
</flow>
To receive message from the queue :-
<flow name="JmsReceiveFlow" doc:name="JmsReceiveFlow" >
<jms:inbound-endpoint queue="StudioOUT" connector-ref="Active_MQ1" exchange-pattern="one-way"/>
<logger message="Message received#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
For more information about JMS:-
http://blogs.mulesoft.com/dev/newbie/mule-school-jms-tutorial/
Here is the ActiveMQ usage guide for Mule JMS connector.
Mule ActiveMQ integration
http://www.mulesoft.org/documentation/display/MULE3USER/ActiveMQ+Integration
This should help.
Drag out another HTTP connector and drop it in the canvas to create a new flow.
Give the flow a new name of postTopicMessageFlow.
In the HTTP Properties view, set the connector configuration to the existing
HTTP_Listener_Configuration.
Set the path to /jms and the allowed methods to GET.
Drag out another JMS connector and drop it into the process section of the flow.
In the JMS Properties view, select topic and set it to jms connectivity.
Set the connector configuration to the existing Active_MQ.
If you see an Attribute ‘action’ is required warning, ignore it.
Add a Set Payload transformer between the HTTP and JMS connector endpoints.
In the Set Payload Properties view, change the display name to Set Message and set the value
to a message query parameter.
Add a breakpoint to the Set Payload transformer.
Add a Property transformer after the Set Payload transformer.
In the Properties view, change the display name to Set Name.
Select Set Property and set the name to name and the value to your name.
Note: You can set this to a query parameter instead if you prefer.
Save the file to redeploy the application and make a request to
http://localhost:8081/jms?message=Hello.
Look at the console;; you should see your name and message displayed – along with those of
your classmates.

Spring Integration, delete file in outbound channel adapter

I am using Spring Integration to poll a directory for a File, process this file in a service class, write this file to an output directory and then delete the original file.
I have the following XML configuration:
<int-file:inbound-channel-adapter id="filesInChannel"
directory="file:${java.io.tmpdir}/input"
auto-create-directory="true" >
<int:poller id="poller" fixed-delay="1000" />
</int-file:inbound-channel-adapter>
<int:service-activator id="servicActivator"
input-channel="filesInChannel"
output-channel="filesOut"
ref="my_file_processing_service">
</int:service-activator>
<int-file:outbound-channel-adapter id="filesOut" auto-create-directory="true" delete-source-files="true" directory="file:${java.io.tmpdir}/output"/>
This polls the file, passes it to my processing_service and copies it to the outbound directory. However the original file is not being deleted. Does anyone have any idea as to why not?
I know that the question was asked a long time ago but maybe the answer will be useful to someone else.
The reason why the input file is not deleted is provided in the Spring Integration Reference:
The delete-source-files attribute will only have an effect if the
inbound Message has a File payload or if the FileHeaders.ORIGINAL_FILE
header value contains either the source File instance or a String
representing the original file path.
Your message does not contain this particular header. If you use one of the standard file transformers (FileToStringTransformer and FileToByteArrayTransformer) it will be set automatically. Alternatively you can set it manually using a header enricher.
Behind the scenes something like this is happening in the file transformers:
...
Message<?> transformedMessage = MessageBuilder.withPayload(result)
.copyHeaders(message.getHeaders())
.setHeaderIfAbsent(FileHeaders.ORIGINAL_FILE, file)
.setHeaderIfAbsent(FileHeaders.FILENAME, file.getName())
.build();
...
From the documentation http://static.springsource.org/spring-integration/reference/html/files.html
<int-file:outbound-gateway id="mover" request-channel="moveInput"
reply-channel="output"
directory="${output.directory}"
mode="REPLACE" delete-source-files="true"/>
I don't know how to do this on the inbound-channel-adapter(which I think makes sense)

Resources