INT-3551: Idempotent Receiver: Add value-strategy
JIRA: https://jira.spring.io/browse/INT-3551 * Rename `MetadataKeyStrategy` -> `MetadataEntryStrategy` * Add `valueStrategy` to the `MetadataStoreSelector` * Add `value-strategy` and `value-expression` to the `<idempotent-receiver>` INT-3551: Add `@IR` support on service methods Rework `MetadataKeyStrategy` just to the `MessageProcessor` Fix Docs Minor Doc Polishing.
This commit is contained in:
committed by
Gary Russell
parent
1018fcf361
commit
0cc9273a2e
@@ -16,11 +16,19 @@
|
||||
<idempotent-receiver id="selectorInterceptor" endpoint="foo" selector="selector"/>
|
||||
|
||||
<beans:bean id="keyStrategy" class="org.mockito.Mockito" factory-method="mock">
|
||||
<beans:constructor-arg value="org.springframework.integration.metadata.MetadataKeyStrategy"/>
|
||||
<beans:constructor-arg value="org.springframework.integration.handler.MessageProcessor"/>
|
||||
</beans:bean>
|
||||
|
||||
<idempotent-receiver id="strategyInterceptor" endpoint="foo" key-strategy="keyStrategy"
|
||||
discard-channel="nullChannel" throw-exception-on-rejection="true"/>
|
||||
<beans:bean id="valueStrategy" class="org.mockito.Mockito" factory-method="mock">
|
||||
<beans:constructor-arg value="org.springframework.integration.handler.MessageProcessor"/>
|
||||
</beans:bean>
|
||||
|
||||
<idempotent-receiver id="strategyInterceptor"
|
||||
endpoint="foo"
|
||||
key-strategy="keyStrategy"
|
||||
value-strategy="valueStrategy"
|
||||
discard-channel="nullChannel"
|
||||
throw-exception-on-rejection="true"/>
|
||||
|
||||
<beans:bean id="store" class="org.springframework.integration.metadata.SimpleMetadataStore"/>
|
||||
|
||||
@@ -31,7 +39,7 @@
|
||||
<context:property-placeholder properties-ref="properties"/>
|
||||
|
||||
<idempotent-receiver id="expressionInterceptor" endpoint="foo, ${bar}"
|
||||
metadata-store="store"
|
||||
key-expression="headers.foo"/>
|
||||
metadata-store="store"
|
||||
key-expression="headers.foo"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -46,9 +46,9 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.integration.core.MessageSelector;
|
||||
import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor;
|
||||
import org.springframework.integration.handler.MessageProcessor;
|
||||
import org.springframework.integration.handler.advice.IdempotentReceiverInterceptor;
|
||||
import org.springframework.integration.metadata.ExpressionMetadataKeyStrategy;
|
||||
import org.springframework.integration.metadata.MetadataKeyStrategy;
|
||||
import org.springframework.integration.metadata.MetadataStore;
|
||||
import org.springframework.integration.selector.MetadataStoreSelector;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
@@ -79,7 +79,10 @@ public class IdempotentReceiverParserTests {
|
||||
private IdempotentReceiverInterceptor strategyInterceptor;
|
||||
|
||||
@Autowired
|
||||
private MetadataKeyStrategy keyStrategy;
|
||||
private MessageProcessor<String> keyStrategy;
|
||||
|
||||
@Autowired
|
||||
private MessageProcessor<String> valueStrategy;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("nullChannel")
|
||||
@@ -113,6 +116,7 @@ public class IdempotentReceiverParserTests {
|
||||
Object messageSelector = getPropertyValue(this.strategyInterceptor, "messageSelector");
|
||||
assertThat(messageSelector, instanceOf(MetadataStoreSelector.class));
|
||||
assertSame(this.keyStrategy, getPropertyValue(messageSelector, "keyStrategy"));
|
||||
assertSame(this.valueStrategy, getPropertyValue(messageSelector, "valueStrategy"));
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, List<String>> idempotentEndpoints =
|
||||
(Map<String, List<String>>) getPropertyValue(this.idempotentReceiverAutoProxyCreator,
|
||||
@@ -129,7 +133,7 @@ public class IdempotentReceiverParserTests {
|
||||
assertThat(messageSelector, instanceOf(MetadataStoreSelector.class));
|
||||
assertSame(this.store, getPropertyValue(messageSelector, "metadataStore"));
|
||||
Object keyStrategy = getPropertyValue(messageSelector, "keyStrategy");
|
||||
assertThat(keyStrategy, instanceOf(ExpressionMetadataKeyStrategy.class));
|
||||
assertThat(keyStrategy, instanceOf(ExpressionEvaluatingMessageProcessor.class));
|
||||
assertThat(keyStrategy.toString(), containsString("headers.foo"));
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, List<String>> idempotentEndpoints =
|
||||
@@ -176,40 +180,66 @@ public class IdempotentReceiverParserTests {
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " +
|
||||
"'key-strategy' or 'key-expression'"));
|
||||
"'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectorAndStrategy() throws Exception {
|
||||
public void testSelectorAndKeyStrategy() throws Exception {
|
||||
try {
|
||||
bootStrap("selector-and-strategy");
|
||||
bootStrap("selector-and-key-strategy");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " +
|
||||
"'key-strategy' or 'key-expression'"));
|
||||
"'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectorAndExpression() throws Exception {
|
||||
public void testSelectorAndKeyExpression() throws Exception {
|
||||
try {
|
||||
bootStrap("selector-and-expression");
|
||||
bootStrap("selector-and-key-expression");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " +
|
||||
"'key-strategy' or 'key-expression'"));
|
||||
"'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrategyAndExpression() throws Exception {
|
||||
public void testSelectorAndValueStrategy() throws Exception {
|
||||
try {
|
||||
bootStrap("strategy-and-expression");
|
||||
bootStrap("selector-and-value-strategy");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " +
|
||||
"'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectorAndValueExpression() throws Exception {
|
||||
try {
|
||||
bootStrap("selector-and-value-expression");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " +
|
||||
"'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStrategyAndKeyExpression() throws Exception {
|
||||
try {
|
||||
bootStrap("key-strategy-and-key-expression");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
@@ -218,6 +248,18 @@ public class IdempotentReceiverParserTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueStrategyAndValueExpression() throws Exception {
|
||||
try {
|
||||
bootStrap("value-strategy-and-value-expression");
|
||||
fail("BeanDefinitionParsingException expected");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("The 'value-strategy' and 'value-expression' attributes are mutually exclusive"));
|
||||
}
|
||||
}
|
||||
|
||||
private ApplicationContext bootStrap(String configProperty) throws Exception {
|
||||
PropertiesFactoryBean pfb = new PropertiesFactoryBean();
|
||||
pfb.setLocation(new ClassPathResource(
|
||||
|
||||
@@ -13,8 +13,17 @@ without-endpoint=<int:idempotent-receiver endpoint="" selector="selector"/>
|
||||
|
||||
selector-and-store=<int:idempotent-receiver endpoint="foo" selector="selector" metadata-store="store"/>
|
||||
|
||||
selector-and-strategy=<int:idempotent-receiver endpoint="foo" selector="selector" key-strategy="strategy"/>
|
||||
selector-and-key-strategy=<int:idempotent-receiver endpoint="foo" selector="selector" key-strategy="strategy"/>
|
||||
|
||||
selector-and-expression=<int:idempotent-receiver endpoint="foo" selector="selector" key-expression="expression"/>
|
||||
selector-and-key-expression=<int:idempotent-receiver endpoint="foo" selector="selector" key-expression="expression"/>
|
||||
|
||||
strategy-and-expression=<int:idempotent-receiver endpoint="foo" key-strategy="strategy" key-expression="expression"/>
|
||||
selector-and-value-strategy=<int:idempotent-receiver endpoint="foo" selector="selector" value-strategy="strategy"/>
|
||||
|
||||
selector-and-value-expression=<int:idempotent-receiver endpoint="foo" selector="selector" \
|
||||
value-expression="expression"/>
|
||||
|
||||
key-strategy-and-key-expression=<int:idempotent-receiver endpoint="foo" key-strategy="strategy" \
|
||||
key-expression="expression"/>
|
||||
|
||||
value-strategy-and-value-expression=<int:idempotent-receiver endpoint="foo" key-strategy="strategy" \
|
||||
value-strategy="strategy" value-expression="expression"/>
|
||||
|
||||
@@ -33,16 +33,14 @@ import org.mockito.Mockito;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.MessageRejectedException;
|
||||
import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor;
|
||||
import org.springframework.integration.metadata.ConcurrentMetadataStore;
|
||||
import org.springframework.integration.metadata.ExpressionMetadataKeyStrategy;
|
||||
import org.springframework.integration.metadata.MetadataStore;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.selector.MetadataStoreSelector;
|
||||
import org.springframework.integration.support.DefaultMessageBuilderFactory;
|
||||
import org.springframework.integration.support.MessageBuilderFactory;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
@@ -86,7 +84,8 @@ public class IdempotentReceiverTests {
|
||||
@Test
|
||||
public void testIdempotentReceiverInterceptor() {
|
||||
ConcurrentMetadataStore store = new SimpleMetadataStore();
|
||||
ExpressionMetadataKeyStrategy idempotentKeyStrategy = new ExpressionMetadataKeyStrategy("payload");
|
||||
ExpressionEvaluatingMessageProcessor<String> idempotentKeyStrategy =
|
||||
new ExpressionEvaluatingMessageProcessor<>(new SpelExpressionParser().parseExpression("payload"));
|
||||
BeanFactory beanFactory = Mockito.mock(BeanFactory.class);
|
||||
idempotentKeyStrategy.setBeanFactory(beanFactory);
|
||||
IdempotentReceiverInterceptor idempotentReceiverInterceptor =
|
||||
|
||||
Reference in New Issue
Block a user