Spring Integration
  1. Spring Integration
  2. INT-2569

Refactor HttpOutboundGateway to mitigate breaking changes due to UriTemplate changes in Spring 3.1

    Details

    • Type: Task Task
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Won't Fix
    • Affects Version/s: 2.2 M1
    • Fix Version/s: 2.2 M2
    • Component/s: HTTP Support
    • Labels:
      None

      Description

      The following configuration no longer works with Spring 3.1

      <int-http:outbound-gateway url="{url}" request-channel="someChannelIn" reply-channel="someChannelOut"
      		expected-response-type="java.lang.String" http-method="GET">
      	<int-http:uri-variable name="url" expression="'http://www.google.com/finance/info?q=vmw'"/>
      </int-http:outbound-gateway>
      

      due to the changes that were made to UriTemplate
      After several discussions we decided that this would be too much of a breaking change, so a patch is possible in SI to avoid this.
      We also need to provide a proper support for dynamic URIs via something like a uri-expression attribute or simply allow SpEL Expression in the 'uri' attribute

        Issue Links

          Activity

          Show
          Oleg Zhurakousky added a comment - PR https://github.com/SpringSource/spring-integration/pull/448
          Hide
          Oleg Zhurakousky added a comment - - edited

          Just to add a few notes
          The root of the problem is that UriTemplate encodes existing uri then replaces uri variables. This means that if you had configuration like this (which woud work with previous versions of Spring) it will no longer work

          <int-http:outbound-gateway url="{url}" request-channel="vmwChannel" reply-channel="replyChannel"
          				expected-response-type="java.lang.String" http-method="GET">
          	<int-http:uri-variable name="url" expression="'http://www.google.com/finance/info?q=vmw'"/>
          </int-http:outbound-gateway>
          

          since '?' will be encoded and the resulting URL will be something like this: http%3A%2F%2Fwww.google.com%2Ffinance%2Finfo%3Fq%3Dvmw

          To mitigate this and still allow full or partial URL replacement we've introduced a new attribute on the uri-variable subelement. The attribute name is 'encode' which is a boolean and its default value is 'true'
          However to make the above example work all you need to do is set it to 'false'

          <int-http:outbound-gateway url="{url}" request-channel="vmwChannel" reply-channel="replyChannel"
          				expected-response-type="java.lang.String" http-method="GET">
          	<int-http:uri-variable name="url" expression="'http://www.google.com/finance/info?q=vmw'" encode="false"/>
          </int-http:outbound-gateway>
          

          This way the placeholder substitution is going to be performed outside of UriTemplate and will not be encoded.

          Show
          Oleg Zhurakousky added a comment - - edited Just to add a few notes The root of the problem is that UriTemplate encodes existing uri then replaces uri variables. This means that if you had configuration like this (which woud work with previous versions of Spring) it will no longer work < int -http:outbound-gateway url= "{url}" request-channel= "vmwChannel" reply-channel= "replyChannel" expected-response-type= "java.lang. String " http-method= "GET" > < int -http:uri-variable name= "url" expression= "'http: //www.google.com/finance/info?q=vmw'" /> </ int -http:outbound-gateway> since '?' will be encoded and the resulting URL will be something like this: http%3A%2F%2Fwww.google.com%2Ffinance%2Finfo%3Fq%3Dvmw To mitigate this and still allow full or partial URL replacement we've introduced a new attribute on the uri-variable subelement. The attribute name is 'encode' which is a boolean and its default value is 'true' However to make the above example work all you need to do is set it to 'false' < int -http:outbound-gateway url= "{url}" request-channel= "vmwChannel" reply-channel= "replyChannel" expected-response-type= "java.lang. String " http-method= "GET" > < int -http:uri-variable name= "url" expression= "'http: //www.google.com/finance/info?q=vmw'" encode= " false " /> </ int -http:outbound-gateway> This way the placeholder substitution is going to be performed outside of UriTemplate and will not be encoded.
          Hide
          Rossen Stoyanchev added a comment - - edited

          SPR-8662 has a good overview of why the UriTemplate and UriUtils were effectively replaced by (or at least internally they delegate to) UriComponentsBuilder and UriComponents. SPR-8403 and SPR-8918 provide further examples of the kinds of issues that could not be resolved otherwise.

          That said I don't think the use of a single URI variable to make up the entire URI should be encouraged. Typically URI variables replace some part of the URI (path, query param, etc.) and since the different parts of a URI are encoded differently it makes it possible to encode them correctly.

          To ensure a dynamic URI template I think a uri-expression property on outbound-gateway might work better. It would also allow for the dynamic URI expression to be a template with variables to substitute, which doesn't seem possible with the current approach.

          Show
          Rossen Stoyanchev added a comment - - edited SPR-8662 has a good overview of why the UriTemplate and UriUtils were effectively replaced by (or at least internally they delegate to) UriComponentsBuilder and UriComponents. SPR-8403 and SPR-8918 provide further examples of the kinds of issues that could not be resolved otherwise. That said I don't think the use of a single URI variable to make up the entire URI should be encouraged. Typically URI variables replace some part of the URI (path, query param, etc.) and since the different parts of a URI are encoded differently it makes it possible to encode them correctly. To ensure a dynamic URI template I think a uri-expression property on outbound-gateway might work better. It would also allow for the dynamic URI expression to be a template with variables to substitute, which doesn't seem possible with the current approach.
          Hide
          Oleg Zhurakousky added a comment -

          @Rossen
          That said I don't think the use of a single URI variable to make up the entire URI should be encouraged
          You absolutely right. As you read form the JIRA title its really about mitigating a breaking change that this will result in. However I already opened INT-2570 which taks about exactly that and that we would need a more formal way of providing URL dynamically.
          Thanks for the links

          Show
          Oleg Zhurakousky added a comment - @Rossen That said I don't think the use of a single URI variable to make up the entire URI should be encouraged You absolutely right. As you read form the JIRA title its really about mitigating a breaking change that this will result in. However I already opened INT-2570 which taks about exactly that and that we would need a more formal way of providing URL dynamically. Thanks for the links
          Hide
          Oleg Zhurakousky added a comment -

          After several discussions the decision was made that introducing a new attribute just to mitigate a breaking change is still a patch so INT-2570 addressed the issue the right way and we just need to explain in documentation the full story

          Show
          Oleg Zhurakousky added a comment - After several discussions the decision was made that introducing a new attribute just to mitigate a breaking change is still a patch so INT-2570 addressed the issue the right way and we just need to explain in documentation the full story

            People

            • Assignee:
              Oleg Zhurakousky
              Reporter:
              Oleg Zhurakousky
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: