Claim Check

In earlier sections, we covered several content enricher components that can help you deal with situations where a message is missing a piece of data. We also discussed content filtering, which lets you remove data items from a message. However, there are times when we want to hide data temporarily. For example, in a distributed system, we may receive a message with a very large payload. Some intermittent message processing steps may not need access to this payload and some may only need to access certain headers, so carrying the large message payload through each processing step may cause performance degradation, may produce a security risk, and may make debugging more difficult.

The store in library (or claim check) pattern describes a mechanism that lets you store data in a well known place while maintaining only a pointer (a claim check) to where that data is located. You can pass that pointer around as the payload of a new message, thereby letting any component within the message flow get the actual data as soon as it needs it. This approach is very similar to the certified mail process, where you get a claim check in your mailbox and then have to go to the post office to claim your actual package. It is also the same idea as baggage claim after a flight or in a hotel.

Spring Integration provides two types of claim check transformers:

  • Incoming Claim Check Transformer

  • Outgoing Claim Check Transformer

Convenient namespace-based mechanisms are available to configure them.

Incoming Claim Check Transformer

An incoming claim check transformer transforms an incoming message by storing it in the message store identified by its message-store attribute. The following example defines an incoming claim check transformer:

<int:claim-check-in id="checkin"
        input-channel="checkinChannel"
        message-store="testMessageStore"
        output-channel="output"/>

In the preceding configuration, the message that is received on the input-channel is persisted to the message store identified with the message-store attribute and indexed with a generated ID. That ID is the claim check for that message. The claim check also becomes the payload of the new (transformed) message that is sent to the output-channel.

Now, assume that at some point you do need access to the actual message. You can access the message store manually and get the contents of the message, or you can use the same approach (creating a transformer) except that now you transform the Claim Check to the actual message by using an outgoing claim check transformer.

The following listing provides an overview of all available parameters of an incoming claim check transformer:

<int:claim-check-in auto-startup="true"             (1)
                    id=""                           (2)
                    input-channel=""                (3)
                    message-store="messageStore"    (4)
                    order=""                        (5)
                    output-channel=""               (6)
                    send-timeout="">                (7)
    <int:poller></int:poller>                       (8)
</int:claim-check-in>
1 Lifecycle attribute signaling whether this component should be started during application context startup. It defaults to true. This attribute is not available inside a Chain element. Optional.
2 ID identifying the underlying bean definition (MessageTransformingHandler). This attribute is not available inside a Chain element. Optional.
3 The receiving message channel of this endpoint. This attribute is not available inside a Chain element. Optional.
4 Reference to the MessageStore to be used by this claim check transformer. If not specified, the default reference is to a bean named messageStore. Optional.
5 Specifies the order for invocation when this endpoint is connected as a subscriber to a channel. This is particularly relevant when that channel uses a failover dispatching strategy. It has no effect when this endpoint is itself a polling consumer for a channel with a queue. This attribute is not available inside a Chain element. Optional.
6 Identifies the message channel where the message is sent after being processed by this endpoint. This attribute is not available inside a Chain element. Optional.
7 Specifies the maximum amount of time (in milliseconds) to wait when sending a reply message to the output channel. Defaults to -1 — blocking indefinitely. This attribute is not available inside a Chain element. Optional.
8 Defines a poller. This element is not available inside a Chain element. Optional.

Outgoing Claim Check Transformer

An outgoing claim check transformer lets you transform a message with a claim check payload into a message with the original content as its payload.

<int:claim-check-out id="checkout"
        input-channel="checkoutChannel"
        message-store="testMessageStore"
        output-channel="output"/>

In the preceding configuration, the message received on the input-channel should have a claim check as its payload. The outgoing claim check transformer transforms it into a message with the original payload by querying the message store for a message identified by the provided claim check. It then sends the newly checked-out message to the output-channel.

The following listing provides an overview of all available parameters of an outgoing claim check transformer:

<int:claim-check-out auto-startup="true"             (1)
                     id=""                           (2)
                     input-channel=""                (3)
                     message-store="messageStore"    (4)
                     order=""                        (5)
                     output-channel=""               (6)
                     remove-message="false"          (7)
                     send-timeout="">                (8)
    <int:poller></int:poller>                        (9)
</int:claim-check-out>
1 Lifecycle attribute signaling whether this component should be started during application context startup. It defaults to true. This attribute is not available inside a Chain element. Optional.
2 ID identifying the underlying bean definition (MessageTransformingHandler). This attribute is not available inside a Chain element. Optional.
3 The receiving message channel of this endpoint. This attribute is not available inside a Chain element. Optional.
4 Reference to the MessageStore to be used by this claim check transformer. If not specified, the default reference is to a bean named messageStore. Optional.
5 Specifies the order for invocation when this endpoint is connected as a subscriber to a channel. This is particularly relevant when that channel is using a failover dispatching strategy. It has no effect when this endpoint is itself a polling consumer for a channel with a queue. This attribute is not available inside a Chain element. Optional.
6 Identifies the message channel where the message is sent after being processed by this endpoint. This attribute is not available inside a Chain element. Optional.
7 If set to true, the message is removed from the MessageStore by this transformer. This setting is useful when Message can be “claimed” only once. It defaults to false. Optional.
8 Specifies the maximum amount of time (in milliseconds) to wait when sending a reply message to the output channel. It defaults to -1 — blocking indefinitely. This attribute is not available inside a Chain element. Optional.
9 Defines a poller. This element is not available inside a Chain element. Optional.

Claim Once

Sometimes, a particular message must be claimed only once. As an analogy, consider process of handling airplane luggage. You checking in your luggage on departure and claiming it on arrival. Once the luggage has been claimed, it can not be claimed again without first checking it back in. To accommodate such cases, we introduced a remove-message boolean attribute on the claim-check-out transformer. This attribute is set to false by default. However, if set to true, the claimed message is removed from the MessageStore so that it cannot be claimed again.

This feature has an impact in terms of storage space, especially in the case of the in-memory Map-based SimpleMessageStore, where failing to remove messages could ultimately lead to an OutOfMemoryException. Therefore, if you do not expect multiple claims to be made, we recommend that you set the remove-message attribute’s value to true. The following example show how to use the remove-message attribute:

<int:claim-check-out id="checkout"
        input-channel="checkoutChannel"
        message-store="testMessageStore"
        output-channel="output"
        remove-message="true"/>

A Word on Message Store

Although we rarely care about the details of the claim checks (as long as they work), you should know that the current implementation of the actual claim check (the pointer) in Spring Integration uses a UUID to ensure uniqueness.

org.springframework.integration.store.MessageStore is a strategy interface for storing and retrieving messages. Spring Integration provides two convenient implementations of it:

  • SimpleMessageStore: An in-memory, Map-based implementation (the default, good for testing)

  • JdbcMessageStore: An implementation that uses a relational database over JDBC