Announcement Announcement Module
Collapse
No announcement yet.
Programmatically invoking si:inbound-channel-adapter (SourcePollingChannelAdapter) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Programmatically invoking si:inbound-channel-adapter (SourcePollingChannelAdapter)

    Hi,

    I have this:

    <inbound-channel-adapter id="myAdapter" ref="someBean" method="getSomething" channel="someChannel" >
    <poller>
    <interval-trigger interval="12345" time-unit="SECONDS"/>
    </poller>
    </inbound-channel-adapter>

    This serves as a 'trigger' for some long process (someBean.getSomething() returns some data based on which a long execution begins.

    I want to initate the same process programmatically, reusing as much code as possible.
    I was hoping to find a context.getBean("myAdapter").poll(), but couldnt.

    Does SourcePollingChannelAdapter expose such capabilities?

    What's the best way to do something like this ?

    * I'm using 1.0.1

    10x,
    Ido

  • #2
    As part of SI 2.0 M1 we have a MessagePublisher which would allow you to invoke a method on any bean and have the result of such invocation be sent to a designated message channel:
    http://static.springsource.org/sprin...age-publishing
    Could you upgrade?

    Comment


    • #3
      Thanks, Oleg.

      Actually, upgrading to a milestone version is not that possible at the moment - we are nearing our deadline, and that could be problematic.

      Any other ideas, using 1.0.x ?

      Thanks again,
      Ido

      Comment


      • #4
        Why not just invoke someBean.getSomething? All the reuse that would miss there is code that is not in your repository anyway.

        Comment


        • #5
          because i would be losing logic that is found inside SourcePollingChannelAdapter, like polling more than once, etc.

          Comment


          • #6
            If you are able to upgrade to Spring 3.0, then you might want to look at the new "task" namespace and @Scheduled annotation support. In both cases, you can register a simple ref/method combination along with a "trigger" for scheduling (fixed-rate, fixed-delay, or cron). As of Spring Integration 2.0, that is the same basic mechanism used behind the scenes.

            If you still see limitations with that approach, let us know, since we are considering some form of event-driven triggering in 2.0. It would be great to get specific feedback on that requirement.

            Thanks,
            Mark

            Comment


            • #7
              Programmatically invoking si:inbound-channel-adapter

              Hey guys,

              I seem to be having an issue with the inbound-channel-adaptor. My setup is very basic. I've created a few classes and then an integration context file to wire it all together. The whole thing is just running in a main function that I threw together.

              I've tried to add a poller to my inbound-channel-adaptor, but my method never gets called. I also tried to invoke this method from the main function and it still does not pass along my message to the intended channel. I can see that it has gotten into the method due to the fact that it spits out a log message.

              I created a gateway to pass along the same object to the same channel and it works fine. Not sure at all what I'm doing wrong. I believe I've done everything properly. I'm using the latest spring and spring integration.

              Here's my integration context XML file:
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!--/*
              */
              -->
              
              <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:si="http://www.springframework.org/schema/integration"
                  xmlns:context="http://www.springframework.org/schema/context"
                  xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
                  ">
              
                  <beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                      <beans:property name="location" value="classpath:integrationsContext.properties"/>
                      <beans:property name="ignoreUnresolvablePlaceholders" value="true"/>
                  </beans:bean>
              
                  <si:channel id="vendorEventsIn"/>
                  <si:channel id="smsEventsIn"/>
                  <si:channel id="smsEventsOut"/>
                  <si:channel id="vendorEventsOut"/>
                  
                  <!-- need this? -->
                  <si:gateway id="eventGateway" default-request-channel="vendorEventsIn"
                              default-reply-channel="vendorEventsOut" service-interface="gateway.gateway.TestGateway" />
              
                  <si:inbound-channel-adapter ref="vendorHandler" method="checkForUpdates" channel="vendorEventsIn">
                      <si:poller>
                         <si:interval-trigger interval="1000"/>
                      </si:poller>
                  </si:inbound-channel-adapter>
              
                  <si:transformer input-channel="vendorEventsIn"
                      ref="vendorToSmsTransformer" method="transform" output-channel="smsEventsIn" />
              
              
                  <si:service-activator ref="smsWsClient" method="forwardSmsEvent" input-channel="smsEventsIn" output-channel="smsEventsOut"/>
                  
                  <si:transformer input-channel="smsEventsOut" ref="smsToVendorTransformer" 
                                  method="transform" output-channel="vendorEventsOut" />
                                  
              
                  <si:outbound-channel-adapter ref="vendorHandler" method="reply" channel="vendorEventsOut"/>
              
              
                  <beans:bean id="vendorHandler" class="gateway.vendor.TestVendorHandler" />
                  <beans:bean id="vendorToSmsTransformer" class="gateway.transformer.TestVendorToSmsTransformer" />
                  <beans:bean id="smsToVendorTransformer" class="gateway.transformer.TestSmsToVendorTransformer" />
                  <beans:bean id="smsWsClient" class="gateway.sms.SmsWsClient" />
              
              
                  <si:poller max-messages-per-poll="1" id="defaultPoller" default="true">
                      <si:interval-trigger interval="3000"/>
                  </si:poller>
              
              </beans:beans>
              Here's my method being called in the class:
              Code:
                  public Message<?> checkForEvents()
                  {
                      // TODO Auto-generated method stub
                      LOGGER.info("checking for events");
                      Message<?> response = null;
                      
                      TestEvent e = new TestEvent();
                      e.setId(1L);
                      
                      response = MessageBuilder.withPayload(e).build();
              
                      return response;
                  }
              I've also tried this with just the object I wanted to send along to the channel. Still, no luck.

              Finally, this is me trying to invoke the thing in my main class:
              Code:
              public static void main(String[] args)
              {
                      try
                      {
                          ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "integrationsContext.xml" });
              
                          appContext.start();
              
                          // works!!!!
                          //TestGateway tg = (TestGateway)appContext.getBean("eventGateway");
                          //tg.testIt(new TestEvent());
                          
                          // does not work 
                          TestVendorHandler tvh = (TestVendorHandler)appContext.getBean("vendorHandler");
                          tvh.checkForEvents();
                      }
                      catch (Throwable e)
                      {
                          LOGGER.info(ExceptionUtils.getFullStackTrace(e));
                      }
                  }
              Last edited by roadblocked; Jun 22nd, 2010, 10:30 AM.

              Comment


              • #8
                The inbound-channel-adapter is intended to be used as a scheduled, background polling mechanism. If you call that method yourself (like you do in the main() method), then it's just a normal method call on that object. In your configuration, however, you have a poller that should also be invoking that method in the background every 3 seconds and sending the return value (if not null) to the 'vendorEventsIn' channel.

                If you actually want a Message to be published as the by-product of a method call, then you should use our AOP interceptor *instead of* an inbound-channel-adapter. Read this for an overview: http://static.springsource.org/sprin...age-publishing

                Comment


                • #9
                  Mark,

                  My intent is to use the poller to call the channel adaptor, but I thought I had a problem so I tried to invoke it directly and see what happened there. I'm still not sure what to think about why that inbound-channel-adaptor wasn't working for me.

                  I'll check out the publishing section of the reference manual that you have provided. Looks like it may come in handy down the line.

                  Thanks for the fast reply.

                  Comment


                  • #10
                    One thing that might help is to temporarily add a wiretap for debugging purposes:
                    Code:
                    <channel id="processingChannel">
                        <interceptors>
                            <wiretap channel="wiretapChannel"/>
                        </interceptors>
                    </channel>
                    Probably the simplest thing is to use a logging-channel-adapter along with that:
                    Code:
                    <logging-channel-adapter id="wiretapChannel"/>

                    Comment


                    • #11
                      This is the strangest thing. Nothing has come across as a result of the wiretap

                      Comment


                      • #12
                        OK, I seem to be a bit confused but the problem has been resolved apparently. My original inbound channel adaptor was not working which was a mystery.

                        I made a new class that does the same exact work and I typed the <inbound-channel-adaptor> XML by hand instead of copying it from the spring reference guide. Works great. Not sure why, but I'll take it.

                        I can't imagine this will help anyone except now they'll know what I did to resolve the issue

                        Comment


                        • #13
                          Can you provide a before/after diff so that we can see if something stands out?

                          Thanks,
                          Mark

                          Comment


                          • #14
                            This example has both. The first inbound channel adaptor is not working but the one at the end is. I couldn't find anything wrong comparing one to another. It's in unix format and I couldn't find any special characters.


                            Code:
                            <?xml version="1.0" encoding="UTF-8"?>
                            <!--/*
                            */
                            -->
                            
                            <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xmlns="http://www.springframework.org/schema/integration"
                                xmlns:context="http://www.springframework.org/schema/context"
                                xsi:schemaLocation="http://www.springframework.org/schema/beans
                                http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                                http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
                                ">
                            
                                <beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                                    <beans:property name="location" value="classpath:integrationsContext.properties"/>
                                    <beans:property name="ignoreUnresolvablePlaceholders" value="true"/>
                                </beans:bean>
                            
                                <!-- need this? -->
                                <beans:import resource="servicesContext.xml"/>
                            
                                <channel id="vendorEventsIn">
                                    <interceptors>
                                        <wire-tap channel="wiretapChannel"/>
                                    </interceptors>
                                </channel>
                                <channel id="smsEventsIn"/>
                                <channel id="smsEventsOut"/>
                                <channel id="vendorEventsOut"/>
                                
                                <!-- need this? -->
                                <gateway id="eventGateway" default-request-channel="vendorEventsIn"
                                            default-reply-channel="vendorEventsOut" service-interface="gateway.gateway.TestGateway" />
                            
                                <!-- override this in actual gateway implementation -->
                                <!-- for third-party CA -->
                                <inbound-channel-adapter ref="vendorHandler" method="checkForUpdates" channel="vendorEventsIn">
                                    <poller>
                                       <interval-trigger interval="1000"/>
                                    </poller>
                                </inbound-channel-adapter>
                            
                                <transformer input-channel="vendorEventsIn"
                                    ref="vendorToSmsTransformer" method="transform" output-channel="smsEventsIn" />
                            
                                <!-- For SMS SA -->
                                <service-activator ref="smsWsClient" method="forwardSmsEvent" input-channel="smsEventsIn" output-channel="smsEventsOut"/>
                                
                                <transformer input-channel="smsEventsOut" ref="smsToVendorTransformer" 
                                                method="transform" output-channel="vendorEventsOut" />
                                                
                                <!-- for third-party CA -->
                                <!-- outbound-channel-adapter ref="vendorHandler" method="reply" channel="vendorEventsOut"/-->
                            
                                <beans:bean id="vendorHandler" class="gateway.vendor.TestVendorHandler" />
                                <beans:bean id="vendorToSmsTransformer" class="gateway.transformer.TestVendorToSmsTransformer" />
                                <beans:bean id="smsToVendorTransformer" class="gateway.transformer.TestSmsToVendorTransformer" />
                                <beans:bean id="smsWsClient" class="gateway.sms.SmsWsClient" />
                            
                                <!--  consider keeping an eye on the default spring integration errorChannel with some channel adaptor -->
                            
                                <poller max-messages-per-poll="1" id="defaultPoller" default="true">
                                    <interval-trigger interval="3000"/>
                                </poller>
                            
                            
                            	<channel id="processingChannel">
                            	    <interceptors>
                            	        <wire-tap channel="wiretapChannel"/>
                            	    </interceptors>
                            	</channel>
                                <logging-channel-adapter id="wiretapChannel" level="DEBUG" log-full-message="true"/>
                                
                                <!-- test -->
                                <inbound-channel-adapter ref="testClass" method="sendIt" channel="smsEventsIn">
                                    <poller>
                                        <interval-trigger interval="2000"/>
                                    </poller>
                                </inbound-channel-adapter>
                                
                                <beans:bean id="testClass" class="gateway.QuickTest" />
                            
                            </beans:beans>

                            Comment

                            Working...
                            X