INT-1863 added support for message removal from the MessageStore to ClaimCheckOutTransformer. Updated documentation.
This commit is contained in:
@@ -69,6 +69,20 @@
|
||||
querying the Message store for a Message identified by the provided Claim Check. It then sends the newly checked-out Message to the
|
||||
<code>output-channel</code>.
|
||||
</para>
|
||||
<para><emphasis>Claim Once</emphasis></para>
|
||||
<para>
|
||||
There are scenarios when a particular message must be claimed only once. Take the airplane luggage check-in/out process.
|
||||
Checking-in your luggage on the departure and and then claiming it on the arrival is a classic example of such scenario.
|
||||
Once the luggage was claimed it can no longer be claimed again without further check-in. To accommodate such cases we
|
||||
introduced <code>remove-message</code> boolean attribute on <code>claim-check-out</code> transformer. This attribute is
|
||||
set to <code>false</code> by default, however if set to <code>true</code>, the claimed Message will also be removed
|
||||
from the MessageStore and can no longer be claimed again.
|
||||
<programlisting language="xml"><![CDATA[<claim-check-out id="checkout"
|
||||
input-channel="checkoutChannel"
|
||||
message-store="testMessageStore"
|
||||
output-channel="output"
|
||||
remove-message="true"/>]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<para>
|
||||
Although we rarely care about the details of the claim checks as long as they work, it is still worth knowing that
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.util.Assert;
|
||||
* Parser for the <claim-check-out/> element.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClaimCheckOutParser extends AbstractTransformerParser {
|
||||
@@ -39,6 +40,7 @@ public class ClaimCheckOutParser extends AbstractTransformerParser {
|
||||
protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String messageStoreRef = element.getAttribute("message-store");
|
||||
Assert.hasText(messageStoreRef, "The 'message-store' attribute is required.");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "remove-message");
|
||||
builder.addConstructorArgReference(messageStoreRef);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,14 @@ import org.springframework.util.Assert;
|
||||
* that ID can be retrieved from the given MessageStore.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClaimCheckOutTransformer extends AbstractTransformer {
|
||||
|
||||
private final MessageStore messageStore;
|
||||
|
||||
private volatile boolean removeMessage = false;
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,7 +46,10 @@ public class ClaimCheckOutTransformer extends AbstractTransformer {
|
||||
Assert.notNull(messageStore, "MessageStore must not be null");
|
||||
this.messageStore = messageStore;
|
||||
}
|
||||
|
||||
|
||||
public void setRemoveMessage(boolean removeMessage) {
|
||||
this.removeMessage = removeMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doTransform(Message<?> message) throws Exception {
|
||||
@@ -53,6 +59,10 @@ public class ClaimCheckOutTransformer extends AbstractTransformer {
|
||||
Message<?> retrievedMessage = this.messageStore.getMessage(id);
|
||||
Assert.notNull(retrievedMessage, "unable to locate Message for ID: " + id
|
||||
+ " within MessageStore [" + this.messageStore + "]");
|
||||
if (this.removeMessage){
|
||||
this.messageStore.removeMessage(id);
|
||||
logger.debug("Message with claim-check '" + id + "' was removed from MessageStore");
|
||||
}
|
||||
MessageBuilder<?> responseBuilder = MessageBuilder.fromMessage(retrievedMessage);
|
||||
// headers on the 'current' message take precedence
|
||||
responseBuilder.copyHeaders(message.getHeaders());
|
||||
|
||||
@@ -1896,7 +1896,7 @@ endpoint itself is a Polling Consumer for a channel with a queue.
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="claim-check-out" type="claimCheckTransformerType">
|
||||
<xsd:element name="claim-check-out">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a Transformer that accepts a Message whose payload is a UUID and
|
||||
@@ -1905,6 +1905,20 @@ endpoint itself is a Polling Consumer for a channel with a queue.
|
||||
available (else null).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="claimCheckTransformerType">
|
||||
<xsd:attribute name="remove-message" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
If set to 'true' the Message will be removed from the MessageStore by
|
||||
this transformer. Useful when Message can be 'claimed' only once. DFAULT is 'false'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="claimCheckTransformerType">
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
<claim-check-out id="checkout"
|
||||
input-channel="checkoutChannel"
|
||||
message-store="testMessageStore"/>
|
||||
|
||||
<!-- claim with remove test -->
|
||||
|
||||
<claim-check-in id="checkinA"
|
||||
input-channel="checkinChannelA"
|
||||
message-store="testMessageStore"
|
||||
output-channel="checkoutChannelA"/>
|
||||
|
||||
<channel id="checkoutChannelA">
|
||||
<interceptors>
|
||||
<wire-tap channel="wiretap"/>
|
||||
</interceptors>
|
||||
</channel>
|
||||
|
||||
<claim-check-out id="checkoutWithRemove"
|
||||
input-channel="checkoutChannelA"
|
||||
message-store="testMessageStore"
|
||||
remove-message="true"/>
|
||||
|
||||
<beans:bean id="testMessageStore"
|
||||
class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -39,6 +42,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@@ -50,6 +54,9 @@ public class ClaimCheckParserTests {
|
||||
|
||||
@Autowired
|
||||
private MessageChannel checkinChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel checkinChannelA;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel wiretap;
|
||||
@@ -59,6 +66,9 @@ public class ClaimCheckParserTests {
|
||||
|
||||
@Autowired
|
||||
private EventDrivenConsumer checkout;
|
||||
|
||||
@Autowired
|
||||
private MessageStore sampleMessageStore;
|
||||
|
||||
|
||||
@Test
|
||||
@@ -86,10 +96,27 @@ public class ClaimCheckParserTests {
|
||||
checkinChannel.send(message);
|
||||
Message<?> wiretapMessage = wiretap.receive(0);
|
||||
assertNotNull(wiretapMessage);
|
||||
assertEquals(message.getHeaders().getId(), wiretapMessage.getPayload());
|
||||
UUID payload = (UUID) wiretapMessage.getPayload();
|
||||
assertEquals(message.getHeaders().getId(), payload);
|
||||
Message<?> resultMessage = replyChannel.receive(0);
|
||||
assertNotNull(resultMessage);
|
||||
assertEquals("test", resultMessage.getPayload());
|
||||
assertNotNull(this.sampleMessageStore.getMessage(payload));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void integrationTestWithRemoval() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
|
||||
checkinChannelA.send(message);
|
||||
Message<?> wiretapMessage = wiretap.receive(0);
|
||||
assertNotNull(wiretapMessage);
|
||||
UUID payload = (UUID) wiretapMessage.getPayload();
|
||||
assertEquals(message.getHeaders().getId(), payload);
|
||||
Message<?> resultMessage = replyChannel.receive(0);
|
||||
assertNotNull(resultMessage);
|
||||
assertEquals("test", resultMessage.getPayload());
|
||||
assertNull(this.sampleMessageStore.getMessage(payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user