You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by "James Strachan (JIRA)" <ji...@apache.org> on 2008/02/13 11:31:35 UTC

[jira] Resolved: (CAMEL-334) endpoints implementing Service do not get stopped

     [ https://issues.apache.org/activemq/browse/CAMEL-334?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

James Strachan resolved CAMEL-334.
----------------------------------

    Resolution: Fixed

patch applied!

> endpoints implementing Service do not get stopped
> -------------------------------------------------
>
>                 Key: CAMEL-334
>                 URL: https://issues.apache.org/activemq/browse/CAMEL-334
>             Project: Apache Camel
>          Issue Type: Bug
>            Reporter: James Strachan
>             Fix For: 1.3.0
>
>


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Re: Where is it best to remove a message transport header that breaks a response?

Posted by James Strachan <ja...@gmail.com>.
On 13/02/2008, Tully, Gary <Ga...@iona.com> wrote:
>
> Consider a http request response route:
>
> from("jetty:http://localhost:8088/someService").unmarshal().string().pro
> cess(
>            new Processor() {
>              public void process(Exchange e) {
>                    String input = (String) e.getIn().getBody();
>                 e.getOut().setBody(input + outputText);
>              }
>            });
>
>
> Currently, the unmarshaller copies the input message to the output
> message and augments it. The copy brings with it all of the http
> headers.
> The result is that Content-Length from the request ends in the reply.
> This breaks the http response[1].

BTW we've had similar issues with JMS for example.

from("activemq:SomeQueue").to("anyjms:Something");

here there is only an IN message; its one way (InOnly) messaging - but
even for this apparently simple use case, we can't just pass all the
headers from the JMS message out when sending JMS messages.

This is because a number of the JMS properties are not allowed to be
specified by a sender (but are fine for a consumer).

e.g. see the populateIgnoreJmsHeaders() method at the bottom of this
binding class for the JMS headers we filter out...

https://svn.apache.org/repos/asf/activemq/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsBinding.java

Am kinda thinking - each transport binding should filter out stuff it
knows is gonna break?


> I am thinking that it never makes sense to copy a Content-Length header
> from a HttpMessage but it would be wrong to remove it.

someone inside the route might wanna know about that header later on.
So having headers available on the IN message so folks can route based
on them is a good thing.  Sending them on again blindly over HTTP is
not so good though :)


> I am thinking that there should be a strategy for copying headers.
>
> The Message.copyFrom() can call getCopyHeaders() which can in turn call
> a strategy method pruneCopyHeaders() which for a HttpMessage override
> can remove the Content-Length header.

Thats a possibility; my worry is there are cases where the HTTP IN
ends up being passed to some other exchange which isn't of type
HttpExchange/HttpMessage so this logic gets lost.

Am wondering if the best place to filter them out is right before they
are really sent out over HTTP - otherwise we kinda wanna keep those
headers around so folks can read them.

Having said that; maybe we just need some way to kinda read headers
from previous exchanges (to avoid actually copying headers) but thats
maybe more wacky...


> Is this overkill or are there other cases where request headers just do
> not make sense in a reply?

Am sure there's quite a few. JMS is a definite case - am sure there
are others - mail?

-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://open.iona.com

Re: Where is it best to remove a message transport header that breaks a response?

Posted by Roman Kalukiewicz <ro...@gmail.com>.
2008/2/14, Gary Tully <ga...@gmail.com>:
>  >  I don't think it is caused by unmarshaller really. Basically it is the
>  >  behaviour of pipeline to copy the result of the pipeline (either in or
>  >  out message) into out message of original exchange. I write it without
>  >  looking at the code, so it could be wrong ;)
>  >
>
> the pipeline copies from out to in or from in to in if there is no
>  out. But it does no create an out message. So in this case
>
>
>  from("jetty:http://localhost:8088/someService")
>
>                 .process(new Processor() {
>
>                  public void process(Exchange e) {
>
>                     e.getOut().setBody(outputText);
>                 }});
>  the out is created by the processor and no headers are copied and it
>  works just fine.
>  With the unmarshaller, it makes a copy from in to out and then resets
>  the body with the contents of the unmarshall. My first attempt to
>  reproduce without an unmarshaller failed because of this :-)

This comes back a little to my in/out/fault discussion, but in fact
pipeline creates out message on original exchange at the very end of
pipeline to produce final result of processing.

If you use only one processor after the endpoint it is not wrapped by
pipeline and if it doesn't produce out, then there is no out. Buf if
you have 2 or more elements in your flow, then pipeline is silently
created and at the very end of its processing it creates out message
that goes back to the endpoint. It is not really consistent and was
one of my arguments to change it (or wrap everything with pipeline
silently ;) )

>  >  I don't think we want to remove any header by default. If I don't see
>  >  a header I assume that there was no such header. If there is
>  >  Content-Length, then it should be in the message.
>  >
>
> I am not sure, after a transformation, say a deserialisation, the
>  Content-Length is meaningless. I am thinking that it is only relevant
>  to the consumer of the HTTPMessage.
>  It has no business in the out message the results from a transformation.

You are definitelly right here. It looks that Content-Length is
meaningless after we have done something with the input stream we
received. But we cannot simply say that it is the first processor
after the endpoint, because there is no reason we should prefer:

from("jetty:http://localhost:1234/test").setHeader("length",
header("Content-Length").setHeader("body", body(String));

over

from("jetty:http://localhost:1234/test").setHeader("body",
body(String)).setHeader("length", header("Content-Length");

>  I like the idea that a particular message type can control how its
>  headers are replicated. Producers of messages then just send on what
>  they get, incompatible headers, or headers that are related only to
>  the initial receipt of the messages are stripped out at source. As in
>  the existing JMS producer case, the set of headers to strip could be
>  configured.

Maybe it is a matter of taste, but I don't like the idea of
disappearing headers in the flow. I believe, that headers (as a
concept) should have strict rule that they propagate always. What can
change it is processor that explicitly manipulates them, and they are
lost when new message is created. Moreover they should be used as
protocol specific properties (like headers in http, or properties in
JMS) always except cases, when it is more probable that they were
propagated 'by mistake' than that they were set explicitly.

>  This does beg the question about access to the original
>  message/exchange for the case that a downstream processor does want to
>  see the original Content-Length, but I can't imagine why!

For example just to log all the headers that I received from HTTP. We
cannot drop them before, because they are not dangerous *unless*
someone tries to use them on some specific kind of the endpoint.

> There is a lot of value in consistency. The simplest solution is to
>  add a remove to the http binding before we produce a response.
>  My only problem with this is that if a processor intentionally added
>  the Content-Length to an out message we would ignore it.

I believe that such situation (as exceptional I think) could be
controlled by parameter on the endpoint like

from("jetty:http://localhost:1234/test?skipDangerousHeaders=false")

but I really don't think someone would use it ;)

Roman

Re: Where is it best to remove a message transport header that breaks a response?

Posted by Gary Tully <ga...@gmail.com>.
On 13/02/2008, Roman Kalukiewicz <ro...@gmail.com> wrote:
> 2008/2/13, Tully, Gary <Ga...@iona.com>:
>  > Currently, the unmarshaller copies the input message to the output
>  > message and augments it. The copy brings with it all of the http
>  > headers.
>  > The result is that Content-Length from the request ends in the reply.
>  > This breaks the http response[1].
>
>  I don't think it is caused by unmarshaller really. Basically it is the
>  behaviour of pipeline to copy the result of the pipeline (either in or
>  out message) into out message of original exchange. I write it without
>  looking at the code, so it could be wrong ;)
>
the pipeline copies from out to in or from in to in if there is no
out. But it does no create an out message. So in this case

from("jetty:http://localhost:8088/someService")
            	.process(new Processor() {
           	 public void process(Exchange e) {
            	    e.getOut().setBody(outputText);
                }});
the out is created by the processor and no headers are copied and it
works just fine.
With the unmarshaller, it makes a copy from in to out and then resets
the body with the contents of the unmarshall. My first attempt to
reproduce without an unmarshaller failed because of this :-)

