Bridging between HTTP endpoints

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Bridging between HTTP endpoints

Jеns Riеmschneidеɾ
Hi,

in Camel 1.x you could write a simple HTTP bridge like this:

         CamelContext camelContext = new DefaultCamelContext();
         camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("jetty:http://localhost:8435/path1").to("http://localhost:8435/path2");
                from("jetty:http://localhost:8435/path2").transform().constant("OK");
            }
         });
         camelContext.start();
         
         ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
         InputStream result = (InputStream) producerTemplate.requestBody("http://localhost:8435/path1", "Hello");
         assertEquals("OK", IOUtils.toString(result));

in Camel 2.0 this doesn't work anymore because the Exchange.HTTP_URI and Exchange.HTTP_PATH are set by the consumer that received the initial request. The HttpProducer that is called because of the to() then "thinks" those header properties were set to define the actual destination and sends the data to "/path1/path1", which leads to an error. You have to explicitly remove those properties from the exchange to make it work:

                from("jetty:http://localhost:8435/path1")
                    .removeHeader(Exchange.HTTP_URI)
                    .removeHeader(Exchange.HTTP_PATH)
                    .to("http://localhost:8435/path2");

I can't think of any use for this behavior and it is rather surprising. However, I understand that it might be a side effect that we have to live with because the header property names are now shared between the endpoints. Anyway, is this the way it is supposed to work now or is it worth to submit a bug report for this? Are there any other properties that should be removed to ensure that the to() really sends it to the destination it is supposed to?

Thanks,
Jens
Reply | Threaded
Open this post in threaded view
|

Re: Bridging between HTTP endpoints

Willem.Jiang
Administrator
That's because other components in Camel 2.0 will use the
Exchange.HTTP_URI and Exchange.HTTP_PATH to do some work.

Maybe we can add an option in http endpoint to ignore these two headers
if you still want to use the HTTP bridge as Camel 1.x.

Willem
_Jens wrote:

> Hi,
>
> in Camel 1.x you could write a simple HTTP bridge like this:
>
>          CamelContext camelContext = new DefaultCamelContext();
>          camelContext.addRoutes(new RouteBuilder() {
>             @Override
>             public void configure() throws Exception {
>                
> from("jetty:http://localhost:8435/path1").to("http://localhost:8435/path2");
>                
> from("jetty:http://localhost:8435/path2").transform().constant("OK");
>             }
>          });
>          camelContext.start();
>          
>          ProducerTemplate producerTemplate =
> camelContext.createProducerTemplate();
>          InputStream result = (InputStream)
> producerTemplate.requestBody("http://localhost:8435/path1", "Hello");
>          assertEquals("OK", IOUtils.toString(result));
>
> in Camel 2.0 this doesn't work anymore because the Exchange.HTTP_URI and
> Exchange.HTTP_PATH are set by the consumer that received the initial
> request. The HttpProducer that is called because of the to() then "thinks"
> those header properties were set to define the actual destination and sends
> the data to "/path1/path1", which leads to an error. You have to explicitly
> remove those properties from the exchange to make it work:
>
>                 from("jetty:http://localhost:8435/path1")
>                     .removeHeader(Exchange.HTTP_URI)
>                     .removeHeader(Exchange.HTTP_PATH)
>                     .to("http://localhost:8435/path2");
>
> I can't think of any use for this behavior and it is rather surprising.
> However, I understand that it might be a side effect that we have to live
> with because the header property names are now shared between the endpoints.
> Anyway, is this the way it is supposed to work now or is it worth to submit
> a bug report for this? Are there any other properties that should be removed
> to ensure that the to() really sends it to the destination it is supposed
> to?
>
> Thanks,
> Jens

Reply | Threaded
Open this post in threaded view
|

Re: Bridging between HTTP endpoints

Jеns Riеmschneidеɾ
Thinking a little bit more about this. Maybe this is just a special case for header filtering strategies. In this case it seems a bit strange, because you explicitly specify the endpoint address in the to() call. However, this is the similar to the case where you want to send a message to an HTTP endpoint with a dynamic address. Thjen you must specify a "dummy" endpoint address. E.g.:

    .setHeader(Exchange.HTTP_URI) ...
    .to("http://dummyUri")

I guess it would be less of an issue, if one would have to clearly state in the to() that this is a dynamic endpoint URI. Something like .to("http") to only define the component and the endpoint URI gets looked up from a header. That way the dummy wouldn't be needed and the case with the bridge would run as well, because the to() clearly refers to a fully qualified endpoint address. However, it's nothing I absolutely require, I can live with removing the headers.

Jens


willem.jiang wrote
That's because other components in Camel 2.0 will use the
Exchange.HTTP_URI and Exchange.HTTP_PATH to do some work.

Maybe we can add an option in http endpoint to ignore these two headers
if you still want to use the HTTP bridge as Camel 1.x.

Willem
Reply | Threaded
Open this post in threaded view
|

Re: Bridging between HTTP endpoints

Claus Ibsen-2
In reply to this post by Willem.Jiang
On Fri, Aug 7, 2009 at 1:25 PM, Willem Jiang<[hidden email]> wrote:
> That's because other components in Camel 2.0 will use the Exchange.HTTP_URI
> and Exchange.HTTP_PATH to do some work.
>
> Maybe we can add an option in http endpoint to ignore these two headers if
> you still want to use the HTTP bridge as Camel 1.x.
>

