Setting up a retry policy - mule

I am attempting to set up a retry policy like so:
<spring:beans>
<spring:bean id="threadingPolicyTemplate"
class="org.mule.retry.async.AsynchronousRetryTemplate">
<spring:constructor-arg index="0">
<spring:bean id="foreverRetryPolicyTemplate"
class="com.Component.ChatConnectionRetryPolicyTemplate">
<spring:property name="sleepTime" value="${connector.retryInterval}" />
</spring:bean>
</spring:constructor-arg>
</spring:bean>
</spring:beans>
<jdbc:connector name="jdbcConnector" dataSource-ref="SQLServerjdbcDataSource">
<spring:property name="retryPolicyTemplate" ref="threadingPolicyTemplate"/>
<jdbc:query key="PollDB"
value="select * from ofMessageArchive where ID > #[payload:]" />
</jdbc:connector>
I use said connector as an outbound endpoint in my flow but I don't see the retry policy even being called. (I've set breakpoints and so and they were not called).
I am using some sort of threaded SimpleRetryPolicy (nothing fancy).
One more question regarding the matter - suppose the connector doesn't start up (retry policy is being attempted) - What would happen to a flow which uses the connector as an endpoint??
How does mule treat these things?

Even if the JdbcConnector has noops for init/start/stop/dispose methods, your retry policy template is supposed to be called right after AbstractConnector.connect() logs "Connecting: ". Maybe you want to breakpoint at this place and follow through?
If you use a threaded retry policy, Mule will start even if a connector is failed. Inbound endpoints depending on this connector will not start hence flows using them won't get triggered until the connector can start. Outbound endpoints will throw exceptions: it's up to you to deal with this situation, either with until-successful or an exception-strategy that perform some custom handling of the issue.

Related

Mule dynamic property file reference

we have a flow where we have property file reference as given below
"context:property-placeholder location="httpdemo.${country}.properties"
now we want ${country} value to be replaced by actual value at the time of deployment.
As we know one way to achieve it is setting the value of country as environment variable on the ESB and deploying it. But we don’t want to do that because of below reasons:
We deploy same code base for multiple countries in parallel
Environment properties can be set only during start of mule runtime so if I set env variable as country=UK and have deployed for UK. Later I want to deploy for MY again I need to restart ESB by setting country=MY which we don’t want to do.
Please let me know if there is any other better way
We had a similar situation where we needed to have multiple versions of the same application running parallely. The solution we used for this was to package the property file along with the build and not have the dynamic element (environment based) to it. For eg; in this case we construct httpdemo.usa.properties and packaged it along with the app. This was fairly easy for us since we use Jenkins to manage our builds and releases. When the build is released, we reference a configuration file from Jenkins which contains all the specific "country" related properties. You can even pass this country as a parameter to the build definition. Using a custom maven plugin we replace the property file within the app with the new properties from the Jenkins property file.
Another solution to your problem could be to follow a naming convention to your apps specific to the "country" you want to use and fetch the properties using spring beans. For eg;
<spring:beans>
<spring:bean id="CountryProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<spring:property name="singleton" value="true"/>
<spring:property name="location" value="${app.name}.properties"/>
</spring:bean>
</spring:beans>
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="5000" doc:name="HTTP Listener Configuration"/>
<flow name="dynamic_propsFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<logger message="#[app.registry.CountryProperties['country.full.name']]" level="INFO" doc:name="Logger"/>
</flow>
My properties are like below:
File - dynamic_props_usa.properties
population=10
country.full.name=united.states.of.america
File - dynamic_props_mexico.properties
population=100
country.full.name=mexico
${app.name} gives you the name of the app that is deployed. In case my app is named dynamic_props_usa, it refers the dynamic_props_usa.properties. If it is, dynamic_props_mexico, it refers dynamic_props_mexico.properties. Hope this helps!
Define context property placeholder to have a file reference in the package and have an option to override the same with server if needed at runtime as below,
<context:property-placeholder location="classpath:app-${mule.env}.properties, file:${mule.config.path}/app-${mule.env}.properties" ignore-resource-not-found="true" ignore-unresolvable="true" />
You can run your on premise Mule server with the option -M-Dmule.country=your-value
You may want to take a look at the documentation

Mule web service consumer over JMS

I need to consume WS that's using JMS as a transport rather than HTTP.
The Web Service Consumer doc says that it supports JMS but no any example provided unfortunately of using the component with non HTTP transports.
Need help with this subject. These are the steps I've done:
The wsdl has been successfully loaded by the connector wizard in anypoint. I've specified the method to be called. The parameters were recognized by DataSense so I can see the input parameters with DataMapper etc.
The URL looks like this: jms:queue:toOrderManagement?replyToName=fromOrderManagement?targetService=OrderManagement
I've defined global JMS connector like this:
<jms:connector name="JMSConnector" specification="1.1" username="user"
password="******" validateConnections="true" doc:name="JMS">
<reconnect-forever />
</jms:connector>
and associated it with the WS connector like this:
<ws:consumer-config name="Web_Service_Consumer" wsdlLocation="myOrder.wsdl"
service="OrderManager" port="JMSOrderManager"
serviceAddress="jms:queue:toOrderManagement?replyToName=fromOrderManagement?targetService=OrderManagement"
doc:name="Web Service Consumer" connector-ref="JMSConnector"/>
So, how to specify the actual JMS queue name and what the format of the serviceAddress attribute when it's configured for JMS/WS?
Ok, it took me some time to get the answer on this.
So, first, the format of the servcieAddress should be like this:
jms://${toQueue}?exchangePattern=request-response
where toQueue is the "request" queue name i.e. the one the request will be sent to.
Now, if you don't specify any additional parameters, a temporary "response" queue will be automatically created and WS Consumer will be waiting for receiving the response from it.
If you wanna use a pre-configured queue for getting responses then, before calling the WS Consumer, you need to set the message property JMSReplyTo with the response queue name to be used. If the property is set then WS Consumer will wait for the response from that queue rather than from the temporary one.

Start/Stop Flow/Endpoint in Mule 3.3.0

I need to programmatically start or stop a flow or endpoint from another flow. Can this be done? Is there risk of message loss?
<flow name="control>
<vm:inbound-endpoint path="in">
<script:component>
<!-- start/stop -->
</script:component>
</flow>
<flow name="startable-stoppable>
<any-transport:inbound-endpoint/>
<component/>
</flow>
After some research I've found that the best option in my case is to start/stop the connectors associated with the endpoints I want to control.
<script:component>
<script:script engine="groovy">
muleContext.getRegistry().lookupConnector('connectorName').start() // or stop()
</script:script>
</script:component>
A disadvantage of this approach is that all the endpoints associated with the connector will be affected. If this is a problem, every endpoint should have its own connector.
You can control the lifecycle of Mule moving parts with JMX: use JConsole to find out what MBean you need to access from your scripted component.

Mule CXF consuming webservice

i am creating one webservice in mule using cxf:jaxws-service. This is the url :http://localhost:65042/InsertDocService/InsertDoc, i am ablie to generate WSDL file, but i want to consume this service in mule using cxf:jaxws-client.
<flow name="documentumclientflowFlow1" doc:name="documentumclientflowFlow1">
<inbound-endpoint address="http://localhost:65042/InsertDocumentumService/InsertDocumentum" doc:name="Generic"/>
<cxf:jaxws-client operation="insertDocumentum" serviceClass="com.integration.IDocumentumInsert" port="80" mtomEnabled="true" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<outbound-endpoint address="http://locahhost:65042/InsertDocumentumService/InsertDocumentum" doc:name="Generic"/>
</flow>
if i invoke this, it's going to Service project and getting erorr like"org.apache.cxf.interceptor.Fault: No such operation: (HTTP GET PATH_INFO: /InsertDocumentumService/InsertDocumentum)". Please any one suggest me how can i solve this issue and how can i consume this service.
Besides the type (locahhost instead of localhost), it looks like you're trying to use the same address in the outbound endpoint than in the inbound one. I don't think this is what you want to do, as it will lead to a looping re-entrant call that will eventually exhaust the pool threads, block, time out and die in a fire.
So what do you want to do with "documentumclientflowFlow1"? It is unclear from your question.

Mule Community Edition and Blocking retry policy

i would like to define some sort of "retry policy" for a custom componenet i built, meaning retry on the initiailise function of the compoenent.
Is that supported by some XML tag (retry policy??) or would i have to implement the retries inside the initialise function itself? (which would mean i would have to handle the threads and stuff if i want to handle it like the "blocking" property of the EE edition)
And suppose there is some sort of retry attempts - what would happen if the component is still attempting to reinitialise while an inbound endpoint event is triggered? (or would that endpoint not register until the flow manages to start the component?)
In case i wasnt clear - this is the short example:
<flow>
<quartz:inbound-endpoint jobName="eventTimer">
<quartz:event-generator-job />
</quartz:inbound-endpoint>
<component>
<singleton-object class="com.SomeComponent" />
</component>
<vm:outbound-endpoint path="ChatMsgs"
exchange-pattern="one-way" />
</flow>
I'd like to set a "non-blocking" retry policy on the component and i would like the flow not to start until the component manages to initialise, is that asking too much of mule? :)
Thanks in advance
Non-blocking retry policies are now part of CE (since 3.2.0).
To have your component integrated with Mule's lifecycle and retry policies, I suggest you develop it as a Mule module using DevKit (see "Mule’s Lifecycle Support" in http://blogs.mulesoft.org/introducing-the-new-devkit/). Though marketed as an "API connector toolkit", DevKit does way way more things...
Of course, this would make your component Mule specific but with the benefit of making it a first-class citizen of Mule's infrastructure.