>  > One solution is to add a .removeHeader("Content-Length") to the route
>  > but should that be necessary?
>  > the header really belongs with the in message.
>  >
>  > I am thinking that it never makes sense to copy a Content-Length header
>  > from a HttpMessage but it would be wrong to remove it.
>
>  I don't think we want to remove any header by default. If I don't see
>  a header I assume that there was no such header. If there is
>  Content-Length, then it should be in the message.
>
I am not sure, after a transformation, say a deserialisation, the
Content-Length is meaningless. I am thinking that it is only relevant
to the consumer of the HTTPMessage.
It has no business in the out message the results from a transformation.

I like the idea that a particular message type can control how its
headers are replicated. Producers of messages then just send on what
they get, incompatible headers, or headers that are related only to
the initial receipt of the messages are stripped out at source. As in
the existing JMS producer case, the set of headers to strip could be
configured.

This does beg the question about access to the original
message/exchange for the case that a downstream processor does want to
see the original Content-Length, but I can't imagine why!

>  I would vote for the solution implemented in JMS case James mentioned
>  about. BTW it is consistent with the same solution we have implemented
>  for CAMEL-254 (notice my comment on the issue).
>
There is a lot of value in consistency. The simplest solution is to
add a remove to the http binding before we produce a response.
My only problem with this is that if a processor intentionally added
the Content-Length to an out message we would ignore it.

Re: Where is it best to remove a message transport header that breaks a response?

Posted by Roman Kalukiewicz <ro...@gmail.com>.
2008/2/13, Tully, Gary <Ga...@iona.com>:
> Currently, the unmarshaller copies the input message to the output
> message and augments it. The copy brings with it all of the http
> headers.
> The result is that Content-Length from the request ends in the reply.
> This breaks the http response[1].

I don't think it is caused by unmarshaller really. Basically it is the
behaviour of pipeline to copy the result of the pipeline (either in or
out message) into out message of original exchange. I write it without
looking at the code, so it could be wrong ;)

> One solution is to add a .removeHeader("Content-Length") to the route
> but should that be necessary?
> the header really belongs with the in message.
>
> I am thinking that it never makes sense to copy a Content-Length header
> from a HttpMessage but it would be wrong to remove it.

I don't think we want to remove any header by default. If I don't see
a header I assume that there was no such header. If there is
Content-Length, then it should be in the message.

I would vote for the solution implemented in JMS case James mentioned
about. BTW it is consistent with the same solution we have implemented
for CAMEL-254 (notice my comment on the issue).

Roman

Where is it best to remove a message transport header that breaks a response?

Posted by "Tully, Gary" <Ga...@iona.com>.
Consider a http request response route:

from("jetty:http://localhost:8088/someService").unmarshal().string().pro
cess(
           new Processor() { 
             public void process(Exchange e) { 
           	   String input = (String) e.getIn().getBody();
            	e.getOut().setBody(input + outputText); 
             }
           });

 
Currently, the unmarshaller copies the input message to the output
message and augments it. The copy brings with it all of the http
headers.
The result is that Content-Length from the request ends in the reply.
This breaks the http response[1].

One solution is to add a .removeHeader("Content-Length") to the route
but should that be necessary?
the header really belongs with the in message.

I am thinking that it never makes sense to copy a Content-Length header
from a HttpMessage but it would be wrong to remove it.

I am thinking that there should be a strategy for copying headers.

The Message.copyFrom() can call getCopyHeaders() which can in turn call
a strategy method pruneCopyHeaders() which for a HttpMessage override
can remove the Content-Length header.

Is this overkill or are there other cases where request headers just do
not make sense in a reply?


[1] https://issues.apache.org/activemq/browse/CAMEL-324


----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland