Announcement Announcement Module
Collapse
No announcement yet.
Service activator hard-coded shouldCopyRequestHeaders=true value Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Service activator hard-coded shouldCopyRequestHeaders=true value

    I use several service activators in a row in order to process some data. However, I have noticed that when a method that explicitly removes message headers is called via the service activator, SI simply replaces the removed headers before calling the next service. Looking at the source, this appears to be done in AbstractReplyProducingMessageHandler.createReplyMe ssage, which copies the request headers into the reply because shouldCopyRequestHeaders always returns true in the case of ServiceActivatingHandler.

    I note that MessageTransformingHandler does not copy the request headers, however I cannot use this because it always expects a reply, and at compile time I don't know whether the underlying service will return a reply or not.

    While copying the request headers makes sense for the use case of adding the request context to a reply from some external system, IMO it does not make sense if the returned value is already a Message as opposed to some other Object. Presumably if the returned value is a Message, the underlying service is SI-aware and would already have set the headers to the desired values.
    Last edited by rgupta; Jan 9th, 2012, 02:12 AM.

  • #2
    If you want to remove headers, you should use a <header-filter> element instead of a service-activator (or alongside one). The reason headers are always copied is that many components only operate with part of the Message (e.g. a payload passed to a POJO service method), and that is how we maintain headers even in those cases. That's especially important for those that control the flow, regardless of how many components are in that flow, such as 'correlationId', 'sequenceNumber', and any transport-specific properties such as a JMSReplyTo value.

    Hope that helps.
    -Mark

    Comment


    • #3
      Hi Mark, thanks for your reply.

      I understand that headers need to be maintained in the situation you described, but that is easily handled by checking if the delegate method returned "! (retVal instanceof Message)". In that situation, the POJO return value should simply be wrapped in a new Message with all of the request headers present, thereby preserving all the context information.

      But what situation calls for copying the request headers into the Message where the return value is already a Message? If an activator needs to apply business logic associated with its service call to the removal of a context header, shouldn't it be allowed to do?

      Comment


      • #4
        Actually the behavior you describe is exactly how it *does* work for a Transformer. In that case, if a Message is returned, it is not altered (since it assumes the Message as-returned is intentionally constructed for the downstream flow). The rationale is that you really do care about the Message instance (rather than just its payload), then "Transformer" is probably the right component. In most (maybe all) cases, a "Service Activator" should not be tied to the Messaging API at all (just operating against the payload, and possibly individually bound header values).

        Does that make sense?
        -Mark

        Comment


        • #5
          Since the SA can also return a Message instance, I don't see why the same logic -- that the Message was intentionally constructed for the downstream flow -- does not apply?

          I actually did switch over to a Transformer initially because I saw that it maintained the header removals, however I ran into the fact that Transformer requires a response. I do need to be able to return null from these components in certain cases.

          In any case, if the SA logic should not change for some reason (the current logic seems inconsistent to me [1]), a new type of component that, like the Transformer, allows the headers to be removed, and like the SA, allows null to be returned would be perfect. I don't know if that would be generally useful but it would definitely fit my use case. I am certainly willing to contribute a patch for this if you are willing to upstream it.

          [1] Not only is the SA logic inconsistent with Transformer in terms of assuming that a returned Message instance was not intentionally constructed, but it is internally inconsistent in that it *does* allow headers to be modified, but *does not* allow headers to be removed.
          Last edited by rgupta; Jan 11th, 2012, 01:10 PM.

          Comment


          • #6
            I created https://jira.springsource.org/browse/INT-2416 to track this. As per my note above as well as in INT-2416, I am willing to submit a patch if the devs indicate any interest. At the very least, removeHeader in a S.A. should not fail silently as it does today.

            Comment

            Working...
            X