Reputation: 35351
I'm upgrading a Mule 1.3 application to Mule 3.2.1 (the latest version). The Mule 1.3 config file has a "model" element with a number of "mule-descriptor" sub-elements.
<model name="theModel">
<mule-descriptor name="theName" implementation="com.company.SomeClass">
<inbound-router>
<endpoint address="servlet://service/foo" transformers="ACustomTransformer" responseTransformers="AnotherCustomTransformer" />
<endpoint address="vm://anEndpoint"/>
</inbound-router>
<outbound-router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="Authenticator">
<properties>
<property name="propName" value="propValue" />
</properties>
</endpoint>
<filter expression="/data = null" className="org.mule.routing.filters.xml.JXPathFilter" />
</router>
<router className="org.mule.routing.outbound.OutboundPassThroughRouter">
<endpoint address="RequestValidator" />
</router>
</outbound-router>
<properties>
<property name="someProp" value="someValue" />
</properties>
</mule-descriptor>
<!-- more <mule-descriptor> elements -->
</model>
How do I convert this to its Mule 3 equivalent? Thanks.
1) Some mule-descriptors have inbound-routers that point to themselves.
<mule-descriptor name="theName" implementation="com.company.SomeClass">
<inbound-router>
<endpoint address="theName" />
</inbound-router>
</mule-descriptor>
How should these be converted to Mule 3 flows? When I convert these to flows using the information in your answer, I get an error message on startup, which seems to say that it can't reference the flow because it's still being created (like a circular dependency):
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ref:RequestValidator.20': Cannot resolve reference to bean 'RequestValidator' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RequestValidator': Cannot create inner bean '(inner bean)' of type [org.mule.config.spring.factories.InboundEndpointFactoryBean] while setting bean property 'messageSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': 1 constructor arguments specified but no matching constructor found in bean '(inner bean)' (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
2) One mule-descriptor uses the BridgeComponent
class from the Mule API as its implementation. How should these be handled? This class does not exist in Mule 3.
<mule-descriptor name="theName" implementation="org.mule.components.simple.BridgeComponent">
<inbound-router>
<endpoint address="vm://theInboundAddress" />
</inbound-router>
<outbound-router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="vm://theOutboundAddress" />
</router>
</outbound-router>
</mule-descriptor>
3) Another mule-descriptor has a "matchAll" attribute in its <outbound-router>
element. How should this be converted to a Mule 3 flow?
<mule-descriptor name="theName" implementation="com.company.SomeClass">
<inbound-router>
<endpoint address="servlet://theInboundEndpoint" />
</inbound-router>
<outbound-router matchAll="true">
<router className="org.mule.routing.outbound.OutboundPassThroughRouter">
<endpoint address="firstOutboundEndpoint" />
</router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter" transformer="MyTransformer">
<endpoint address="vm://secondOutboundEndpoint" />
<filter pattern="Error*" className="org.mule.routing.filters.WildcardFilter" />
</router>
</outbound-router>
</mule-descriptor>
4) The Mule 1.x config has a handful of <endpoint-identifier>
elements with names that are identical to the names of some of the <mule-descriptor>
elements. These names are also used as endpoint addresses in the <mule-descriptor>
. For example:
<endpoint-identifiers>
<endpoint-identifier name="TheEndpointName" value="vm://theEndpointAddress" />
</endpoint-identifiers>
...
<model name="...">
<mule-descriptor name="TheEndpointName" implementation="...">
<inbound-router>
<endpoint address="TheEndpointName" />
</inbound-router>
...
</mule-descriptor>
...
</model>
My guess is that the Mule 3 equivalent should look like the code below. Is this correct?
<flow name="TheEndpointName">
<!--
My first guess was:
<inbound-endpoint ref="TheEndpointName" />
-->
<vm:inbound-endpoint path="theEndpointAddress" />
...
</flow>
Thank you again.
5) Some mule-descriptors use the RestServiceWrapper
class from the Mule API. When I convert this to a Mule 3 <flow>
, I get this error:
The required object/property 'serviceUrl' is null
I noticed that the mule-descriptor in the Mule 1.x config sets a property called "urlFromMessage", which seems to say that, instead of the URL being provided in the XML config file, it will be provided as a property to the Mule message. However, the "urlFromMessage" property does not exist in Mule 3's version of the RestServiceWrapper
class. Should I be using a different component class in Mule 3? Since this class is part of the Mule API, is there a standard XML tag that I should use instead? Thanks.
<mule-descriptor name="theName" implementation="org.mule.components.rest.RestServiceWrapper">
<inbound-router>
...
</inbound-router>
<properties>
<property name="urlFromMessage" value="true" />
</properties>
</mule-descriptor>
Upvotes: 2
Views: 1167
Reputation: 33413
model
has been deprecated.flow
has replaced mule-descriptor
And many more, look at your config converted for Mule 3:
<flow name="theName">
<composite-source>
<vm:inbound-endpoint path="anEndpoint">
<transformer ref="ACustomTransformer" />
<response>
<transformer ref="AnotherCustomTransformer" />
</response>
</vm:inbound-endpoint>
<servlet:inbound-endpoint path="/service/foo" />
</composite-source>
<component>
<singleton-object class="com.company.SomeClass">
<property key="someProp" value="someValue" />
</singleton-object>
</component>
<outbound-endpoint ref="Authenticator">
<expression-filter expression="/data = null"
evaluator="jxpath" />
<property key="propName" value="propValue" />
</outbound-endpoint>
<outbound-endpoint ref="RequestValidator" />
</flow>
NB: This config is valid for Mule 3.2.1 but I can't guarantee it does exactly what you want, you have to test and tweak it!
More answers:
1) Use a different name for flows and endpoints, they are now registered as individual beans behind the scene and thus can't share the same names. That gives:
<flow name="theFlowName">
<inbound-endpoint ref="theInboundName" />
<component>
<singleton-object class="com.company.SomeClass" />
</component>
</flow>
2) Use the Bridge pattern:
<pattern:bridge name="theName"
inboundAddress="vm://theInboundAddress"
outboundAddress="vm://theOutboundAddress" />
3) Use the all
routing message processor and use processor-chain
to group several message processors as one:
<flow name="theName">
<servlet:inbound-endpoint path="/theInboundEndpoint" />
<component>
<singleton-object class="com.company.SomeClass" />
</component>
<all>
<outbound-endpoint ref="firstOutboundEndpoint" />
<processor-chain>
<transformer ref="MyTransformer" />
<wildcard-filter pattern="Error*" />
<vm:outbound-endpoint path="secondOutboundEndpoint" />
</processor-chain>
</all>
</flow>
4) You can't declare global endpoints in flows and you need to use different names for endpoints and flows, so the actual Mule 3 config equivalent is:
<vm:endpoint name="TheEndpointName" path="theEndpointAddress" />
<flow name="TheFlowName">
<inbound-endpoint ref="TheEndpointName" />
<component>
<singleton-object class="..." />
</component>
</flow>
5) Most Mule default components are now available as XML elements, so indeed you need to use:
<http:rest-service-component serviceUrl="..." />
urlFromMessage
is gone: instead you can use a Mule expression to extract the URL from the in-flight message in a dynamic manner. For example, if the URL is provided in an inbound property named svcURL
use:
<http:rest-service-component serviceUrl="#[header:INBOUND:svcURL]" />
Upvotes: 4