Announcement Announcement Module
Collapse
No announcement yet.
Router without annotation Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Router without annotation

    Hi,

    I just discovered spring integration this week and use a fresh build version from the svn trunk.

    Now I'm trying to figure it out how to use a router without annotation, like the org.springframework.integration.router.RecipientLi stRouter, in an xml configuration file

    Thank you for your help !

  • #2
    something I tried:

    Inbound & outboun channels :

    Code:
    <file:inbound-channel-adapter id="inputChannel" directory="file:C:/input">
      <poller>
        <interval-trigger interval="1000" />
      </poller>
    </file:inbound-channel-adapter>
    
    <file:outbound-channel-adapter id="outputChannel" directory="C:/output" />
    Router :

    Code:
    <router ref="recipientListRouter" input-channel="inputChannel"/>
    The class org.springframework.integration.router.RecipientLi stRouter have a property "List<MessageChannel> channels", so I wrote

    Code:
    <beans:bean id="recipientListRouter"
    	class="org.springframework.integration.router.RecipientListRouter">
      <beans:property name="channels">
        <beans:list>
          <beans:ref bean="outputChannel" />
        </beans:list>
      </beans:property>
    </beans:bean>
    and here comes trouble :

    if I try <beans:ref local="outputChannel" /> I have the exception :

    Caused by: org.xml.sax.SAXParseException: cvc-id.1: There is no ID/IDREF binding for IDREF 'outputChannel'.

    and if I try <beans:ref bean="outputChannel" /> :

    org.springframework.beans.factory.UnsatisfiedDepen dencyException:
    Error creating bean with name 'org.springframework.integration.router.MethodInvo kingRouter#0':
    Unsatisfied dependency expressed through constructor argument with index 1 of type [java.lang.String]:
    Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?

    Comment


    • #3
      The problem with the "local" ref is that the "id" for channel-adapter is used to create a channel instance but is not an XMLID type. Although, in hindsight, I think the overloaded use of "id" on channel-adapter is confusing. We should require the "channel" attribute instead. A "local" ref would still not work since the channel attribute's value may either be a new channel name or a channel reference to some other bean (and if that bean were defined like <channel id="whatever"/>, then it could be an XMLID). Nevertheless, I am really second guessing the auto-creation-if-not-defined approach altogether.

      The second problem is that the <router/> parser always creates a MethodInvokingRouter - and its constructor requires an object reference AND a methodName. We need to modify this in the same way that we did for <splitter/> so that the parser detects whether the ref is already a subclass of AbstractMessageRouter. Can you please open a JIRA issue for this?

      In the meantime, you can skip <router/> and instead create a bean of type: SubscribingConsumerEndpoint or PollingConsumerEndpoint depending on the input channel type (SubscribableChannel or PollableChannel respectively).

      Comment


      • #4
        Thanks for your reply

        I let you open that JIRA issue because I'm enough familiar with JIRA and not a native english writer, I think you'll be more able to precisely describe this issue.

        As I really need a kind of router with multiple output channels, I don't think SubscribingConsumerEndpoint is what I need (otherwise I missed something), so I wrote my own class MyRecipientListRouter

        Code:
        public class MyRecipientListRouter {
        
        	private List<String> channels;
        
        	public void setChannels(List<String> channels) {
        		this.channels = channels;
        	}
        	
        	public List<String> route( File file ){
        		return channels; 
        	}
        }
        And with this xml config file :

        Code:
        <message-bus />
        
        <file:inbound-channel-adapter id="inputChannel" directory="file:C:/input">
        	<poller>
        		<interval-trigger interval="1000" />
        	</poller>
        </file:inbound-channel-adapter>
        
        <file:outbound-channel-adapter id="outputChannel"
        	directory="C:/output" />
        	
        <file:outbound-channel-adapter id="anotherOutputChannel"
        	directory="C:/anotherOutput" />
        
        <router ref="myRecipientListRouter" input-channel="inputChannel" method="route"/>
        
        <beans:bean id="myRecipientListRouter"
        	class="test.MyRecipientListRouter">
        	<beans:property name="channels">
        		<beans:list>
        			<beans:value>outputChannel</beans:value>
        			<beans:value>anotherOutputChannel</beans:value>
        		</beans:list>
        	</beans:property>
        </beans:bean>
        thats works, but if there is a better way to do that feel free to share

        Comment


        • #5
          I opened these JIRA issues - both are relevant to this discussion - especially the latter:
          http://jira.springframework.org/browse/INT-433
          http://jira.springframework.org/browse/INT-434

          Comment


          • #6
            Both of the above issues are now resolved. Please try using Spring Integration's PayloadTypeRouter, and provide its bean name for the "ref" value in a <router/> element.

            You can see some working examples from the test cases included in this commit log:
            https://fisheye.springframework.org/...ration?cs=1515

            Comment


            • #7
              Thanks a lot !

              So, with yesterday's trunk build those two examples works perfectly :

              Common part :

              Code:
              <message-bus />
              
              <file:inbound-channel-adapter id="inputChannel" directory="file:C:/input">
                <poller>
                  <interval-trigger interval="1000" />
                </poller>
              </file:inbound-channel-adapter>
              
              <file:outbound-channel-adapter id="outputChannel" directory="C:/output" />
              
              <file:outbound-channel-adapter id="anotherOutputChannel"
              	directory="C:/anotherOutput" />
              RecipientListRouter :

              Code:
              <router ref="recipientListRouter" input-channel="inputChannel"/>
              
              <beans:bean id="recipientListRouter"
              	class="org.springframework.integration.router.RecipientListRouter">
                <beans:property name="channels">
                  <beans:list>
                    <beans:ref bean="outputChannel" />
                    <beans:ref bean="anotherOutputChannel" />
                  </beans:list>
                </beans:property>
              </beans:bean>
              PayloadTypeRouter :

              Code:
              <router ref="payloadTypeRouter" input-channel="inputChannel"/>
              
              <beans:bean id="payloadTypeRouter"
              	class="org.springframework.integration.router.PayloadTypeRouter">
                <beans:property name="payloadTypeChannelMap">
                  <beans:map>
                    <beans:entry key="java.io.File" value-ref="outputChannel" />
                    <beans:entry key="java.lang.String" value-ref="anotherOutputChannel" />
                  </beans:map>
                </beans:property>
              </beans:bean>

              Comment

              Working...
              X