Announcement Announcement Module
Collapse
No announcement yet.
Dynamic Queue Name for Inbound adapter Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynamic Queue Name for Inbound adapter

    Hi,

    I have the below configuration:

    Code:
    	<bean id="tibcoJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    		<property name="environment">
    			<props>
    				<prop key="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</prop>
    				<prop key="java.naming.provider.url">tibco server:port</prop>
    				<prop key="java.naming.security.principal">
    					uid
    					</prop>
    				<prop key="java.naming.security.credentials">
    					pwd
    					</prop>
    			</props>
    		</property>
    	</bean>
    
    
    	<bean id="tibcoJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiTemplate" ref="tibcoJndiTemplate" />
    		<property name="jndiName" value="QueueConnectionFactory">
    		</property>
    	</bean>
    
    	<bean id="tibcoAuthenticationConnectionFactory"
    		class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    		<property name="targetConnectionFactory" ref="tibcoJmsQueueConnectionFactory" />
    		<property name="username" value="uid" />
    		<property name="password" value="pwd" />
    	</bean>
    
    	<bean id="tibcoInboundSendDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiTemplate" ref="tibcoJndiTemplate" />
    		<property name="jndiName" value="QUEUE.NAME" />
    	</bean>
        <si-jms:message-driven-channel-adapter
    		id="tibcoInboundAdapter" destination="tibcoInboundSendDestination"
    		connection-factory="tibcoAuthenticationConnectionFactory"
    		error-channel="exceptionChannel" channel="newOrderXMLInput"
    		concurrent-consumers="5" />
    In this I want to change the "QUEUE.NAME" to "QUEUE.OUTBOUND.NAME" during runtime so that the adapter listens to the new queue name instead of the old.

    How to achieve this?

  • #2
    That's a pretty unusual requirement. You can't dynamically change the queue without stopping the adapter first, and you'd have to use a custom DestinationResolver to change the destination on the fly because the destination is wired into the listener container; you could define an external container by reference, which would allow you to change the queue without needing a custom DestinationResolver.

    You might find it easier to simply add 2 channel adapters, each one listening on a different queue (and both sending to newOrderXMLInput). Set auto-startup to false on one or both of them and start/stop them either by calling the Lifecycle methods directly, or sending messages to a <control-bus/> ("@tibcoInboundAdapter.start()").

    Comment


    • #3
      Try to investigate JndiDestinationResolver with destination JNDI name within external JmsListeningContainer bean

      HTH,
      Artem

      Comment


      • #4
        Hi,

        Thanks for your insights in this. But the problem is I dont know how many queues I have to listen. So i'm trying to do something like this:

        Code:
        <bean id="tibcoInboundAdapter" scope="prototype" class="org.springframework.integration.jms.JmsMessageDrivenEndpoint">
        		<constructor-arg name="listener" ref="listener"/>
        		<constructor-arg name="listenerContainer" ref="listenerContainer"/>
        	</bean>
        	<bean id="listener" scope="prototype" class="org.springframework.integration.jms.ChannelPublishingJmsMessageListener">
        		<property name="errorChannel" ref="exceptionChannel"/>
        		<property name="requestChannel" ref="newOrderXMLInput"/>
        	</bean>
        	<bean id="listenerContainer" scope="prototype" class="org.springframework.jms.listener.AbstractMessageListenerContainer">
        		<property name="connectionFactory" ref="tibcoAuthenticationConnectionFactory"/>
        		<property name="destination" ref="tibcoInboundSendDestination"/>
        	</bean>
        
        <bean id="tibcoInboundSendDestination" scope="prototype class="my.custom.JNDI.object.factory.bean">
        		<constructor-arg name="jndiTemplate" ref="tibcoJndiTemplate" />
        		<constructor-arg name="jndiName" value="Queue.Name" />
        	</bean>
        the tibcoInboundSendDestination will have a configuration inside which will read from a property file during runtime. I believe all the configurations are in order but when I start the application, the application is not listening to the JMS queue like an adapter.

        What am I doing wrong here?
        Please help I'm struck with this for 3 days now.

        Comment


        • #5
          Hi!

          1. There is no reason to configure all as regular beans. You can simply reference to listenerContainer from <si-jms:message-driven-channel-adapter>
          2. listenerContainer should be concrate instance, not Abstract.
          3. This is what I suggest:
          HTML Code:
          <jms:message-driven-channel-adapter channel="fooChannel" container="listenerContainer"/>
          
          <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
          	<property name="destinationResolver">
          		<bean class="org.springframework.jms.support.destination.JndiDestinationResolver">
          			<property name="cache" value="false"/>
          			<property name="jndiEnvironment" ref="jndiEnvironment"/>
          		</bean>
          	</property>
          	<property name="destinationName" value="FOO"/>
          </bean>
          So, you always can change "destinationName" property value at runtime. But here you should how to play with other properties of DefaultMessageListenerContainer, to allow AsyncMessageListenerInvoker reconfiguration for new destination...

          Comment


          • #6
            Originally posted by Cleric View Post
            Hi!
            HTML Code:
            <jms:message-driven-channel-adapter channel="fooChannel" container="listenerContainer"/>
            
            <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
            	<property name="destinationResolver">
            		<bean class="org.springframework.jms.support.destination.JndiDestinationResolver">
            			<property name="cache" value="false"/>
            			<property name="jndiEnvironment" ref="jndiEnvironment"/>
            		</bean>
            	</property>
            	<property name="destinationName" value="FOO"/>
            </bean>
            So here the destinationName is the jndiName(Queue Name)?

            Comment


            • #7
              So here the destinationName is the jndiName(Queue Name)?
              Yes.

              But you should read more source code of mentioned classes, because your use-case isn't tipical.
              Maybe it will be necessary to play with DirectFieldAccessor on DefaultMessageListenerContainer...

              Comment


              • #8
                Originally posted by Cleric View Post
                Yes.

                But you should read more source code of mentioned classes, because your use-case isn't tipical.
                Maybe it will be necessary to play with DirectFieldAccessor on DefaultMessageListenerContainer...
                Thanks. Now I was able to dynamically change the destinationName but the adapter is still listening to the old queue name.
                This is the configuration I'm using.
                Code:
                <si-jms:message-driven-channel-adapter
                		id="tibcoInboundAdapter" container="listenerContainer"
                		error-channel="exceptionChannel" channel="newOrderXMLInput"/>
                	<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
                		<property name="destinationResolver">
                			<bean class="org.springframework.jms.support.destination.JndiDestinationResolver">
                			<property name="cache" value="false"/>
                			<property name="jndiTemplate" ref="tibcoJndiTemplate"/>
                		</bean>
                		</property>
                		<property name="connectionFactory" ref="tibcoAuthenticationConnectionFactory"/>
                		<property name="destinationName" value="INITIAL>QUEUE"/>
                	</bean>
                
                <JAVA>
                DefaultMessageListenerContainer listenerContainer = (DefaultMessageListenerContainer)SpringApplicationContext.getBean("listenerContainer");
                listenerContainer.setDestinationName("NEW.QUEUE");
                </JAVA>

                Comment

                Working...
                X