diff --git a/spring-integration-java-dsl/build.gradle b/spring-integration-java-dsl/build.gradle index 396b071..7e76eeb 100644 --- a/spring-integration-java-dsl/build.gradle +++ b/spring-integration-java-dsl/build.gradle @@ -24,7 +24,7 @@ compileTestJava { } ext { - springIntegrationVersion = '4.0.0.BUILD-SNAPSHOT' + springIntegrationVersion = '4.0.0.RC1' log4jVersion = '1.2.17' linkHomepage = 'https://github.com/spring-projects/spring-integration-extensions' @@ -51,6 +51,8 @@ dependencies { testCompile "org.springframework.integration:spring-integration-event:$springIntegrationVersion" testCompile "org.springframework.integration:spring-integration-file:$springIntegrationVersion" testCompile "org.springframework.integration:spring-integration-xml:$springIntegrationVersion" + testCompile "org.springframework.integration:spring-integration-mongodb:$springIntegrationVersion" + testCompile "de.flapdoodle.embed:de.flapdoodle.embed.mongo:1.43" jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.5.6.201201232323", classifier: "runtime" } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/CorrelationHandlerSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/CorrelationHandlerSpec.java index f814215..04886cb 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/CorrelationHandlerSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/CorrelationHandlerSpec.java @@ -16,6 +16,9 @@ package org.springframework.integration.dsl; +import org.springframework.expression.Expression; +import org.springframework.expression.common.LiteralExpression; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler; import org.springframework.integration.aggregator.CorrelationStrategy; import org.springframework.integration.aggregator.ExpressionEvaluatingCorrelationStrategy; @@ -26,6 +29,7 @@ import org.springframework.integration.config.ReleaseStrategyFactoryBean; import org.springframework.integration.dsl.core.IntegrationComponentSpec; import org.springframework.integration.store.MessageGroupStore; import org.springframework.messaging.MessageChannel; +import org.springframework.scheduling.TaskScheduler; /** * @author Artem Bilan @@ -33,12 +37,18 @@ import org.springframework.messaging.MessageChannel; public abstract class CorrelationHandlerSpec, H extends AbstractCorrelatingMessageHandler> extends IntegrationComponentSpec { + protected final static SpelExpressionParser PARSER = new SpelExpressionParser(); + protected MessageGroupStore messageStore; protected boolean sendPartialResultOnExpiry; private long minimumTimeoutForEmptyGroups; + private Expression groupTimeoutExpression; + + private TaskScheduler taskScheduler; + private MessageChannel discardChannel; private String discardChannelName; @@ -62,6 +72,21 @@ public abstract class CorrelationHandlerSpec EnricherSpec property(String key, V value) { + this.propertyExpressions.put(key, new ValueExpression(value)); return _this(); } @@ -109,20 +109,12 @@ public class EnricherSpec extends IntegrationComponentSpec type) { - return this.headerExpression(name, expression, null, type); - } - - public EnricherSpec headerExpression(String name, String expression, Boolean overwrite, Class type) { - AbstractHeaderValueMessageProcessor headerValueMessageProcessor = - new ExpressionEvaluatingHeaderValueMessageProcessor(expression, type); + AbstractHeaderValueMessageProcessor headerValueMessageProcessor = + new ExpressionEvaluatingHeaderValueMessageProcessor(expression, null); headerValueMessageProcessor.setOverwrite(overwrite); return this.header(name, headerValueMessageProcessor); } @@ -133,7 +125,6 @@ public class EnricherSpec extends IntegrationComponentSpec type) { + public HeaderEnricherSpec headerExpression(String name, String expression, Class type) { return this.headerExpression(name, expression, null, type); } @@ -104,7 +104,6 @@ public class HeaderEnricherSpec extends IntegrationComponentSpec messageSource, EndpointConfigurer endpointConfigurer) { + public static IntegrationFlowBuilder from(MessageSource messageSource, + EndpointConfigurer endpointConfigurer) { SourcePollingChannelAdapterSpec spec = new SourcePollingChannelAdapterSpec(messageSource); if (endpointConfigurer != null) { endpointConfigurer.configure(spec); } SourcePollingChannelAdapterFactoryBean sourcePollingChannelAdapterFactoryBean = spec.get().getT1(); - return new IntegrationFlowBuilder().addComponent(sourcePollingChannelAdapterFactoryBean).currentComponent(sourcePollingChannelAdapterFactoryBean); + return new IntegrationFlowBuilder() + .addComponent(sourcePollingChannelAdapterFactoryBean) + .currentComponent(sourcePollingChannelAdapterFactoryBean); } /*public static IntegrationFlowBuilder from(AbstractEndpoint endpoint) { diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java index 639d632..2883b7e 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.dsl.core.IntegrationComponentSpec; +import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.util.Assert; @@ -37,6 +38,8 @@ public abstract class MessageChannelSpec, C e private final List interceptors = new LinkedList(); + private MessageConverter messageConverter; + @Override protected S id(String id) { return super.id(id); @@ -54,11 +57,17 @@ public abstract class MessageChannelSpec, C e return _this(); } + public S messageConverter(MessageConverter messageConverter) { + this.messageConverter = messageConverter; + return _this(); + } + @Override protected C doGet() { this.channel.setDatatypes(this.datatypes.toArray(new Class[this.datatypes.size()])); this.channel.setBeanName(this.id); this.channel.setInterceptors(this.interceptors); + this.channel.setMessageConverter(this.messageConverter); return this.channel; } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannels.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannels.java index a0bbba9..a093112 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannels.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannels.java @@ -19,7 +19,8 @@ package org.springframework.integration.dsl.channel; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; -import org.springframework.integration.store.MessageGroupStore; +import org.springframework.integration.store.ChannelMessageStore; +import org.springframework.integration.store.PriorityCapableChannelMessageStore; import org.springframework.messaging.Message; /** @@ -59,11 +60,11 @@ public final class MessageChannels { return queue(capacity).id(id); } - public static QueueChannelSpec.MessageStoreSpec queue(MessageGroupStore messageGroupStore, Object groupId) { + public static QueueChannelSpec.MessageStoreSpec queue(ChannelMessageStore messageGroupStore, Object groupId) { return new QueueChannelSpec.MessageStoreSpec(messageGroupStore, groupId); } - public static QueueChannelSpec.MessageStoreSpec queue(String id, MessageGroupStore messageGroupStore, Object groupId) { + public static QueueChannelSpec.MessageStoreSpec queue(String id, ChannelMessageStore messageGroupStore, Object groupId) { return queue(messageGroupStore, groupId).id(id); } @@ -91,6 +92,16 @@ public final class MessageChannels { return priority().id(id); } + public static QueueChannelSpec.MessageStoreSpec priority(PriorityCapableChannelMessageStore messageGroupStore, + Object groupId) { + return new QueueChannelSpec.MessageStoreSpec(messageGroupStore, groupId); + } + + public static QueueChannelSpec.MessageStoreSpec priority(String id, PriorityCapableChannelMessageStore messageGroupStore, + Object groupId) { + return queue(messageGroupStore, groupId).id(id); + } + public static PublishSubscribeChannelSpec publishSubscribe() { return new PublishSubscribeChannelSpec(); } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java index 3cc9d07..e9ae527 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java @@ -20,8 +20,9 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.locks.Lock; import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.store.ChannelMessageStore; import org.springframework.integration.store.MessageGroupQueue; -import org.springframework.integration.store.MessageGroupStore; +import org.springframework.integration.store.PriorityCapableChannelMessageStore; import org.springframework.messaging.Message; /** @@ -60,13 +61,13 @@ public class QueueChannelSpec extends MessageChannelSpec message = MessageBuilder.withPayload("1").setPriority(1).build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("-1").setPriority(-1).build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("3").setPriority(3).build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("0").setPriority(0).build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("2").setPriority(2).build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("none").build(); + this.priorityChannel.send(message); + + message = MessageBuilder.withPayload("31").setPriority(3).build(); + this.priorityChannel.send(message); + + Thread.sleep(1000); + + Message receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("3", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("31", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("2", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("1", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("0", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("-1", receive.getPayload()); + + receive = this.priorityReplyChannel.receive(1000); + assertNotNull(receive); + assertEquals("none", receive.getPayload()); + } + @MessagingGateway(defaultRequestChannel = "controlBus") private static interface ControlBusGateway { @@ -752,6 +846,27 @@ public class IntegrationFlowTests { .get(); } + @Bean + public MongoDbFactory mongoDbFactory() throws Exception { + return new SimpleMongoDbFactory(new MongoURI("mongodb://localhost:12345/local")); + } + + @Bean + public MongoDbChannelMessageStore mongoDbChannelMessageStore(MongoDbFactory mongoDbFactory) { + MongoDbChannelMessageStore mongoDbChannelMessageStore = new MongoDbChannelMessageStore(mongoDbFactory); + mongoDbChannelMessageStore.setPriorityEnabled(true); + return mongoDbChannelMessageStore; + } + + @Bean + public IntegrationFlow priorityFlow(PriorityCapableChannelMessageStore mongoDbChannelMessageStore) { + return IntegrationFlows.from(MessageChannels.priority("priorityChannel", + mongoDbChannelMessageStore, "priorityGroup")) + .bridge(s -> s.poller(Pollers.fixedDelay(1000, 2000))) + .channel(MessageChannels.queue("priorityReplyChannel")) + .get(); + } + } @MessageEndpoint @@ -851,7 +966,8 @@ public class IntegrationFlowTests { r.defaultOutputChannel(defaultOutputChannel()) .recipient("foo-channel", "'foo' == payload") .recipient("bar-channel", m -> - m.getHeaders().containsKey("recipient") && (boolean) m.getHeaders().get("recipient")) + m.getHeaders().containsKey("recipient") + && (boolean) m.getHeaders().get("recipient")) ) .get(); } @@ -1175,3 +1291,4 @@ public class IntegrationFlowTests { } } +