简体   繁体   中英

Converting Mule 1.3 “model” element to Mule 3 equivalent

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.


EDIT - 5/29/2012

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.

EDIT 5/30/2012

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>
  • 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]" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM