Announcement Announcement Module
Collapse
No announcement yet.
http outbound gateway Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • http outbound gateway

    Hi,
    i have the below mentioned configuration
    <int:chain input-channel="c1" id="chain1">
    <int:header-enricher>
    <int:header name="Accept" value="application/xml"/>
    <int:header name="Content-Type" value="application/xml"/>
    </int:header-enricher>
    <int-http:outbound-gateway url="${serviceURL}a/b" http-method="POST" expected-response-type="com.m.a.X" />
    </int:chain>

    This keeps on failing even though i have a PropertyPlaceholderConfigurer with the url in the properties file.


    Caused by: java.lang.IllegalArgumentException: Map has no value for 'serviceURL'
    at org.springframework.web.util.UriComponents$MapTemp lateVariables.getValue(UriComponents.java:251)
    at org.springframework.web.util.UriComponents.expandU riComponent(UriComponents.java:188)
    at org.springframework.web.util.HierarchicalUriCompon ents$FullPathComponent.expand(HierarchicalUriCompo nents.java:662)
    at org.springframework.web.util.HierarchicalUriCompon ents.expandInternal(HierarchicalUriComponents.java :314)
    at org.springframework.web.util.HierarchicalUriCompon ents.expandInternal(HierarchicalUriComponents.java :44)
    at org.springframework.web.util.UriComponents.expand( UriComponents.java:154)
    at org.springframework.web.util.UriTemplate.expand(Ur iTemplate.java:101)
    at org.springframework.web.client.RestTemplate.execut e(RestTemplate.java:454)
    at org.springframework.web.client.RestTemplate.exchan ge(RestTemplate.java:402)
    at org.springframework.integration.http.outbound.Http RequestExecutingMessageHandler.handleRequestMessag e(HttpRequestExecutingMessageHandler.java:351)


    Can you help?

  • #2
    Hi!

    In general I don't understand what's going on. I've just tested it and it works well:
    HTML Code:
    <context:property-placeholder properties-ref="configProperties"/>
    
    	<util:properties id="configProperties">
    		<beans:prop key="serviceURL">http://localhost:51235/</beans:prop>
    	</util:properties>
    
    	<beans:bean id="restTemplate" class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandlerTests$MockRestTemplate2"/>
    
    	<si:chain input-channel="httpOutboundGatewayWithinChain" output-channel="replyChannel">
    		<outbound-gateway url="${serviceURL}testApps/httpOutboundGatewayWithinChain"
    						  rest-template="restTemplate"
    						  expected-response-type="java.lang.String"/>
    	</si:chain>
    I get similar Exception only if I remove '$' from 'url' attribute...
    So, please, review your config and try to figure out what is wrong.

    Take care,
    Artem

    Comment


    • #3
      Turn on DEBUG logging for org.springframework - it emits copious logging for property placeholder handling.
      Searching for key 'foo' in ...
      Found key 'foo' in ...

      Comment


      • #4
        If there is no avaliable property within property-placeholder we get a message:
        Could not resolve placeholder 'serviceURL' in string value "${serviceURL}testApps/httpOutboundGatewayWithinChain"
        IMO: it's wrong config

        Comment


        • #5
          Could not resolve placeholder ...
          Unless you set ignore-unresolvable="true" on the PPC, in which case, a missing property will cause the reported error when an attempt to resolve it as a <uri-variable/> is made.

          With DEBUG logging, you'll see

          Could not find key 'foo' in any property source. Returning [null]
          (BTW, as an aside - not related to this question - this would be required when using uri-variables).

          Comment


          • #6
            here is my complete xml...

            Code:
            beans.xml
            <beans
               default-lazy-init="false">
                
                <bean id="queuePropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                    <property name="location" value="file:${catalina.home}/conf/serviceurls.properties"/>
                    <property name="ignoreUnresolvablePlaceholders" value="true"/>
                </bean>
                
            	<import resource="beans-packorder.xml"/>
                
                <int:message-history/>
                
            </beans>
            
            
            beans-packorder.xml
            
            
            <?xml version="1.0" encoding="UTF-8"?>
            
            <beans
               default-lazy-init="false">  
                <int:channel id="httpRequestChannel"/>
                <int:channel id="httpReplyChannel"/>
                <int:channel id="packOrderProcessingChannel"/>
                <int:channel id="packReleaseChannel" />
                <int:channel id="pushReleaseLMSChannel" />
                <int:channel id="packReleaseWMSChannel" />
                <int:channel id="packReleasePortalChannel" />
                <int:channel id="packReleaseChannelTOQ" />
                <int:channel id="packReleaseChannelOUT" />
                
                <bean id="releaseMessageStoreForPackOrder" class="org.springframework.integration.store.SimpleMessageStore" />
                
                <bean id="packReleaseTransformer" class="PackReleaseTransformer" />
                <bean id="releaseTransformerForWms" class="PackReleaseTransformerForWms" />
                <bean id="releaseTransformerForPortal" class="PackReleaseTransformerForPortal" />
                <bean id="releaseTransformerForLms" class="PackReleaseTransformerForLms" />
                
                <int-http:inbound-gateway id="packRelease" request-channel="httpRequestChannel" reply-channel="httpReplyChannel" supported-methods="GET,POST" 
                    path="/markReleasePacked/{releaseId}" error-channel="errorChannel">
                    <int-http:header name="releaseId" expression="#pathVariables.releaseId"/>
                </int-http:inbound-gateway>
                
                <int:chain id="packOrderChain" input-channel="httpRequestChannel">
                    <int:service-activator ref="loggingActivator" method="handleMessage" />     
                    <int:header-enricher>
                         <int:header name="Accept" value="application/xml"/>
                         <int:header name="Content-Type" value="application/xml"/>
                    </int:header-enricher>
                    <int-http:outbound-gateway url="${wmsURL}platform/items/search?q=orderId.eq:{releaseId}" expected-response-type="com.myntra.client.wms.response.ItemResponse" http-method="GET">
                        <int-http:uri-variable name="releaseId" expression="headers[releaseId]"/>
                    </int-http:outbound-gateway>
                    
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    
                    <int-http:outbound-gateway url="${omsURL}oms/orderrelease/validateReleaseForPacking/{releaseId}" http-method="POST" expected-response-type="OrderReleaseResponse">
                        <int-http:uri-variable name="releaseId" expression="headers[releaseId]"/>
                    </int-http:outbound-gateway>
                    
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    
                    <int:router expression="payload.status.statusType" default-output-channel="errorChannel">
                        <int:mapping value="SUCCESS" channel="packOrderProcessingChannel"/>
                        <int:mapping value="ERROR" channel="errorChannel"/>
                    </int:router>
                </int:chain>
                
                <int:recipient-list-router ignore-send-failures="true" input-channel="packOrderProcessingChannel">
                        <int:recipient channel="packReleaseChannel"/>
                        <int:recipient channel="packReleaseLMSChannel"/>
                        <int:recipient channel="packReleaseWMSChannel"/>
                        <int:recipient channel="packReleasePortalChannel"/>
                    </int:recipient-list-router>
                
                <int:chain id="packReleaseChain" input-channel="packReleaseChannel">
                    <int:claim-check-in message-store="releaseMessageStoreForPackOrder"/>
                    <int:header-enricher>
                      <int:header name="PACK_RELEASE_CLAIM_CHECK_ID" expression="payload"/>
                    </int:header-enricher>
                    <int:claim-check-out message-store="releaseMessageStoreForPackOrder" />
                    <int:service-activator ref="loggingActivator" method="handleMessage" /> 
                    <int:transformer ref="packReleaseTransformer" method="doTransform"/>
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <int:recipient-list-router ignore-send-failures="true">
                        <int:recipient channel="packReleaseChannelTOQ"/>
                        <int:recipient channel="packReleaseChannelOUT"/>
                    </int:recipient-list-router>
                </int:chain>
                
                <int:chain id="packReleaseTOQChain" input-channel="packReleaseChannelTOQ">
            	    <int:transformer ref="marshallingTransformer" method="doTransform" />    
            	    <amqp:outbound-channel-adapter amqp-template="rabbitTemplate" routing-key="orderEvents">
            	        <amqp:request-handler-advice-chain>
            	            <ref bean="retryAdvice"/>            
            	        </amqp:request-handler-advice-chain>
            	    </amqp:outbound-channel-adapter>
                </int:chain>
                
                <int:chain id="packReleaseOUTChain" input-channel="packReleaseChannelOUT" output-channel="httpReplyChannel">
                    <int:transformer expression="headers[PACK_RELEASE_CLAIM_CHECK_ID]"/>
                    <int:claim-check-out message-store="releaseMessageStoreForPackOrder" remove-message="true"/>
                </int:chain>
                
                <int:chain input-channel="packReleaseLMSChannel">
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <int:transformer ref="releaseTransformerForLms" method="doTransform"/>
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <amqp:outbound-channel-adapter amqp-template="rabbitTemplate" routing-key="packReleaseQueueLMS" exchange-name="oms">
                        <amqp:request-handler-advice-chain>
                            <ref bean="retryAdvice"/>            
                        </amqp:request-handler-advice-chain>
                    </amqp:outbound-channel-adapter>
                </int:chain>
                
                <int:chain input-channel="packReleaseWMSChannel">
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <int:transformer ref="releaseTransformerForWms" method="doTransform"/>
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <amqp:outbound-channel-adapter amqp-template="rabbitTemplate" routing-key="packReleaseQueueWMS" exchange-name="oms">
                        <amqp:request-handler-advice-chain>
                            <ref bean="retryAdvice"/>            
                        </amqp:request-handler-advice-chain>
                    </amqp:outbound-channel-adapter>
                </int:chain>
                
                <int:chain input-channel="packReleasePortalChannel">
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <int:transformer ref="releaseTransformerForPortal" method="doTransform"/>
                    <int:service-activator ref="loggingActivator" method="handleMessage" />
                    <amqp:outbound-channel-adapter amqp-template="rabbitTemplate" routing-key="packReleaseQueuePortal" exchange-name="oms">
                        <amqp:request-handler-advice-chain>
                            <ref bean="retryAdvice"/>            
                        </amqp:request-handler-advice-chain>
                    </amqp:outbound-channel-adapter>
                </int:chain>
                
                <!-- below section is to get message from queue and hit lms/wms -->
                <int:channel id="packReleaseLMSChannelFromQueue" />
                <int:channel id="packReleaseWMSChannelFromQueue" />
                <int:channel id="packReleasePortalChannelFromQueue" />
                
                <amqp:inbound-channel-adapter channel="packReleasePortalChannelFromQueue" queue-names="packReleaseQueuePortal" connection-factory="rabbitConnectionFactory" advice-chain="retryAdvice" concurrent-consumers="10"/>
                <int:chain input-channel="packReleasePortalChannelFromQueue" id="portalchain">
                    <int:header-enricher>
                         <int:header name="Accept" value="application/xml"/>
                         <int:header name="Content-Type" value="application/xml"/>
                    </int:header-enricher>
                    <int-http:outbound-gateway url="${portalURL}/RequestHandler.php" http-method="POST" expected-response-type="com.myntra.client.portal.response.PortalCommonResponse">
                        <int-http:uri-variable name="releaseId" expression="1"/>
                    </int-http:outbound-gateway>
                </int:chain>
                
                <amqp:inbound-channel-adapter channel="packReleaseLMSChannelFromQueue" queue-names="packReleaseQueueLMS" connection-factory="rabbitConnectionFactory" advice-chain="retryAdvice" concurrent-consumers="10"/>
                <int:chain input-channel="packReleaseLMSChannelFromQueue" id="lmschain">
                    <int:header-enricher>
                         <int:header name="Accept" value="application/xml"/>
                         <int:header name="Content-Type" value="application/xml"/>
                    </int:header-enricher>
                    <int-http:outbound-gateway url="${lmsURL}order/{service}" http-method="POST" expected-response-type="com.myntra.lms.client.response.OrderResponse">
                        <int-http:uri-variable name="service" expression="'bulkCreateOrUpdate'"/>
                    </int-http:outbound-gateway>
                </int:chain>
              
                <amqp:inbound-channel-adapter channel="packReleaseWMSChannelFromQueue" queue-names="packReleaseQueueWMS" connection-factory="rabbitConnectionFactory" advice-chain="retryAdvice" concurrent-consumers="10"/>    
                <int:chain input-channel="packReleaseWMSChannelFromQueue" id="wmschain">
                    <int:header-enricher>
                         <int:header name="Accept" value="application/xml"/>
                         <int:header name="Content-Type" value="application/xml"/>
                    </int:header-enricher>
                    <int-http:outbound-gateway url="${wmsURL}platform/items/bulkupdate" http-method="POST" expected-response-type="com.myntra.oms.client.response.OrderReleaseResponse" />
                </int:chain>    
            </beans>
            the first two (items,validate) are working fine, but the ones in amqp inbound adapter chain are'nt. any idea?
            Last edited by Gary Russell; Mar 21st, 2013, 07:18 AM.

            Comment


            • #7
              As Gary said, remove this one:
              <property name="ignoreUnresolvablePlaceholders" value="true"/>
              and you'll see the message in the logs about your missed properties.

              Please, use [ CODE ] [ /CODE ] without whitespaces to show code: now it's very non-readable

              Comment


              • #8
                thanks for the response,
                is there a plan to have header mapper feature in amqp inbound/outbound channel adapters. can u give me an example?

                Comment


                • #9
                  H-m-m...
                  eader mapper feature in amqp inbound/outbound channel adapters
                  Not sure what do you mean...
                  http://static.springsource.org/sprin...mlsingle/#amqp
                  And, of course, if you are about HTTP:
                  http://static.springsource.org/sprin...mlsingle/#http
                  And try to find 'header-mapper' phrase

                  Comment


                  • #10
                    i tried this..

                    <amqp:outbound-channel-adapter channel="eventCreationChannelXML" amqp-template="rabbitTemplate" routing-key="eventCreationQueue" header-mapper="headerMapper"/>

                    <bean id="headerMapper" class="org.springframework.integration.http.suppor t.DefaultHttpHeaderMapper">
                    <property name="inboundHeaderNames" value="EVENT_NAME"/>
                    <property name="outboundHeaderNames" value="EVENT_NAME"/>
                    </bean>

                    but startup fails with the below exception..

                    Caused by: org.xml.sax.SAXParseException; lineNumber: 57; columnNumber: 161; cvc-complex-type.3.2.2: Attribute 'header-mapper' is not allowed to appear in element 'amqp:outbound-channel-adapter'.

                    Comment


                    • #11
                      my inbound adapter seems to be working..

                      <amqp:inbound-channel-adapter channel="orderEventsWithXmlPayLoad" queue-names="eventCreationQueue" connection-factory="rabbitConnectionFactory" header-mapper="headerMapper"/>

                      <bean id="headerMapper" class="org.springframework.integration.amqp.suppor t.DefaultAmqpHeaderMapper">
                      <property name="requestHeaderNames" value="EVENT_NAME"/>
                      <property name="replyHeaderNames" value="EVENT_NAME"/>
                      </bean>

                      but outbound adapter doesnt have support for headermapper..

                      how do i set that?

                      Comment


                      • #12
                        Ha!

                        Thanks, now I see.
                        You try to reference to the DefaultHttpHeaderMapper who is instance of HeaderMapper, but AMQP endpoints expect an instance of AmqpHeaderMapper.
                        So, raise, please a JIRA issue https://jira.springsource.org/browse/INT about wrong header-mapper attribute 'expected-type' in the AMQP XSD.
                        Try to use this one org.springframework.integration.amqp.support.Defau ltAmqpHeaderMapper for outbound too.

                        However I don't understand why you are observing similar Exception.
                        I've catched this:
                        Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.springframework.integration.http.support.Defau ltHttpHeaderMapper] to required type [org.springframework.integration.amqp.support.AmqpH eaderMapper] for property 'headerMapper': no matching editors or conversion strategy found
                        Which version of Spring Integration do you use? How about to switch to the latest 2.2.2 ?

                        Comment


                        • #13
                          thanks,
                          after i chang the mapper to amqpheadermapper, inbound channel adapter seems to be working, but i still have trouble getting the outboud adapter work.
                          do u have a sample config.

                          i am using 2.2.0.. lemme try 2.2.2

                          Comment


                          • #14
                            do u have a sample config.
                            HTML Code:
                            <bean id="headerMapper" class="org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper"/>
                            
                            <amqp:outbound-channel-adapter id="toRabbitOnlyWithTemplateChannel" amqp-template="amqpTemplateWithSuppliedExchangeAndRoutingKey"
                            			header-mapper="headerMapper"/>
                            Code:
                            		MessageChannel requestChannel = context.getBean("toRabbitOnlyWithTemplateChannel", MessageChannel.class);
                            		MessageHandler amqpOutboundEndpoint = context.getBean("toRabbitOnlyWithTemplateChannel.handler", MessageHandler.class);
                            		AmqpHeaderMapper headerMapper = TestUtils.getPropertyValue(amqpOutboundEndpoint, "headerMapper", AmqpHeaderMapper.class);
                            		assertSame(context.getBean("headerMapper"), headerMapper);
                            		requestChannel.send(MessageBuilder.withPayload("test").build());
                            Do you use versionless xsd refs in your config:
                            HTML Code:
                            xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
                            ?

                            Comment


                            • #15
                              JIRA is raised: https://jira.springsource.org/browse/INT-2971.
                              Will be fixed soon.

                              Comment

                              Working...
                              X