Yeah it could make sense to have a boolean option that will force it
to only use the static URI defined on the endpoint.
As messages could come from many different sources that are HTTP based
and thus would have a "dynamic" URI header.


> Willem
> _Jens wrote:
>>
>> Hi,
>>
>> in Camel 1.x you could write a simple HTTP bridge like this:
>>
>>         CamelContext camelContext = new DefaultCamelContext();
>>         camelContext.addRoutes(new RouteBuilder() {
>>            @Override
>>            public void configure() throws Exception {
>>
>> from("jetty:http://localhost:8435/path1").to("http://localhost:8435/path2");
>>
>> from("jetty:http://localhost:8435/path2").transform().constant("OK");
>>            }
>>         });
>>         camelContext.start();
>>                 ProducerTemplate producerTemplate =
>> camelContext.createProducerTemplate();
>>         InputStream result = (InputStream)
>> producerTemplate.requestBody("http://localhost:8435/path1", "Hello");
>>         assertEquals("OK", IOUtils.toString(result));
>>
>> in Camel 2.0 this doesn't work anymore because the Exchange.HTTP_URI and
>> Exchange.HTTP_PATH are set by the consumer that received the initial
>> request. The HttpProducer that is called because of the to() then "thinks"
>> those header properties were set to define the actual destination and
>> sends
>> the data to "/path1/path1", which leads to an error. You have to
>> explicitly
>> remove those properties from the exchange to make it work:
>>
>>                from("jetty:http://localhost:8435/path1")
>>                    .removeHeader(Exchange.HTTP_URI)
>>                    .removeHeader(Exchange.HTTP_PATH)
>>                    .to("http://localhost:8435/path2");
>>
>> I can't think of any use for this behavior and it is rather surprising.
>> However, I understand that it might be a side effect that we have to live
>> with because the header property names are now shared between the
>> endpoints.
>> Anyway, is this the way it is supposed to work now or is it worth to
>> submit
>> a bug report for this? Are there any other properties that should be
>> removed
>> to ensure that the to() really sends it to the destination it is supposed
>> to?
>>
>> Thanks,
>> Jens
>
>



--
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus
Reply | Threaded
Open this post in threaded view
|

Re: Bridging between HTTP endpoints

Claus Ibsen-2
Hi

You actually also needs to add ?throwExceptionOnFailure=false to the
HTTP endpoint to be able return the various error codes as is.
In case eg the HTTP returns a http error 301 and you want it to be
returned as it to jetty.

PS: We should probably look into letting Jetty "understand"
HttpOperationFailedException and fetch the error code and error
message from it directly.



On Fri, Aug 7, 2009 at 3:27 PM, Claus Ibsen<[hidden email]> wrote:

> On Fri, Aug 7, 2009 at 1:25 PM, Willem Jiang<[hidden email]> wrote:
>> That's because other components in Camel 2.0 will use the Exchange.HTTP_URI
>> and Exchange.HTTP_PATH to do some work.
>>
>> Maybe we can add an option in http endpoint to ignore these two headers if
>> you still want to use the HTTP bridge as Camel 1.x.
>>
>
> Yeah it could make sense to have a boolean option that will force it
> to only use the static URI defined on the endpoint.
> As messages could come from many different sources that are HTTP based
> and thus would have a "dynamic" URI header.
>
>
>> Willem
>> _Jens wrote:
>>>
>>> Hi,
>>>
>>> in Camel 1.x you could write a simple HTTP bridge like this:
>>>
>>>         CamelContext camelContext = new DefaultCamelContext();
>>>         camelContext.addRoutes(new RouteBuilder() {
>>>            @Override
>>>            public void configure() throws Exception {
>>>
>>> from("jetty:http://localhost:8435/path1").to("http://localhost:8435/path2");
>>>
>>> from("jetty:http://localhost:8435/path2").transform().constant("OK");
>>>            }
>>>         });
>>>         camelContext.start();
>>>                 ProducerTemplate producerTemplate =
>>> camelContext.createProducerTemplate();
>>>         InputStream result = (InputStream)
>>> producerTemplate.requestBody("http://localhost:8435/path1", "Hello");
>>>         assertEquals("OK", IOUtils.toString(result));
>>>
>>> in Camel 2.0 this doesn't work anymore because the Exchange.HTTP_URI and
>>> Exchange.HTTP_PATH are set by the consumer that received the initial
>>> request. The HttpProducer that is called because of the to() then "thinks"
>>> those header properties were set to define the actual destination and
>>> sends
>>> the data to "/path1/path1", which leads to an error. You have to
>>> explicitly
>>> remove those properties from the exchange to make it work:
>>>
>>>                from("jetty:http://localhost:8435/path1")
>>>                    .removeHeader(Exchange.HTTP_URI)
>>>                    .removeHeader(Exchange.HTTP_PATH)
>>>                    .to("http://localhost:8435/path2");
>>>
>>> I can't think of any use for this behavior and it is rather surprising.
>>> However, I understand that it might be a side effect that we have to live
>>> with because the header property names are now shared between the
>>> endpoints.
>>> Anyway, is this the way it is supposed to work now or is it worth to
>>> submit
>>> a bug report for this? Are there any other properties that should be
>>> removed
>>> to ensure that the to() really sends it to the destination it is supposed
>>> to?
>>>
>>> Thanks,
>>> Jens
>>
>>
>
>
>
> --
> Claus Ibsen
> Apache Camel Committer
>
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> Twitter: http://twitter.com/davsclaus
>



--
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus