Results 1 to 7 of 7

Thread: Configuring activator with channels within chain

  1. #1
    Join Date
    Jul 2009
    Location
    Charlotte, NC
    Posts
    131

    Default Configuring activator with channels within chain

    Can someone help me explaining why this doesn't work:
    Code:
    <chain input-channel="xxxxRequestChannelMQ"
    		output-channel="xxxxResponseRouterChannel">
    		<service-activator ref="someRequestActivator"
    			method="transformPayload" output-channel="preMQSendChannel"/>
    		<service-activator ref="jmsSender" method="send" input-channel="preMQSendChannel"/>
    		<service-activator ref="jmsReceiver" method="receive" />
    	</chain>
    But this does:
    Code:
    <chain input-channel="xxxxRequestChannelMQ"
    		output-channel="xxxxResponseRouterChannel">
    		<service-activator ref="someRequestActivator"
    			method="transformPayload"/>
    		<service-activator ref="jmsSender" method="send"/>
    		<service-activator ref="jmsReceiver" method="receive" />
    	</chain>
    In the former case, I am getting this in the logs:
    Code:
    java.lang.IllegalStateException: Cannot convert value of type [org.springframework.integration.endpoint.EventDrivenConsumer] to required type [org.springframework.integration.message.MessageHandler] for property 'handlers[1]': no matching editors or conversion strategy found
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:291)
    	at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:580)
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:233)
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:155)
    	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:461)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1363)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1322)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:563)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:872)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
    	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
    	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
    Am I missing something ?

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

    Default

    Well first of all you should not be specifying input or output channel on any endpoints within the chain.
    If you were using M6 build where we actually fixed the schema to explicitly disallow that you would get and exception . . .Caused by: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'output-channel' is not allowed to appear in element 'int:service-activator'.

    So what version of SI are you using and why do you have an output-channel defined in the first service-activator in the chain?

  3. #3
    Join Date
    Jul 2009
    Location
    Charlotte, NC
    Posts
    131

    Default

    I am using 1.0.4 Release

    Basically, I want the complete SI message after the first activator is done executing, and I want to put it on preMQSendChannel and start some background process asynchronously. For that purpose, I have put a wiretap on preMQSendChannel to some other tempChannel, and finally a threadpooltaskexecutor dispatcher which does the background process.

    I can break the chain, and write the activators with individual in/out channels, but I was hoping to achieve this within the chain itself.

    So, is there any other way other than moving activators out of chain?

    Also, any reason why this shouldn't be allowed within the chain?

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

    Default

    No and for your case breaking it out of chain would be the better solution.
    There is a pattern called Composed Message Processor. Chain is really a variation of this pattern. It allows you to compose an endpoint from multiple endpoints, but once assembled (composed) you should look and treat the chain as a single component with its input and (output).

  5. #5
    Join Date
    Jul 2009
    Location
    Charlotte, NC
    Posts
    131

    Default

    Thanks Oleg, makes better sense now...

    But here is my use case: This strategy is a part of global transaction management, including many SI channels.
    I need to audit requests from every channel which is considered part of the transaction boundary for a particular operation. In case of any failures, there is another background process, which will read the stored audit logs, and do the roll back.

    Now I have a lot of chains, routers, individual activators etc in every operation. This activity of breaking chains would result in at least double the number of named SI channels, which I was using till now. Not a cleaner approach...
    Last edited by GPS; Aug 25th, 2010 at 07:48 PM.

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

    Default

    Well, think about what I said with regards to chains. Chain is an endpoint which is no different then service-activator or router or filter. But you are not asking to get access to the call-flow of method calls of any of those endpoints. Instead you are naturally treating is as a black box because its is,.. its a black box is given to you by the framework with few parameters exposed for custom configuration. Chain on the other hand is a value-add approach given to you by the framework to assemble your own black box based on a collection of smaller black boxes, but once assembled. . . it will become a single endpoint that is no different then router or filter with single input and (output).

    Let me make another analogy.
    private inner class. . .
    You could have many arguments why you needed it in the first place in your particular case, but. . . you don't expect someone questioning your decisions about making it private, especially when there is an alternative, clean approach to expose its functionality publicly.

  7. #7
    Join Date
    Jul 2009
    Location
    Charlotte, NC
    Posts
    131

    Default

    Cannot agree more.... Chain should indeed be a black box...
    It's just that I don't like writing extra code...
    Thanks for the clarification!

Posting Permissions

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