Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: How I can define a dynamic channels for int:router's "method" referenced

  1. #1
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default How I can define a dynamic channels for int:router's "method" referenced

    Hello Guys

    I have the follow

    Code:
    <int:router id="router"
    		input-channel="inicio"		
    	        apply-sequence="true"
    		resolution-required="true" 
    		default-output-channel="noTypeMatchChannel"
    		method="metodoRouter01"
    		ref="myRouterSinAnnotationUno"
    	/>
    where the Java code is

    Code:
    public String metodoRouter01(Message<?> message){
    		
    	logger.info(".... message: {}", message);
    		
    	if(message.getPayload() instanceof String)
    		return "stringChannel";
    	else if(message.getPayload() instanceof Integer)
    		return "integerChannel";
    	else if(message.getPayload() instanceof ItemArticulo)
    		return "instrumentoMusicalChannel";
    	else
    		return null;
    }
    I am checking each payload type to return the name of the channel. Since I use a String return type for the method used by the Router.

    I could declared a static String[] type instead to get later a desired item through an index for each if/elseif scope to do the same approach

    My problem is when I try to do the same with MessageChannel I mean, I must have the follow (code located in other class)

    Code:
    private DirectChannel stringChannel;
    private DirectChannel integerChannel;
    private DirectChannel instrumentoMusicalChannel;
    	
    @Value("#{stringChannel}")
    public void setStringChannel(DirectChannel stringChannel) {
    	this.stringChannel = stringChannel;
    }
    
    @Value("#{integerChannel}")
    public void setIntegerChannel(DirectChannel integerChannel) {
    	this.integerChannel = integerChannel;
    }
    
    @Value("#{instrumentoMusicalChannel}")
    public void setInstrumentoMusicalChannel(DirectChannel instrumentoMusicalChannel) {
    	this.instrumentoMusicalChannel = instrumentoMusicalChannel;
    }
    
    public MessageChannel metodoRouter01(Message<?> message){
    		
    	logger.info("... message: {}", message);
    					
    	if(message.getPayload() instanceof String){
    		return stringChannel; 
    	}
    	else if(message.getPayload() instanceof Integer){			
    		return integerChannel;			
    	}
    	else if(message.getPayload() instanceof ItemArticulo){			
    		return instrumentoMusicalChannel;			
    	}
            else
    	        return null;
    }
    The code work fine, but I must declare each channel like a variable, it could be painful if my flow integration has 10 - 15 channels, exists a way to only declare for example just one

    Code:
    private DirectChannel directChannel;
    	
    public void setDirectChannel(DirectChannel directChannel) {
    	this.directChannel = directChannel;
    }
    and in the if scope in someway just then indicate explicitly which Channel must be returned?

    Code:
    if(message.getPayload() instanceof String){
            //something to do get from my flow integration the stringChannel element
    	return directChannel; 
    }
    Thanks in advanced
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  2. #2
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    Why aren't you using <intayload-type-router> with <mapping>?

  3. #3
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    Hello Oleg


    Why aren't you using <intayload-type-router> with <mapping>?
    I did and work fine

    I am working with this approach only to test the part of Configuring a Router with Annotations where appear the follow snippet code

    Code:
    @Router
    public MessageChannel route(Message message) {...}
    
    @Router
    public List<MessageChannel> route(Message message) {...}
    
    @Router
    public String route(Foo payload) {...}
    
    @Router
    public List<String> route(Foo payload) {...}
    Since I am not calling some Service class, therefore I am doing explicitly this fake resolution like I shown on my first post

    I hope you see my point
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  4. #4
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    Well if you doing it in code than you are essentially doing the same thing we do. In other words your if/else is an equivalent of <mapping>. Internally we use ChannelResolver strategy (BeanFactoryChannelResolver) but it does the same thing. I guess I am missing the question.

  5. #5
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    Hello Oleg

    Well if you doing it in code than you are essentially doing the same thing we do. In other words your if/else is an equivalent of <mapping>. Internally we use ChannelResolver strategy (BeanFactoryChannelResolver) but it does the same thing
    Yes, totally agree, I am just testing the other options available, of course with mapping is more cleaner but with int:router I could do about calling a method to later decide the output channel, I mean

    Code:
    public String metodoRouter01(Message<?> message){
    		
    	String x = this.someServiceBo(...);
    		
    	if(x....)
    		return "xxx";
    	else
    		return "yyy";
    }
    I guess I am missing the question.
    Yes

    I have


    Code:
    private DirectChannel stringChannel;
    private DirectChannel integerChannel;
    private DirectChannel instrumentoMusicalChannel;
    	
    @Value("#{stringChannel}")
    public void setStringChannel(DirectChannel stringChannel) {
    	this.stringChannel = stringChannel;
    }
    
    @Value("#{integerChannel}")
    public void setIntegerChannel(DirectChannel integerChannel) {
    	this.integerChannel = integerChannel;
    }
    
    @Value("#{instrumentoMusicalChannel}")
    public void setInstrumentoMusicalChannel(DirectChannel instrumentoMusicalChannel) {
    	this.instrumentoMusicalChannel = instrumentoMusicalChannel;
    }
    I must declare each channel like a variable, it could be painful if my flow integration has 10 - 15 channels, I want to know if exists a way to only declare for example just only one variable

    Code:
    private DirectChannel directChannel;
    	
    public void setDirectChannel(DirectChannel directChannel) {
    	this.directChannel = directChannel;
    }
    and latter in the if scope in someway just then indicate explicitly which Channel must assigned and returned?

    Code:
          String result = this.someServiceBo(...);
    
           if(result ....){
                 //something to do here 
                 //to get from my flow integration the abcChannel element reference
                 //and assign to directChannel    
    	     return directChannel; 
           else if(result ...){
                 //something to do here 
                 //to get from my flow integration the xyzChannel element reference
                 //and assign to directChannel    
    	     return directChannel; 
           }
           ...
    }
    I edited the code above how a new version to avoid confuse with <intayload-type-router> with <mapping> behavior like you did, sorry for the confusion

    Practically the directChannel is unware about which Channel it must represent by itself until the code enter to some if/else if an then there, this directChannel is assigned to the some desired channel from the flow integration, in this way I avoid to declare 4 or 10 different DirectChannels

    Thank you
    Last edited by dr_pompeii; Aug 23rd, 2011 at 11:49 AM.
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  6. #6
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,040

    Default

    Code:
    	@Autowired
    	Map<String, MessageChannel> channels;
    For each entry in the map, the key is the bean name, the value is the channel.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  7. #7
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    Hello Gary

    Thanks for the reply

    I am working with this router and these channels

    Code:
    <int:channel id="dvdChannel" />	
    <int:channel id="instrumentoMusicalChannel" />
    ...
    <int:router id="router"
    		input-channel="inicio"		
    	        apply-sequence="true"
    		resolution-required="true" 
    		default-output-channel="noTypeMatchChannel"
    		method="metodoRouter01"
    		ref="myRouterConAnnotationUno"
    />
    I am little confused about your code
    Code:
    @Autowired
    Map<String, MessageChannel> channels;
    For each entry in the map, the key is the bean name, the value is the channel.

    With your approach Should I define a stand alone map collection in my flow integration file referring these channels?, Am I right?, or What did you do mean?

    Thank you
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  8. #8
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,040

    Default

    I was simply answering this question...

    I must declare each channel like a variable, it could be painful if my flow integration has 10 - 15 channels, I want to know if exists a way to only declare for example just only one variable
    You an use a map to get all the channels, mapped by their names. When your code decides which channel name to send to, simply lookup the map.

    Code:
    return channels.get("xyzChannel");
    The point is, though, it's much easier to use the form of router that returns a channel name, not a MessageChannel object; as Oleg said, the framework will do the same thing and resolve the name to a channel.

    Again, the general idea is not to tie your code (router or anything) to the framework. There is no need for your Router to know about channels (Direct or otherwise); just use names.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  9. #9
    Join Date
    Aug 2006
    Location
    Arequipa-Peru / South America
    Posts
    2,796

    Default

    Hello Gary

    Thanks again for your time and help

    You an use a map to get all the channels, mapped by their names. When your code decides which channel name to send to, simply lookup the map.
    I am totally agree, but is necessary create something like <util:map id="channels">
    to let my class work in peace with

    Code:
    	@Autowired
    	Map<String, MessageChannel> channels;
    The point is, though, it's much easier to use the form of router that returns a channel name, not a MessageChannel object; as Oleg said, the framework will do the same thing and resolve the name to a channel.
    I am agree with you, but I am just testing the other options to learn well the correct configuration and the most appropiate

    Again, the general idea is not to tie your code (router or anything) to the framework. There is no need for your Router to know
    Like my previous last sentence

    Thanks a lot for your time
    - Manuel Jordan

    Kill Your Pride, Share Your Knowledge With All
    The Fear Of The LORD Is The Beginning Of Knowledge, But Fools Despise Wisdom And Discipline. Proverbs 1:7

    Blog


    Technical Reviewer of Apress

    • Pro SpringSource dm Server
    • Spring Enterprise Recipes: A Problem-Solution Approach
    • Spring Recipes: A Problem-Solution Approach, 2nd Edition
    • Pro Spring Integration
    • Pro Spring Batch
    • Pro Spring 3
    • Pro Spring MVC: With Web Flow
    • Pro Spring Security

  10. #10
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,040

    Default

    is [ it ] necessary create something like <util:map id="channels">
    No, spring will collect up all beans of that type in the context and create a Map for you and inject it here. It is the same as calling applicationContext.getBeansOfType(SomeType.class), which returns a Map<String,SomeType>.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •