INT-4157: Migrate JMS DSL

JIRA: https://jira.spring.io/browse/INT-4157

- Refactor the core message-driven endpoint to be `MessageProducerSupport`, eliminating the DSL wrapper
- Retain and refactor the DSL gateway wrapper - still required because it needs to be a MGS
- Port the (core) `Channels` factory

Fix Javadoc

Remove Deprecated setter

Move JmsInboundGateway to the jms Package

* Some polishing for `@Copyright`s
* Remove `@Deprecated` methods in the `Jms`
* Reinstate `IntegrationFlows.from(Function<Channels, MessageChannelSpec<?, ?>>)`
* Typos fixes in the `JmsTests`
This commit is contained in:
Gary Russell
2016-11-02 18:17:20 -04:00
committed by Artem Bilan
parent e0b0c29ce1
commit cfceca8518
21 changed files with 3184 additions and 4 deletions

View File

@@ -0,0 +1,136 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.dsl;
import java.util.Queue;
import java.util.concurrent.Executor;
import org.springframework.integration.dsl.channel.DirectChannelSpec;
import org.springframework.integration.dsl.channel.ExecutorChannelSpec;
import org.springframework.integration.dsl.channel.MessageChannels;
import org.springframework.integration.dsl.channel.PriorityChannelSpec;
import org.springframework.integration.dsl.channel.PublishSubscribeChannelSpec;
import org.springframework.integration.dsl.channel.QueueChannelSpec;
import org.springframework.integration.dsl.channel.RendezvousChannelSpec;
import org.springframework.integration.store.ChannelMessageStore;
import org.springframework.integration.store.PriorityCapableChannelMessageStore;
import org.springframework.messaging.Message;
/**
* @author Artem Bilan
* @author Gary Russell
*
* @since 5.0
*/
public class Channels {
public DirectChannelSpec direct() {
return MessageChannels.direct();
}
public DirectChannelSpec direct(String id) {
return MessageChannels.direct(id);
}
public QueueChannelSpec queue() {
return MessageChannels.queue();
}
public QueueChannelSpec queue(String id) {
return MessageChannels.queue(id);
}
public QueueChannelSpec queue(Integer capacity) {
return MessageChannels.queue(capacity);
}
public QueueChannelSpec queue(String id, Integer capacity) {
return MessageChannels.queue(id, capacity);
}
public QueueChannelSpec queue(Queue<Message<?>> queue) {
return MessageChannels.queue(queue);
}
public QueueChannelSpec queue(String id, Queue<Message<?>> queue) {
return MessageChannels.queue(id, queue);
}
public QueueChannelSpec.MessageStoreSpec queue(ChannelMessageStore messageGroupStore, Object groupId) {
return MessageChannels.queue(messageGroupStore, groupId);
}
public QueueChannelSpec.MessageStoreSpec queue(String id, ChannelMessageStore messageGroupStore, Object groupId) {
return MessageChannels.queue(id, messageGroupStore, groupId);
}
public PriorityChannelSpec priority() {
return MessageChannels.priority();
}
public PriorityChannelSpec priority(String id) {
return MessageChannels.priority(id);
}
public QueueChannelSpec.MessageStoreSpec priority(String id, PriorityCapableChannelMessageStore messageGroupStore,
Object groupId) {
return MessageChannels.priority(id, messageGroupStore, groupId);
}
public QueueChannelSpec.MessageStoreSpec priority(PriorityCapableChannelMessageStore messageGroupStore,
Object groupId) {
return MessageChannels.priority(messageGroupStore, groupId);
}
public RendezvousChannelSpec rendezvous() {
return MessageChannels.rendezvous();
}
public RendezvousChannelSpec rendezvous(String id) {
return MessageChannels.rendezvous(id);
}
public PublishSubscribeChannelSpec<? extends PublishSubscribeChannelSpec<?>> publishSubscribe() {
return MessageChannels.publishSubscribe();
}
public PublishSubscribeChannelSpec<? extends PublishSubscribeChannelSpec<?>> publishSubscribe(Executor executor) {
return MessageChannels.publishSubscribe(executor);
}
public PublishSubscribeChannelSpec<? extends PublishSubscribeChannelSpec<?>> publishSubscribe(String id,
Executor executor) {
return MessageChannels.publishSubscribe(id, executor);
}
public PublishSubscribeChannelSpec<? extends PublishSubscribeChannelSpec<?>> publishSubscribe(String id) {
return MessageChannels.publishSubscribe(id);
}
public ExecutorChannelSpec executor(Executor executor) {
return MessageChannels.executor(executor);
}
public ExecutorChannelSpec executor(String id, Executor executor) {
return MessageChannels.executor(id, executor);
}
Channels() {
super();
}
}

View File

@@ -212,6 +212,18 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
return registerOutputChannelIfCan(this.currentMessageChannel);
}
/**
* Populate a {@link MessageChannel} instance
* at the current {@link IntegrationFlow} chain position using the {@link Channels}
* factory fluent API.
* @param channels the {@link Function} to use.
* @return the current {@link IntegrationFlowDefinition}.
*/
public B channel(Function<Channels, MessageChannelSpec<?, ?>> channels) {
Assert.notNull(channels);
return channel(channels.apply(new Channels()));
}
/**
* The {@link org.springframework.integration.channel.PublishSubscribeChannel} {@link #channel}
* method specific implementation to allow the use of the 'subflow' subscriber capability.

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.dsl;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageSource;
@@ -74,6 +75,20 @@ public final class IntegrationFlows {
: from(messageChannelName);
}
/**
* Populate the {@link MessageChannel} object to the
* {@link IntegrationFlowBuilder} chain using the fluent API from {@link Channels} factory.
* The {@link org.springframework.integration.dsl.IntegrationFlow} {@code inputChannel}.
* @param channels the {@link Function} to use method chain to configure.
* {@link MessageChannel} via {@link Channels} factory.
* @return new {@link IntegrationFlowBuilder}.
* @see Channels
*/
public static IntegrationFlowBuilder from(Function<Channels, MessageChannelSpec<?, ?>> channels) {
Assert.notNull(channels);
return from(channels.apply(new Channels()));
}
/**
* Populate the {@link MessageChannel} object to the
* {@link IntegrationFlowBuilder} chain using the fluent API from {@link MessageChannelSpec}.

View File

@@ -242,7 +242,7 @@ public class CorrelationHandlerTests {
@Bean
@DependsOn("barrierFlow")
public IntegrationFlow releaseBarrierFlow(MessageTriggerAction barrierTriggerAction) {
return IntegrationFlows.from(MessageChannels.queue("releaseChannel"))
return IntegrationFlows.from(c -> c.queue("releaseChannel"))
.trigger(barrierTriggerAction,
e -> e.poller(p -> p.fixedDelay(100)))
.get();

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.context.OrderlyShutdownCapable;
import org.springframework.integration.gateway.MessagingGatewaySupport;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.messaging.MessageChannel;
/**
* A wrapper around the {@link JmsMessageDrivenEndpoint} implementing
* {@link MessagingGatewaySupport}.
*
* @author Artem Bilan
* @author Gary Russell
*
* @since 5.0
*/
public class JmsInboundGateway extends MessagingGatewaySupport implements DisposableBean, OrderlyShutdownCapable {
private final JmsMessageDrivenEndpoint endpoint;
public JmsInboundGateway(AbstractMessageListenerContainer listenerContainer,
ChannelPublishingJmsMessageListener listener) {
this.endpoint = new JmsMessageDrivenEndpoint(listenerContainer, listener);
}
@Override
public void setRequestChannel(MessageChannel requestChannel) {
super.setRequestChannel(requestChannel);
this.endpoint.getListener().setRequestChannel(requestChannel);
}
@Override
public String getComponentType() {
return this.endpoint.getComponentType();
}
@Override
public void setComponentName(String componentName) {
super.setComponentName(componentName);
this.endpoint.setComponentName(getComponentName());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
super.setApplicationContext(applicationContext);
this.endpoint.setApplicationContext(applicationContext);
this.endpoint.setBeanFactory(applicationContext);
this.endpoint.getListener().setBeanFactory(applicationContext);
}
@Override
protected void onInit() throws Exception {
this.endpoint.afterPropertiesSet();
}
public ChannelPublishingJmsMessageListener getListener() {
return this.endpoint.getListener();
}
@Override
protected void doStart() {
this.endpoint.start();
}
@Override
protected void doStop() {
this.endpoint.stop();
}
@Override
public void destroy() throws Exception {
this.endpoint.destroy();
}
@Override
public int beforeShutdown() {
return this.endpoint.beforeShutdown();
}
@Override
public int afterShutdown() {
return this.endpoint.afterShutdown();
}
}

View File

@@ -16,12 +16,15 @@
package org.springframework.integration.jms;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.context.OrderlyShutdownCapable;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.jms.util.JmsAdapterUtils;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.messaging.MessageChannel;
import org.springframework.util.Assert;
/**
@@ -33,7 +36,7 @@ import org.springframework.util.Assert;
* @author Gary Russell
* @author Artem Bilan
*/
public class JmsMessageDrivenEndpoint extends AbstractEndpoint implements DisposableBean, OrderlyShutdownCapable {
public class JmsMessageDrivenEndpoint extends MessageProducerSupport implements DisposableBean, OrderlyShutdownCapable {
private final AbstractMessageListenerContainer listenerContainer;
@@ -89,13 +92,64 @@ public class JmsMessageDrivenEndpoint extends AbstractEndpoint implements Dispos
this.sessionAcknowledgeMode = sessionAcknowledgeMode;
}
@Override
public void setOutputChannel(MessageChannel outputChannel) {
super.setOutputChannel(outputChannel);
this.listener.setRequestChannel(outputChannel);
}
@Override
public void setOutputChannelName(String outputChannelName) {
super.setOutputChannelName(outputChannelName);
this.listener.setRequestChannelName(outputChannelName);
}
@Override
public void setErrorChannel(MessageChannel errorChannel) {
super.setErrorChannel(errorChannel);
this.listener.setErrorChannel(errorChannel);
}
@Override
public void setErrorChannelName(String errorChannelName) {
super.setErrorChannelName(errorChannelName);
this.listener.setErrorChannelName(errorChannelName);
}
@Override
public void setSendTimeout(long sendTimeout) {
super.setSendTimeout(sendTimeout);
this.listener.setRequestTimeout(sendTimeout);
}
@Override
public void setShouldTrack(boolean shouldTrack) {
super.setShouldTrack(shouldTrack);
this.listener.setShouldTrack(shouldTrack);
}
public ChannelPublishingJmsMessageListener getListener() {
return this.listener;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
super.setApplicationContext(applicationContext);
this.listener.setBeanFactory(applicationContext);
}
@Override
public String getComponentType() {
return "jms:message-driven-channel-adapter";
}
@Override
protected void onInit() throws Exception {
public void afterSingletonsInstantiated() {
// skip the output channel requirement assertion for when the listener is pre-built
}
@Override
protected void onInit() {
this.listener.afterPropertiesSet();
if (!this.listenerContainer.isActive()) {
this.listenerContainer.afterPropertiesSet();

View File

@@ -0,0 +1,282 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
/**
* Factory class for JMS components.
*
* @author Artem Bilan
* @author Gary Russell
*
* @since 5.0
*/
public final class Jms {
/**
* The factory to produce a {@link JmsPollableMessageChannelSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param <S> the {@link JmsPollableMessageChannelSpec} inheritor type
* @return the {@link JmsPollableMessageChannelSpec} instance
*/
public static <S extends JmsPollableMessageChannelSpec<S>> JmsPollableMessageChannelSpec<S> pollableChannel(
ConnectionFactory connectionFactory) {
return pollableChannel(null, connectionFactory);
}
/**
* The factory to produce a {@link JmsPollableMessageChannelSpec}.
* @param id the bean name for the target {@code PollableChannel} component
* @param connectionFactory the JMS ConnectionFactory to build on
* @param <S> the {@link JmsPollableMessageChannelSpec} inheritor type
* @return the {@link JmsPollableMessageChannelSpec} instance
*/
public static <S extends JmsPollableMessageChannelSpec<S>> JmsPollableMessageChannelSpec<S> pollableChannel(
String id, ConnectionFactory connectionFactory) {
return new JmsPollableMessageChannelSpec<S>(connectionFactory).id(id);
}
/**
* The factory to produce a {@link JmsMessageChannelSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param <S> the {@link JmsMessageChannelSpec} inheritor type
* @return the {@link JmsMessageChannelSpec} instance
*/
public static <S extends JmsMessageChannelSpec<S>> JmsMessageChannelSpec<S> channel(
ConnectionFactory connectionFactory) {
return channel(null, connectionFactory);
}
/**
* The factory to produce a {@link JmsMessageChannelSpec}.
* @param id the bean name for the target {@code MessageChannel} component
* @param connectionFactory the JMS ConnectionFactory to build on
* @param <S> the {@link JmsMessageChannelSpec} inheritor type
* @return the {@link JmsMessageChannelSpec} instance
*/
public static <S extends JmsMessageChannelSpec<S>> JmsMessageChannelSpec<S> channel(String id,
ConnectionFactory connectionFactory) {
return new JmsMessageChannelSpec<S>(connectionFactory).id(id);
}
/**
* The factory to produce a {@link JmsPublishSubscribeMessageChannelSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsPublishSubscribeMessageChannelSpec} instance
*/
public static JmsPublishSubscribeMessageChannelSpec publishSubscribeChannel(ConnectionFactory connectionFactory) {
return publishSubscribeChannel(null, connectionFactory);
}
/**
* The factory to produce a {@link JmsPublishSubscribeMessageChannelSpec}.
* @param id the bean name for the target {@code MessageChannel} component
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsPublishSubscribeMessageChannelSpec} instance
*/
public static JmsPublishSubscribeMessageChannelSpec publishSubscribeChannel(String id,
ConnectionFactory connectionFactory) {
return new JmsPublishSubscribeMessageChannelSpec(connectionFactory).id(id);
}
/**
* The factory to produce a {@link JmsOutboundChannelAdapterSpec}.
* @param jmsTemplate the JmsTemplate to build on
* @param <S> the {@link JmsOutboundChannelAdapterSpec} inheritor type
* @return the {@link JmsOutboundChannelAdapterSpec} instance
*/
public static <S extends JmsOutboundChannelAdapterSpec<S>> JmsOutboundChannelAdapterSpec<S> outboundAdapter(
JmsTemplate jmsTemplate) {
return new JmsOutboundChannelAdapterSpec<S>(jmsTemplate);
}
/**
* The factory to produce a {@link JmsOutboundChannelAdapterSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsOutboundChannelAdapterSpec} instance
*/
public static JmsOutboundChannelAdapterSpec.JmsOutboundChannelSpecTemplateAware outboundAdapter(
ConnectionFactory connectionFactory) {
return new JmsOutboundChannelAdapterSpec.JmsOutboundChannelSpecTemplateAware(connectionFactory);
}
/**
* The factory to produce a {@link JmsInboundChannelAdapterSpec}.
* @param jmsTemplate the JmsTemplate to build on
* @param <S> the {@link JmsInboundChannelAdapterSpec} inheritor type
* @return the {@link JmsInboundChannelAdapterSpec} instance
*/
public static <S extends JmsInboundChannelAdapterSpec<S>> JmsInboundChannelAdapterSpec<S> inboundAdapter(
JmsTemplate jmsTemplate) {
return new JmsInboundChannelAdapterSpec<S>(jmsTemplate);
}
/**
* The factory to produce a {@link JmsInboundChannelAdapterSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsInboundChannelAdapterSpec} instance
*/
public static JmsInboundChannelAdapterSpec.JmsInboundChannelSpecTemplateAware inboundAdapter(
ConnectionFactory connectionFactory) {
return new JmsInboundChannelAdapterSpec.JmsInboundChannelSpecTemplateAware(connectionFactory);
}
/**
* The factory to produce a {@link JmsOutboundGatewaySpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsOutboundGatewaySpec} instance
*/
public static JmsOutboundGatewaySpec outboundGateway(ConnectionFactory connectionFactory) {
return new JmsOutboundGatewaySpec(connectionFactory);
}
/**
* The factory to produce a {@link JmsOutboundGatewaySpec}.
* @param listenerContainer the JMS {@link AbstractMessageListenerContainer} to build on
* @param <S> the {@link JmsInboundGatewaySpec} inheritor type
* @return the {@link JmsOutboundGatewaySpec} instance
*/
public static <S extends JmsInboundGatewaySpec<S>> JmsInboundGatewaySpec<S> inboundGateway(
AbstractMessageListenerContainer listenerContainer) {
return new JmsInboundGatewaySpec<S>(listenerContainer);
}
/**
* The factory to produce a {@link JmsOutboundGatewaySpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsOutboundGatewaySpec} instance
*/
public static JmsInboundGatewaySpec.JmsInboundGatewayListenerContainerSpec<JmsDefaultListenerContainerSpec, DefaultMessageListenerContainer>
inboundGateway(ConnectionFactory connectionFactory) {
return inboundGateway(connectionFactory, DefaultMessageListenerContainer.class);
}
/**
* The factory to produce a {@link JmsOutboundGatewaySpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param containerClass the {@link AbstractMessageListenerContainer} implementation class
* to instantiate listener container
* @param <S> the {@link JmsListenerContainerSpec} inheritor type
* @param <C> the {@link AbstractMessageListenerContainer} inheritor type
* @return the {@link JmsOutboundGatewaySpec} instance
*/
public static <S extends JmsListenerContainerSpec<S, C>, C extends AbstractMessageListenerContainer>
JmsInboundGatewaySpec.JmsInboundGatewayListenerContainerSpec<S, C> inboundGateway(ConnectionFactory connectionFactory,
Class<C> containerClass) {
try {
JmsListenerContainerSpec<S, C> spec =
new JmsListenerContainerSpec<S, C>(containerClass)
.connectionFactory(connectionFactory);
return new JmsInboundGatewaySpec.JmsInboundGatewayListenerContainerSpec<S, C>(spec);
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
/**
* The factory to produce a {@link JmsMessageDrivenChannelAdapterSpec}.
* @param listenerContainer the {@link AbstractMessageListenerContainer} to build on
* @param <S> the {@link JmsMessageDrivenChannelAdapterSpec} inheritor type
* @return the {@link JmsMessageDrivenChannelAdapterSpec} instance
*/
public static <S extends JmsMessageDrivenChannelAdapterSpec<S>>
JmsMessageDrivenChannelAdapterSpec<S> messageDrivenChannelAdapter(
AbstractMessageListenerContainer listenerContainer) {
return new JmsMessageDrivenChannelAdapterSpec<S>(listenerContainer);
}
/**
* The factory to produce a {@link JmsMessageDrivenChannelAdapterSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @return the {@link JmsMessageDrivenChannelAdapterSpec} instance
*/
public static JmsMessageDrivenChannelAdapterSpec
.JmsMessageDrivenChannelAdapterListenerContainerSpec<JmsDefaultListenerContainerSpec, DefaultMessageListenerContainer>
messageDrivenChannelAdapter(ConnectionFactory connectionFactory) {
return messageDrivenChannelAdapter(connectionFactory, DefaultMessageListenerContainer.class);
}
/**
* The factory to produce a {@link JmsMessageDrivenChannelAdapterSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param containerClass the {@link AbstractMessageListenerContainer} implementation class
* to instantiate listener container
* @param <S> the {@link JmsListenerContainerSpec} inheritor type
* @param <C> the {@link AbstractMessageListenerContainer} inheritor type
* @return the {@link JmsMessageDrivenChannelAdapterSpec} instance
*/
public static <S extends JmsListenerContainerSpec<S, C>, C extends AbstractMessageListenerContainer>
JmsMessageDrivenChannelAdapterSpec.JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C>
messageDrivenChannelAdapter(ConnectionFactory connectionFactory, Class<C> containerClass) {
try {
JmsListenerContainerSpec<S, C> spec =
new JmsListenerContainerSpec<S, C>(containerClass)
.connectionFactory(connectionFactory);
return new JmsMessageDrivenChannelAdapterSpec.JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C>(spec);
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
/**
* The factory to produce a {@link JmsListenerContainerSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param destination the {@link Destination} to listen to
* @return the {@link JmsListenerContainerSpec} instance
*/
public static JmsDefaultListenerContainerSpec container(ConnectionFactory connectionFactory,
Destination destination) {
try {
return new JmsDefaultListenerContainerSpec()
.connectionFactory(connectionFactory)
.destination(destination);
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
/**
* The factory to produce a {@link JmsListenerContainerSpec}.
* @param connectionFactory the JMS ConnectionFactory to build on
* @param destinationName the destination name to listen to
* @return the {@link JmsListenerContainerSpec} instance
*/
public static JmsDefaultListenerContainerSpec container(ConnectionFactory connectionFactory,
String destinationName) {
try {
return new JmsDefaultListenerContainerSpec()
.connectionFactory(connectionFactory)
.destination(destinationName);
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
private Jms() {
}
}

View File

@@ -0,0 +1,205 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.concurrent.Executor;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.backoff.BackOff;
/**
* A {@link DefaultMessageListenerContainer} specific {@link JmsListenerContainerSpec} extension.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsDefaultListenerContainerSpec
extends JmsListenerContainerSpec<JmsDefaultListenerContainerSpec, DefaultMessageListenerContainer> {
JmsDefaultListenerContainerSpec() throws Exception {
super(DefaultMessageListenerContainer.class);
}
/**
* Specify an {@link Executor}.
* @param taskExecutor the {@link Executor} to use.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setTaskExecutor(Executor)
*/
public JmsDefaultListenerContainerSpec taskExecutor(Executor taskExecutor) {
this.target.setTaskExecutor(taskExecutor);
return this;
}
/**
* Specify a {@link BackOff}.
* @param backOff the {@link BackOff} to use.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setBackOff(BackOff)
*/
public JmsDefaultListenerContainerSpec backOff(BackOff backOff) {
this.target.setBackOff(backOff);
return this;
}
/**
* Specify a recovery interval.
* @param recoveryInterval the recovery interval to use.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setRecoveryInterval(long)
*/
public JmsDefaultListenerContainerSpec recoveryInterval(long recoveryInterval) {
this.target.setRecoveryInterval(recoveryInterval);
return this;
}
/**
* Specify the level of caching that this listener container is allowed to apply,
* in the form of the name of the corresponding constant: e.g. "CACHE_CONNECTION".
* @param constantName the cache level constant name.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see #cacheLevel(int)
* @see DefaultMessageListenerContainer#setCacheLevelName(String)
*/
public JmsDefaultListenerContainerSpec cacheLevelName(String constantName) {
this.target.setCacheLevelName(constantName);
return this;
}
/**
* Specify the level of caching that this listener container is allowed to apply.
* @param cacheLevel the level of caching.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setCacheLevel(int)
*/
public JmsDefaultListenerContainerSpec cacheLevel(int cacheLevel) {
this.target.setCacheLevel(cacheLevel);
return this;
}
/**
* The concurrency to use.
* @param concurrency the concurrency.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setConcurrency(String)
*/
public JmsDefaultListenerContainerSpec concurrency(String concurrency) {
this.target.setConcurrency(concurrency);
return this;
}
/**
* The concurrent consumers number to use.
* @param concurrentConsumers the concurrent consumers count.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setConcurrentConsumers(int)
*/
public JmsDefaultListenerContainerSpec concurrentConsumers(int concurrentConsumers) {
this.target.setConcurrentConsumers(concurrentConsumers);
return this;
}
/**
* The max for concurrent consumers number to use.
* @param maxConcurrentConsumers the max concurrent consumers count.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setMaxConcurrentConsumers(int)
*/
public JmsDefaultListenerContainerSpec maxConcurrentConsumers(int maxConcurrentConsumers) {
this.target.setMaxConcurrentConsumers(maxConcurrentConsumers);
return this;
}
/**
* The max messages per task.
* @param maxMessagesPerTask the max messages per task.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setMaxMessagesPerTask(int)
*/
public JmsDefaultListenerContainerSpec maxMessagesPerTask(int maxMessagesPerTask) {
this.target.setMaxMessagesPerTask(maxMessagesPerTask);
return this;
}
/**
* The max for concurrent consumers number to use.
* @param idleConsumerLimit the limit for idle consumer.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setMaxConcurrentConsumers(int)
*/
public JmsDefaultListenerContainerSpec idleConsumerLimit(int idleConsumerLimit) {
this.target.setIdleConsumerLimit(idleConsumerLimit);
return this;
}
/**
* The the limit for idle task.
* @param idleTaskExecutionLimit the limit for idle task.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setIdleTaskExecutionLimit(int)
*/
public JmsDefaultListenerContainerSpec idleTaskExecutionLimit(int idleTaskExecutionLimit) {
this.target.setIdleTaskExecutionLimit(idleTaskExecutionLimit);
return this;
}
/**
* A {@link PlatformTransactionManager} reference.
* @param transactionManager the {@link PlatformTransactionManager} to use.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setTransactionManager(PlatformTransactionManager)
*/
public JmsDefaultListenerContainerSpec transactionManager(PlatformTransactionManager transactionManager) {
this.target.setTransactionManager(transactionManager);
return this;
}
/**
* A name for transaction.
* @param transactionName the name for transaction.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setTransactionName(String)
*/
public JmsDefaultListenerContainerSpec transactionName(String transactionName) {
this.target.setTransactionName(transactionName);
return this;
}
/**
* A transaction timeout.
* @param transactionTimeout the transaction timeout.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setTransactionTimeout(int)
*/
public JmsDefaultListenerContainerSpec transactionTimeout(int transactionTimeout) {
this.target.setTransactionTimeout(transactionTimeout);
return this;
}
/**
* A receive timeout.
* @param receiveTimeout the receive timeout.
* @return current {@link JmsDefaultListenerContainerSpec}.
* @see DefaultMessageListenerContainer#setReceiveTimeout(long)
*/
public JmsDefaultListenerContainerSpec receiveTimeout(long receiveTimeout) {
this.target.setReceiveTimeout(receiveTimeout);
return this;
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import javax.jms.ConnectionFactory;
import org.springframework.integration.dsl.IntegrationComponentSpec;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.jms.support.destination.JmsDestinationAccessor;
/**
* A base {@link IntegrationComponentSpec} for {@link JmsDestinationAccessor}s.
*
* @param <S> the target {@link JmsDestinationAccessorSpec} implementation type.
* @param <A> the target {@link JmsDestinationAccessor} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public abstract class
JmsDestinationAccessorSpec<S extends JmsDestinationAccessorSpec<S, A>, A extends JmsDestinationAccessor>
extends IntegrationComponentSpec<S, A> {
protected JmsDestinationAccessorSpec(A accessor) {
this.target = accessor;
}
S connectionFactory(ConnectionFactory connectionFactory) {
this.target.setConnectionFactory(connectionFactory);
return _this();
}
/**
* A {@link DestinationResolver} to use.
* @param destinationResolver the {@link DestinationResolver} to use.
* @return the spec
* @see JmsDestinationAccessor#setDestinationResolver
*/
public S destinationResolver(DestinationResolver destinationResolver) {
this.target.setDestinationResolver(destinationResolver);
return _this();
}
/**
* A {@code pubSubDomain} flag.
* @param pubSubDomain the {@code pubSubDomain} flag.
* @return the spec
* @see JmsDestinationAccessor#setPubSubDomain(boolean)
*/
public S pubSubDomain(boolean pubSubDomain) {
target.setPubSubDomain(pubSubDomain);
return _this();
}
/**
* A session acknowledgement mode.
* @param sessionAcknowledgeMode the acknowledgement mode constant
* @return the spec
* @see javax.jms.Session#AUTO_ACKNOWLEDGE etc.
* @see JmsDestinationAccessor#setSessionAcknowledgeMode
*/
public S sessionAcknowledgeMode(int sessionAcknowledgeMode) {
this.target.setSessionAcknowledgeMode(sessionAcknowledgeMode);
return _this();
}
/**
* A session acknowledgement mode name.
* @param constantName the name of the {@link javax.jms.Session} acknowledge mode constant.
* @return the spec.
* @see JmsDestinationAccessor#setSessionAcknowledgeModeName
*/
public S sessionAcknowledgeModeName(String constantName) {
target.setSessionAcknowledgeModeName(constantName);
return _this();
}
/**
* A session transaction mode.
* @param sessionTransacted the transaction mode.
* @return the spec.
* @see JmsDestinationAccessor#setSessionTransacted
*/
public S sessionTransacted(boolean sessionTransacted) {
this.target.setSessionTransacted(sessionTransacted);
return _this();
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.function.Consumer;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.integration.dsl.MessageSourceSpec;
import org.springframework.integration.jms.JmsDestinationPollingSource;
import org.springframework.integration.jms.JmsHeaderMapper;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.util.Assert;
/**
* A {@link MessageSourceSpec} for a {@link JmsDestinationPollingSource}.
*
* @param <S> the target {@link JmsInboundChannelAdapterSpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsInboundChannelAdapterSpec<S extends JmsInboundChannelAdapterSpec<S>>
extends MessageSourceSpec<S, JmsDestinationPollingSource> {
protected final JmsTemplateSpec jmsTemplateSpec = new JmsTemplateSpec();
JmsInboundChannelAdapterSpec(JmsTemplate jmsTemplate) {
this.target = new JmsDestinationPollingSource(jmsTemplate);
}
private JmsInboundChannelAdapterSpec(ConnectionFactory connectionFactory) {
this.target = new JmsDestinationPollingSource(this.jmsTemplateSpec.connectionFactory(connectionFactory).get());
}
/**
* @param messageSelector the messageSelector.
* @return the spec.
* @see JmsDestinationPollingSource#setMessageSelector(String)
*/
public S messageSelector(String messageSelector) {
this.target.setMessageSelector(messageSelector);
return _this();
}
/**
* Configure a {@link JmsHeaderMapper} to map from JMS headers and properties to
* Spring Integration headers.
* @param headerMapper the headerMapper.
* @return the spec.
*/
public S headerMapper(JmsHeaderMapper headerMapper) {
this.target.setHeaderMapper(headerMapper);
return _this();
}
/**
* Configure the destination from which to receive messages.
* @param destination the destination.
* @return the spec.
*/
public S destination(Destination destination) {
this.target.setDestination(destination);
return _this();
}
/**
* Configure the name of destination from which to receive messages.
* @param destination the destination.
* @return the spec.
*/
public S destination(String destination) {
this.target.setDestinationName(destination);
return _this();
}
/**
* A {@link JmsTemplate}-based {@link JmsInboundChannelAdapterSpec} extension.
*/
public static class JmsInboundChannelSpecTemplateAware extends
JmsInboundChannelAdapterSpec<JmsInboundChannelSpecTemplateAware> {
JmsInboundChannelSpecTemplateAware(ConnectionFactory connectionFactory) {
super(connectionFactory);
}
/**
* Configure the channel adapter to use the template specification created by invoking the
* {@link Consumer} callback, passing in a {@link JmsTemplateSpec}.
* @param configurer the configurer.
* @return the spec.
*/
public JmsInboundChannelSpecTemplateAware configureJmsTemplate(Consumer<JmsTemplateSpec> configurer) {
Assert.notNull(configurer);
configurer.accept(this.jmsTemplateSpec);
return _this();
}
}
}

View File

@@ -0,0 +1,224 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.function.Consumer;
import javax.jms.Destination;
import org.springframework.integration.dsl.MessagingGatewaySpec;
import org.springframework.integration.jms.ChannelPublishingJmsMessageListener;
import org.springframework.integration.jms.JmsHeaderMapper;
import org.springframework.integration.jms.JmsInboundGateway;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.util.Assert;
/**
* A {@link MessagingGatewaySpec} for a {@link JmsInboundGateway}.
*
* @param <S> the target {@link JmsInboundGatewaySpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsInboundGatewaySpec<S extends JmsInboundGatewaySpec<S>>
extends MessagingGatewaySpec<S, JmsInboundGateway> {
JmsInboundGatewaySpec(AbstractMessageListenerContainer listenerContainer) {
super(new JmsInboundGateway(listenerContainer, new ChannelPublishingJmsMessageListener()));
this.target.getListener().setExpectReply(true);
}
/**
* @param defaultReplyDestination the defaultReplyDestination
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setDefaultReplyDestination(Destination)
*/
public S defaultReplyDestination(Destination defaultReplyDestination) {
this.target.getListener().setDefaultReplyDestination(defaultReplyDestination);
return _this();
}
/**
* @param destinationName the destinationName
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setDefaultReplyQueueName(String)
*/
public S defaultReplyQueueName(String destinationName) {
this.target.getListener().setDefaultReplyQueueName(destinationName);
return _this();
}
/**
* @param destinationName the destinationName
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setDefaultReplyTopicName(String)
*/
public S defaultReplyTopicName(String destinationName) {
this.target.getListener().setDefaultReplyTopicName(destinationName);
return _this();
}
/**
* @param replyTimeToLive the replyTimeToLive
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setReplyTimeToLive(long)
*/
public S replyTimeToLive(long replyTimeToLive) {
this.target.getListener().setReplyTimeToLive(replyTimeToLive);
return _this();
}
/**
* @param replyPriority the replyPriority
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setReplyPriority(int)
*/
public S replyPriority(int replyPriority) {
this.target.getListener().setReplyPriority(replyPriority);
return _this();
}
/**
* @param replyDeliveryPersistent the replyDeliveryPersistent
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setReplyDeliveryPersistent(boolean)
*/
public S replyDeliveryPersistent(boolean replyDeliveryPersistent) {
this.target.getListener().setReplyDeliveryPersistent(replyDeliveryPersistent);
return _this();
}
/**
* @param correlationKey the correlationKey
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setCorrelationKey(String)
*/
public S correlationKey(String correlationKey) {
this.target.getListener().setCorrelationKey(correlationKey);
return _this();
}
/**
* @param explicitQosEnabledForReplies the explicitQosEnabledForReplies.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setExplicitQosEnabledForReplies(boolean)
*/
public S explicitQosEnabledForReplies(boolean explicitQosEnabledForReplies) {
this.target.getListener().setExplicitQosEnabledForReplies(explicitQosEnabledForReplies);
return _this();
}
/**
* @param destinationResolver the destinationResolver.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setDestinationResolver(DestinationResolver)
*/
public S destinationResolver(DestinationResolver destinationResolver) {
this.target.getListener().setDestinationResolver(destinationResolver);
return _this();
}
/**
* @param messageConverter the messageConverter.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setMessageConverter(MessageConverter)
*/
public S jmsMessageConverter(MessageConverter messageConverter) {
this.target.getListener().setMessageConverter(messageConverter);
return _this();
}
/**
* @param headerMapper the headerMapper.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setHeaderMapper(JmsHeaderMapper)
*/
public S setHeaderMapper(JmsHeaderMapper headerMapper) {
this.target.getListener().setHeaderMapper(headerMapper);
return _this();
}
/**
* @param extractRequestPayload the extractRequestPayload.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setExtractRequestPayload(boolean)
*/
public S extractRequestPayload(boolean extractRequestPayload) {
this.target.getListener().setExtractRequestPayload(extractRequestPayload);
return _this();
}
/**
* @param extractReplyPayload the extractReplyPayload.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setExtractReplyPayload(boolean)
*/
public S extractReplyPayload(boolean extractReplyPayload) {
this.target.getListener().setExtractReplyPayload(extractReplyPayload);
return _this();
}
/**
* An {@link AbstractMessageListenerContainer}-based {@link JmsInboundGatewaySpec} extension.
*
* @param <S> the target {@link JmsListenerContainerSpec} implementation type.
* @param <C> the target {@link AbstractMessageListenerContainer} implementation type.
*/
public static class JmsInboundGatewayListenerContainerSpec<S extends JmsListenerContainerSpec<S, C>, C extends AbstractMessageListenerContainer>
extends JmsInboundGatewaySpec<JmsInboundGatewayListenerContainerSpec<S, C>> {
private final JmsListenerContainerSpec<S, C> spec;
JmsInboundGatewayListenerContainerSpec(JmsListenerContainerSpec<S, C> spec) {
super(spec.get());
this.spec = spec;
this.spec.get().setAutoStartup(false);
}
/**
* @param destination the destination
* @return the spec.
* @see JmsListenerContainerSpec#destination(Destination)
*/
public JmsInboundGatewayListenerContainerSpec<S, C> destination(Destination destination) {
this.spec.destination(destination);
return _this();
}
/**
* @param destinationName the destinationName
* @return the spec.
* @see JmsListenerContainerSpec#destination(String)
*/
public JmsInboundGatewayListenerContainerSpec<S, C> destination(String destinationName) {
this.spec.destination(destinationName);
return _this();
}
public JmsInboundGatewayListenerContainerSpec<S, C> configureListenerContainer(
Consumer<JmsListenerContainerSpec<S, C>> configurer) {
Assert.notNull(configurer);
configurer.accept(this.spec);
return _this();
}
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.util.ErrorHandler;
/**
* A {@link JmsDestinationAccessorSpec} for {@link JmsListenerContainerSpec}s.
*
* @param <S> the target {@link JmsListenerContainerSpec} implementation type.
* @param <C> the target {@link AbstractMessageListenerContainer} implementation type.
*
* @author Artem Bilan
* @author Gary Russell
* @since 5.0
*/
public class JmsListenerContainerSpec<S extends JmsListenerContainerSpec<S, C>, C extends AbstractMessageListenerContainer>
extends JmsDestinationAccessorSpec<S, C> {
JmsListenerContainerSpec(Class<C> aClass) throws Exception {
super(aClass.newInstance());
if (DefaultMessageListenerContainer.class.isAssignableFrom(aClass)) {
this.target.setSessionTransacted(true);
}
}
/**
* @param destination the destination.
* @return the spec.
* @see AbstractMessageListenerContainer#setDestination(Destination)
*/
S destination(Destination destination) {
this.target.setDestination(destination);
return _this();
}
/**
* @param destinationName the destinationName.
* @return the spec.
* @see AbstractMessageListenerContainer#setDestinationName(String)
*/
S destination(String destinationName) {
this.target.setDestinationName(destinationName);
return _this();
}
/**
* @param messageSelector the messageSelector.
* @return the spec.
* @see AbstractMessageListenerContainer#setMessageSelector(String)
*/
public S messageSelector(String messageSelector) {
this.target.setMessageSelector(messageSelector);
return _this();
}
/**
* @param subscriptionDurable the subscriptionDurable.
* @return the spec.
* @see AbstractMessageListenerContainer#setSubscriptionDurable(boolean)
*/
public S subscriptionDurable(boolean subscriptionDurable) {
this.target.setSubscriptionDurable(subscriptionDurable);
return _this();
}
/**
* @param durableSubscriptionName the durableSubscriptionName.
* @return the spec.
* @see AbstractMessageListenerContainer#setDurableSubscriptionName(String)
*/
public S durableSubscriptionName(String durableSubscriptionName) {
this.target.setDurableSubscriptionName(durableSubscriptionName);
return _this();
}
/**
* @param exceptionListener the exceptionListener.
* @return the spec.
* @see AbstractMessageListenerContainer#setExceptionListener(ExceptionListener)
*/
public S exceptionListener(ExceptionListener exceptionListener) {
this.target.setExceptionListener(exceptionListener);
return _this();
}
/**
* @param errorHandler the errorHandler.
* @return the spec.
* @see AbstractMessageListenerContainer#setErrorHandler(ErrorHandler)
*/
public S errorHandler(ErrorHandler errorHandler) {
this.target.setErrorHandler(errorHandler);
return _this();
}
/**
* @param exposeListenerSession the exposeListenerSession.
* @return the spec.
* @see AbstractMessageListenerContainer#setExposeListenerSession(boolean)
*/
public S exposeListenerSession(boolean exposeListenerSession) {
this.target.setExposeListenerSession(exposeListenerSession);
return _this();
}
/**
* @param acceptMessagesWhileStopping the acceptMessagesWhileStopping.
* @return the spec.
* @see AbstractMessageListenerContainer#setAcceptMessagesWhileStopping(boolean)
*/
public S acceptMessagesWhileStopping(boolean acceptMessagesWhileStopping) {
this.target.setAcceptMessagesWhileStopping(acceptMessagesWhileStopping);
return _this();
}
/**
* @param clientId the clientId.
* @return the spec.
* @see AbstractMessageListenerContainer#setClientId(String)
*/
public S clientId(String clientId) {
this.target.setClientId(clientId);
return _this();
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.concurrent.Executor;
import javax.jms.ConnectionFactory;
import org.springframework.integration.jms.AbstractJmsChannel;
import org.springframework.integration.jms.SubscribableJmsChannel;
import org.springframework.integration.jms.config.JmsChannelFactoryBean;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.ErrorHandler;
/**
* A {@link JmsMessageChannelSpec} for subscribable {@link AbstractJmsChannel}s.
*
* @param <S> the target {@link JmsMessageChannelSpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsMessageChannelSpec<S extends JmsMessageChannelSpec<S>> extends JmsPollableMessageChannelSpec<S> {
JmsMessageChannelSpec(ConnectionFactory connectionFactory) {
super(new JmsChannelFactoryBean(true), connectionFactory);
}
/**
* Configure the type of the container.
* {@link AbstractMessageListenerContainer}. Defaults to
* {@link DefaultMessageListenerContainer}.
* @param containerType the containerType.
* @return the current {@link JmsMessageChannelSpec}.
*/
public S containerType(Class<? extends AbstractMessageListenerContainer> containerType) {
this.jmsChannelFactoryBean.setContainerType(containerType);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}
* or a {@link org.springframework.jms.listener.SimpleMessageListenerContainer}.
* @param concurrentConsumers the concurrentConsumers.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setConcurrentConsumers(int)
* @see org.springframework.jms.listener.SimpleMessageListenerContainer#setConcurrentConsumers(int)
*/
public S concurrentConsumers(int concurrentConsumers) {
this.jmsChannelFactoryBean.setConcurrentConsumers(concurrentConsumers);
return _this();
}
/**
* @param maxSubscribers the maxSubscribers.
* @return the current {@link JmsMessageChannelSpec}.
* @see SubscribableJmsChannel#setMaxSubscribers(int)
*/
public S maxSubscribers(int maxSubscribers) {
this.jmsChannelFactoryBean.setMaxSubscribers(maxSubscribers);
return _this();
}
/**
* @param autoStartup the autoStartup.
* @return the current {@link JmsMessageChannelSpec}.
* @see org.springframework.context.SmartLifecycle
*/
public S autoStartup(boolean autoStartup) {
this.jmsChannelFactoryBean.setAutoStartup(autoStartup);
return _this();
}
/**
* @param phase the phase.
* @return the current {@link JmsMessageChannelSpec}.
* @see org.springframework.context.SmartLifecycle
*/
public S phase(int phase) {
this.jmsChannelFactoryBean.setPhase(phase);
return _this();
}
/**
* @param errorHandler the errorHandler.
* @return the current {@link JmsMessageChannelSpec}.
* @see AbstractMessageListenerContainer#setErrorHandler(ErrorHandler)
*/
public S errorHandler(ErrorHandler errorHandler) {
this.jmsChannelFactoryBean.setErrorHandler(errorHandler);
return _this();
}
/**
* @param exposeListenerSession the exposeListenerSession.
* @return the current {@link JmsMessageChannelSpec}.
* @see AbstractMessageListenerContainer#setExposeListenerSession(boolean)
*/
public S exposeListenerSession(boolean exposeListenerSession) {
this.jmsChannelFactoryBean.setExposeListenerSession(exposeListenerSession);
return _this();
}
/**
* @param acceptMessagesWhileStopping the acceptMessagesWhileStopping.
* @return the current {@link JmsMessageChannelSpec}.
* @see AbstractMessageListenerContainer#setAcceptMessagesWhileStopping(boolean)
*/
public S acceptMessagesWhileStopping(boolean acceptMessagesWhileStopping) {
this.jmsChannelFactoryBean.setAcceptMessagesWhileStopping(acceptMessagesWhileStopping);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param idleTaskExecutionLimit the idleTaskExecutionLimit.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setIdleTaskExecutionLimit(int)
*/
public S idleTaskExecutionLimit(int idleTaskExecutionLimit) {
this.jmsChannelFactoryBean.setIdleTaskExecutionLimit(idleTaskExecutionLimit);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param maxMessagesPerTask the maxMessagesPerTask.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setMaxMessagesPerTask(int)
*/
public S maxMessagesPerTask(int maxMessagesPerTask) {
this.jmsChannelFactoryBean.setMaxMessagesPerTask(maxMessagesPerTask);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param recoveryInterval the recoveryInterval.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setRecoveryInterval(long)
*/
public S recoveryInterval(long recoveryInterval) {
this.jmsChannelFactoryBean.setRecoveryInterval(recoveryInterval);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}
* or a {@link org.springframework.jms.listener.SimpleMessageListenerContainer}.
* @param taskExecutor the taskExecutor.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setTaskExecutor(Executor)
* @see org.springframework.jms.listener.SimpleMessageListenerContainer#setTaskExecutor(Executor)
*/
public S taskExecutor(Executor taskExecutor) {
this.jmsChannelFactoryBean.setTaskExecutor(taskExecutor);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param transactionManager the transactionManager.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setTransactionManager(PlatformTransactionManager)
*/
public S transactionManager(PlatformTransactionManager transactionManager) {
this.jmsChannelFactoryBean.setTransactionManager(transactionManager);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param transactionName the transactionName.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setTransactionName(String)
*/
public S transactionName(String transactionName) {
this.jmsChannelFactoryBean.setTransactionName(transactionName);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}.
* @param transactionTimeout the transactionTimeout.
* @return the current {@link JmsMessageChannelSpec}.
* @see DefaultMessageListenerContainer#setTransactionTimeout(int)
*/
public S transactionTimeout(int transactionTimeout) {
this.jmsChannelFactoryBean.setTransactionTimeout(transactionTimeout);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a
* {@link DefaultMessageListenerContainer}.
* @param cacheLevel the value for {@code DefaultMessageListenerContainer.cacheLevel}
* @return the current {@link JmsMessageChannelSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setCacheLevel(int)
*/
public S cacheLevel(Integer cacheLevel) {
this.jmsChannelFactoryBean.setCacheLevel(cacheLevel);
return _this();
}
/**
* @param subscriptionShared the subscription shared {@code boolean} flag.
* @return the current {@link JmsMessageChannelSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setSubscriptionShared
*/
public S subscriptionShared(boolean subscriptionShared) {
this.jmsChannelFactoryBean.setSubscriptionShared(subscriptionShared);
return _this();
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.function.Consumer;
import javax.jms.Destination;
import org.springframework.integration.dsl.MessageProducerSpec;
import org.springframework.integration.jms.ChannelPublishingJmsMessageListener;
import org.springframework.integration.jms.JmsHeaderMapper;
import org.springframework.integration.jms.JmsMessageDrivenEndpoint;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.util.Assert;
/**
* A {@link MessageProducerSpec} for {@link JmsMessageDrivenEndpoint}s.
*
* @param <S> the target {@link JmsMessageDrivenChannelAdapterSpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsMessageDrivenChannelAdapterSpec<S extends JmsMessageDrivenChannelAdapterSpec<S>>
extends MessageProducerSpec<S, JmsMessageDrivenEndpoint> {
JmsMessageDrivenChannelAdapterSpec(AbstractMessageListenerContainer listenerContainer) {
super(new JmsMessageDrivenEndpoint(listenerContainer, new ChannelPublishingJmsMessageListener()));
this.target.getListener().setExpectReply(false);
}
/**
* @param messageConverter the messageConverter.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setMessageConverter(MessageConverter)
*/
public S jmsMessageConverter(MessageConverter messageConverter) {
this.target.getListener().setMessageConverter(messageConverter);
return _this();
}
/**
* @param headerMapper the headerMapper.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setHeaderMapper(JmsHeaderMapper)
*/
public S headerMapper(JmsHeaderMapper headerMapper) {
this.target.getListener().setHeaderMapper(headerMapper);
return _this();
}
/**
* @param extractRequestPayload the extractRequestPayload.
* @return the spec.
* @see ChannelPublishingJmsMessageListener#setExtractRequestPayload(boolean)
*/
public S extractPayload(boolean extractRequestPayload) {
this.target.getListener().setExtractRequestPayload(extractRequestPayload);
return _this();
}
/**
*
* @param <S> the target {@link JmsListenerContainerSpec} implementation type.
* @param <C> the target {@link AbstractMessageListenerContainer} implementation type.
*/
public static class
JmsMessageDrivenChannelAdapterListenerContainerSpec<S extends JmsListenerContainerSpec<S, C>, C extends AbstractMessageListenerContainer>
extends JmsMessageDrivenChannelAdapterSpec<JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C>> {
private final JmsListenerContainerSpec<S, C> spec;
JmsMessageDrivenChannelAdapterListenerContainerSpec(JmsListenerContainerSpec<S, C> spec) {
super(spec.get());
this.spec = spec;
this.spec.get().setAutoStartup(false);
}
/**
* @param destination the destination.
* @return the spec.
* @see JmsListenerContainerSpec#destination(Destination)
*/
public JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C> destination(Destination destination) {
this.spec.destination(destination);
return _this();
}
/**
* Specify a destination name to use.
* @param destinationName the destinationName.
* @return the spec.
* @see JmsListenerContainerSpec#destination(String)
*/
public JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C> destination(String destinationName) {
this.spec.destination(destinationName);
return _this();
}
/**
* Configure a listener container by invoking the {@link Consumer} callback, with a
* {@link JmsListenerContainerSpec} argument.
* @param configurer the configurer.
* @return the spec.
*/
public JmsMessageDrivenChannelAdapterListenerContainerSpec<S, C> configureListenerContainer(
Consumer<JmsListenerContainerSpec<S, C>> configurer) {
Assert.notNull(configurer);
configurer.accept(this.spec);
return _this();
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.integration.dsl.MessageHandlerSpec;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.integration.jms.JmsHeaderMapper;
import org.springframework.integration.jms.JmsSendingMessageHandler;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
/**
* A {@link MessageHandlerSpec} for a {@link JmsSendingMessageHandler}.
*
* @param <S> the target {@link JmsOutboundChannelAdapterSpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsOutboundChannelAdapterSpec<S extends JmsOutboundChannelAdapterSpec<S>>
extends MessageHandlerSpec<S, JmsSendingMessageHandler> {
protected final JmsTemplateSpec jmsTemplateSpec = new JmsTemplateSpec();
JmsOutboundChannelAdapterSpec(JmsTemplate jmsTemplate) {
this.target = new JmsSendingMessageHandler(jmsTemplate);
}
private JmsOutboundChannelAdapterSpec(ConnectionFactory connectionFactory) {
this.target = new JmsSendingMessageHandler(this.jmsTemplateSpec.connectionFactory(connectionFactory).get());
}
/**
* @param extractPayload the extractPayload flag.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setExtractPayload(boolean)
*/
public S extractPayload(boolean extractPayload) {
this.target.setExtractPayload(extractPayload);
return _this();
}
/**
* @param headerMapper the headerMapper.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setHeaderMapper(JmsHeaderMapper)
*/
public S headerMapper(JmsHeaderMapper headerMapper) {
this.target.setHeaderMapper(headerMapper);
return _this();
}
/**
* Configure the destination to which this adapter will send messages.
* @param destination the destination.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setDestination(Destination)
*/
public S destination(Destination destination) {
this.target.setDestination(destination);
return _this();
}
/**
* Configure the name of the destination to which this adapter will send messages.
* @param destination the destination name.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setDestinationName(String)
*/
public S destination(String destination) {
this.target.setDestinationName(destination);
return _this();
}
/**
* Configure a SpEL expression that will evaluate, at run time, the destination to
* which a message will be sent.
* @param destination the destination name.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setDestinationName(String)
*/
public S destinationExpression(String destination) {
this.target.setDestinationExpression(PARSER.parseExpression(destination));
return _this();
}
/**
* Configure a {@link Function} that will be invoked at run time to determine the destination to
* which a message will be sent. Typically used with a Java 8 Lambda expression:
* <pre class="code">
* {@code
* .<Foo>destination(m -> m.getPayload().getState())
* }
* </pre>
* @param destinationFunction the destination function.
* @param <P> the expected payload type.
* @return the current {@link JmsOutboundChannelAdapterSpec}.
* @see JmsSendingMessageHandler#setDestinationName(String)
* @see FunctionExpression
*/
public <P> S destination(Function<Message<P>, ?> destinationFunction) {
this.target.setDestinationExpression(new FunctionExpression<Message<P>>(destinationFunction));
return _this();
}
/**
* A {@link JmsTemplate}-based {@link JmsOutboundChannelAdapterSpec} extension.
*/
public static class JmsOutboundChannelSpecTemplateAware extends
JmsOutboundChannelAdapterSpec<JmsOutboundChannelSpecTemplateAware> {
JmsOutboundChannelSpecTemplateAware(ConnectionFactory connectionFactory) {
super(connectionFactory);
}
public JmsOutboundChannelSpecTemplateAware configureJmsTemplate(Consumer<JmsTemplateSpec> configurer) {
Assert.notNull(configurer);
configurer.accept(this.jmsTemplateSpec);
return _this();
}
}
}

View File

@@ -0,0 +1,438 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.integration.dsl.IntegrationComponentSpec;
import org.springframework.integration.dsl.MessageHandlerSpec;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.integration.jms.JmsHeaderMapper;
import org.springframework.integration.jms.JmsOutboundGateway;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
/**
* A {@link MessageHandlerSpec} for a {@link JmsOutboundGateway}.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsOutboundGatewaySpec extends MessageHandlerSpec<JmsOutboundGatewaySpec, JmsOutboundGateway> {
JmsOutboundGatewaySpec(ConnectionFactory connectionFactory) {
this.target = new JmsOutboundGateway();
this.target.setConnectionFactory(connectionFactory);
this.target.setRequiresReply(true);
}
/**
* @param extractPayload the extractPayload.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setExtractRequestPayload(boolean)
*/
public JmsOutboundGatewaySpec extractRequestPayload(boolean extractPayload) {
this.target.setExtractRequestPayload(extractPayload);
return _this();
}
/**
* @param extractPayload the extractPayload.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setExtractReplyPayload(boolean)
*/
public JmsOutboundGatewaySpec extractReplyPayload(boolean extractPayload) {
this.target.setExtractReplyPayload(extractPayload);
return _this();
}
/**
* @param headerMapper the headerMapper.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setHeaderMapper(JmsHeaderMapper)
*/
public JmsOutboundGatewaySpec headerMapper(JmsHeaderMapper headerMapper) {
this.target.setHeaderMapper(headerMapper);
return _this();
}
/**
* @param destination the destination.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setRequestDestination(Destination)
*/
public JmsOutboundGatewaySpec requestDestination(Destination destination) {
this.target.setRequestDestination(destination);
return _this();
}
/**
* @param destination the destination name.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setRequestDestinationName(String)
*/
public JmsOutboundGatewaySpec requestDestination(String destination) {
this.target.setRequestDestinationName(destination);
return _this();
}
/**
* @param destination the destination expression.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setRequestDestinationExpression(org.springframework.expression.Expression)
*/
public JmsOutboundGatewaySpec requestDestinationExpression(String destination) {
this.target.setRequestDestinationExpression(PARSER.parseExpression(destination));
return _this();
}
/**
* Configure a {@link Function} that will be invoked at run time to determine the destination to
* which a message will be sent. Typically used with a Java 8 Lambda expression:
* <pre class="code">
* {@code
* .<Foo>destination(m -> m.getPayload().getState())
* }
* </pre>
* @param destinationFunction the destination function.
* @param <P> the expected payload type.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setRequestDestinationExpression(org.springframework.expression.Expression)
* @see FunctionExpression
*/
public <P> JmsOutboundGatewaySpec requestDestination(Function<Message<P>, ?> destinationFunction) {
this.target.setRequestDestinationExpression(new FunctionExpression<Message<P>>(destinationFunction));
return _this();
}
/**
* @param destination the destination.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReplyDestination(Destination)
*/
public JmsOutboundGatewaySpec replyDestination(Destination destination) {
this.target.setReplyDestination(destination);
return _this();
}
/**
* @param destination the destination name.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReplyDestinationName(String)
*/
public JmsOutboundGatewaySpec replyDestination(String destination) {
this.target.setReplyDestinationName(destination);
return _this();
}
/**
* @param destination the destination expression.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReplyDestinationExpression(org.springframework.expression.Expression)
*/
public JmsOutboundGatewaySpec replyDestinationExpression(String destination) {
this.target.setReplyDestinationExpression(PARSER.parseExpression(destination));
return _this();
}
/**
* Configure a {@link Function} that will be invoked at run time to determine the destination from
* which a reply will be received. Typically used with a Java 8 Lambda expression:
* <pre class="code">
* {@code
* .<Foo>replyDestination(m -> m.getPayload().getState())
* }
* </pre>
* @param destinationFunction the destination function.
* @param <P> the expected payload type.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReplyDestinationExpression(org.springframework.expression.Expression)
* @see FunctionExpression
*/
public <P> JmsOutboundGatewaySpec replyDestination(Function<Message<P>, ?> destinationFunction) {
this.target.setReplyDestinationExpression(new FunctionExpression<Message<P>>(destinationFunction));
return _this();
}
/**
* @param destinationResolver the destinationResolver.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setDestinationResolver(DestinationResolver)
*/
public JmsOutboundGatewaySpec destinationResolver(DestinationResolver destinationResolver) {
this.target.setDestinationResolver(destinationResolver);
return _this();
}
/**
* @param messageConverter the messageConverter.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setMessageConverter(MessageConverter)
*/
public JmsOutboundGatewaySpec jmsMessageConverter(MessageConverter messageConverter) {
this.target.setMessageConverter(messageConverter);
return _this();
}
/**
* @param correlationKey the correlationKey
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setCorrelationKey(String)
*/
public JmsOutboundGatewaySpec correlationKey(String correlationKey) {
this.target.setCorrelationKey(correlationKey);
return _this();
}
/**
* @param pubSubDomain the pubSubDomain
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReplyPubSubDomain(boolean)
*/
public JmsOutboundGatewaySpec requestPubSubDomain(boolean pubSubDomain) {
this.target.setRequestPubSubDomain(pubSubDomain);
return _this();
}
/**
* @param pubSubDomain the pubSubDomain
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setRequestPubSubDomain(boolean)
*/
public JmsOutboundGatewaySpec replyPubSubDomain(boolean pubSubDomain) {
this.target.setReplyPubSubDomain(pubSubDomain);
return _this();
}
/**
* @param deliveryPersistent the deliveryPersistent.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setDeliveryPersistent(boolean)
*/
public JmsOutboundGatewaySpec deliveryPersistent(boolean deliveryPersistent) {
this.target.setDeliveryPersistent(deliveryPersistent);
return _this();
}
/**
* Default priority. May be overridden at run time with a message
* priority header.
* @param priority the priority.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setPriority(int)
*/
public JmsOutboundGatewaySpec priority(int priority) {
this.target.setPriority(priority);
return _this();
}
/**
* @param timeToLive the timeToLive.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setTimeToLive(long)
*/
public JmsOutboundGatewaySpec timeToLive(long timeToLive) {
this.target.setTimeToLive(timeToLive);
return _this();
}
/**
* @param receiveTimeout the receiveTimeout.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setReceiveTimeout(long)
*/
public JmsOutboundGatewaySpec receiveTimeout(long receiveTimeout) {
this.target.setReceiveTimeout(receiveTimeout);
return _this();
}
/**
* @param explicitQosEnabled the explicitQosEnabled.
* @return the current {@link JmsOutboundGatewaySpec}.
* @see JmsOutboundGateway#setExplicitQosEnabled(boolean)
*/
public JmsOutboundGatewaySpec explicitQosEnabled(boolean explicitQosEnabled) {
this.target.setExplicitQosEnabled(explicitQosEnabled);
return _this();
}
/**
* Configure a reply container with default properties.
* @return the current {@link JmsOutboundGatewaySpec}.
*/
public JmsOutboundGatewaySpec replyContainer() {
this.target.setReplyContainerProperties(new JmsOutboundGateway.ReplyContainerProperties());
return _this();
}
/**
* Configure a reply container with a reply container specification determined by
* invoking the {@link Consumer} callback with a {@link ReplyContainerSpec}.
* @param configurer the configurer.
* @return the current {@link JmsOutboundGatewaySpec}.
*/
public JmsOutboundGatewaySpec replyContainer(Consumer<ReplyContainerSpec> configurer) {
Assert.notNull(configurer);
ReplyContainerSpec spec = new ReplyContainerSpec();
configurer.accept(spec);
this.target.setReplyContainerProperties(spec.get());
return _this();
}
/**
* An {@link IntegrationComponentSpec} for {@link JmsOutboundGateway.ReplyContainerProperties}.
*
*/
public class ReplyContainerSpec
extends IntegrationComponentSpec<ReplyContainerSpec, JmsOutboundGateway.ReplyContainerProperties> {
ReplyContainerSpec() {
this.target = new JmsOutboundGateway.ReplyContainerProperties();
}
/**
* @param sessionTransacted the sessionTransacted.
* @return the current {@link ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setSessionTransacted(boolean)
*/
public ReplyContainerSpec sessionTransacted(Boolean sessionTransacted) {
this.target.setSessionTransacted(sessionTransacted);
return _this();
}
/**
* @param sessionAcknowledgeMode the acknowledgement mode constant
* @return the current {@link ReplyContainerSpec}.
* @see javax.jms.Session#AUTO_ACKNOWLEDGE etc.
*/
public ReplyContainerSpec sessionAcknowledgeMode(Integer sessionAcknowledgeMode) {
this.target.setSessionAcknowledgeMode(sessionAcknowledgeMode);
return _this();
}
/**
* @param receiveTimeout the receiveTimeout.
* @return the current {@link ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setReceiveTimeout(long)
*/
public ReplyContainerSpec receiveTimeout(Long receiveTimeout) {
this.target.setReceiveTimeout(receiveTimeout);
return _this();
}
/**
* @param recoveryInterval the recoveryInterval.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setRecoveryInterval(long)
*/
public ReplyContainerSpec recoveryInterval(Long recoveryInterval) {
this.target.setRecoveryInterval(recoveryInterval);
return _this();
}
/**
* @param cacheLevel the value for
* {@code org.springframework.jms.listener.DefaultMessageListenerContainer.cacheLevel}.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setCacheLevel(int)
*/
public ReplyContainerSpec cacheLevel(Integer cacheLevel) {
this.target.setCacheLevel(cacheLevel);
return _this();
}
/**
* @param concurrentConsumers the concurrentConsumers.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setConcurrentConsumers(int)
*/
public ReplyContainerSpec concurrentConsumers(Integer concurrentConsumers) {
this.target.setConcurrentConsumers(concurrentConsumers);
return _this();
}
/**
* @param maxConcurrentConsumers the maxConcurrentConsumers.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setMaxConcurrentConsumers(int)
*/
public ReplyContainerSpec maxConcurrentConsumers(Integer maxConcurrentConsumers) {
this.target.setMaxConcurrentConsumers(maxConcurrentConsumers);
return _this();
}
/**
* @param maxMessagesPerTask the maxMessagesPerTask.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setMaxMessagesPerTask(int)
*/
public ReplyContainerSpec maxMessagesPerTask(Integer maxMessagesPerTask) {
this.target.setMaxMessagesPerTask(maxMessagesPerTask);
return _this();
}
/**
* @param idleConsumerLimit the idleConsumerLimit.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setIdleConsumerLimit(int)
*/
public ReplyContainerSpec idleConsumerLimit(Integer idleConsumerLimit) {
this.target.setIdleConsumerLimit(idleConsumerLimit);
return _this();
}
/**
* @param idleTaskExecutionLimit the idleTaskExecutionLimit.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setIdleTaskExecutionLimit(int)
*/
public ReplyContainerSpec idleTaskExecutionLimit(Integer idleTaskExecutionLimit) {
this.target.setIdleTaskExecutionLimit(idleTaskExecutionLimit);
return _this();
}
/**
* @param taskExecutor the taskExecutor.
* @return the current {ReplyContainerSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setTaskExecutor(Executor)
*/
public ReplyContainerSpec taskExecutor(Executor taskExecutor) {
this.target.setTaskExecutor(taskExecutor);
return _this();
}
/**
* @param idleReplyContainerTimeout the timeout in seconds.
* @return the current {ReplyContainerSpec}.
* @see JmsOutboundGateway#setIdleReplyContainerTimeout
*/
public ReplyContainerSpec idleReplyContainerTimeout(long idleReplyContainerTimeout) {
JmsOutboundGatewaySpec.this.target.setIdleReplyContainerTimeout(idleReplyContainerTimeout);
return this;
}
}
}

View File

@@ -0,0 +1,225 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.integration.dsl.channel.MessageChannelSpec;
import org.springframework.integration.jms.AbstractJmsChannel;
import org.springframework.integration.jms.config.JmsChannelFactoryBean;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
/**
* A {@link MessageChannelSpec} for an {@link AbstractJmsChannel}.
*
* @param <S> the target {@link JmsPollableMessageChannelSpec} implementation type.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsPollableMessageChannelSpec<S extends JmsPollableMessageChannelSpec<S>>
extends MessageChannelSpec<S, AbstractJmsChannel> {
protected final JmsChannelFactoryBean jmsChannelFactoryBean;
JmsPollableMessageChannelSpec(ConnectionFactory connectionFactory) {
this(new JmsChannelFactoryBean(false), connectionFactory);
}
JmsPollableMessageChannelSpec(JmsChannelFactoryBean jmsChannelFactoryBean, ConnectionFactory connectionFactory) {
this.jmsChannelFactoryBean = jmsChannelFactoryBean;
this.jmsChannelFactoryBean.setConnectionFactory(connectionFactory);
this.jmsChannelFactoryBean.setSingleton(false);
this.jmsChannelFactoryBean.setBeanFactory(new DefaultListableBeanFactory());
}
@Override
protected S id(String id) {
this.jmsChannelFactoryBean.setBeanName(id);
return super.id(id);
}
/**
* Configure the destination name that backs this channel.
* @param destination the destination.
* @return the current {@link MessageChannelSpec}.
*/
public S destination(String destination) {
this.jmsChannelFactoryBean.setDestinationName(destination);
return _this();
}
/**
* @param destinationResolver the destinationResolver.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setDestinationResolver(DestinationResolver)
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setDestinationResolver(DestinationResolver)
*/
public S destinationResolver(DestinationResolver destinationResolver) {
this.jmsChannelFactoryBean.setDestinationResolver(destinationResolver);
return _this();
}
/**
* Configure the destination that backs this channel.
* @param destination the destination.
* @return the current {@link MessageChannelSpec}.
*/
public S destination(Destination destination) {
this.jmsChannelFactoryBean.setDestination(destination);
return _this();
}
/**
* Configure a message selector in the
* {@link org.springframework.jms.listener.DefaultMessageListenerContainer} (when
* message driven) or the {@link org.springframework.jms.core.JmsTemplate} (when
* polled).
* @param messageSelector the messageSelector.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setMessageSelector(String)
* @see org.springframework.jms.core.JmsTemplate#receiveSelectedAndConvert(String)
*/
public S messageSelector(String messageSelector) {
this.jmsChannelFactoryBean.setMessageSelector(messageSelector);
return _this();
}
/**
* Configure the {@link MessageConverter} used for both sending and
* receiving.
* @param messageConverter the messageConverter.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setMessageConverter(MessageConverter)
*/
public S jmsMessageConverter(MessageConverter messageConverter) {
this.jmsChannelFactoryBean.setMessageConverter(messageConverter);
return _this();
}
/**
* @param deliveryPersistent the deliveryPersistent.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setDeliveryPersistent(boolean)
*/
public S deliveryPersistent(boolean deliveryPersistent) {
this.jmsChannelFactoryBean.setDeliveryPersistent(deliveryPersistent);
return _this();
}
/**
* @param explicitQosEnabled the explicitQosEnabled.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setExplicitQosEnabled(boolean)
*/
public S explicitQosEnabled(boolean explicitQosEnabled) {
this.jmsChannelFactoryBean.setExplicitQosEnabled(explicitQosEnabled);
return _this();
}
/**
* @param messageIdEnabled the messageIdEnabled.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setMessageIdEnabled(boolean)
*/
public S messageIdEnabled(boolean messageIdEnabled) {
this.jmsChannelFactoryBean.setMessageIdEnabled(messageIdEnabled);
return _this();
}
/**
* @param messageTimestampEnabled the messageTimestampEnabled.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setMessageTimestampEnabled(boolean)
*/
public S messageTimestampEnabled(boolean messageTimestampEnabled) {
this.jmsChannelFactoryBean.setMessageTimestampEnabled(messageTimestampEnabled);
return _this();
}
/**
* Default priority. May be overridden at run time with a message
* priority header.
* @param priority the priority.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setPriority(int)
*/
public S priority(int priority) {
this.jmsChannelFactoryBean.setPriority(priority);
return _this();
}
/**
* @param timeToLive the timeToLive.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setTimeToLive(long)
*/
public S timeToLive(long timeToLive) {
this.jmsChannelFactoryBean.setTimeToLive(timeToLive);
return _this();
}
/**
* @param receiveTimeout the receiveTimeout.
* @return the current {@link MessageChannelSpec}.
* @see org.springframework.jms.core.JmsTemplate#setReceiveTimeout(long)
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setReceiveTimeout(long)
*/
public S receiveTimeout(long receiveTimeout) {
this.jmsChannelFactoryBean.setReceiveTimeout(receiveTimeout);
return _this();
}
/**
* @param sessionAcknowledgeMode the acknowledgement mode constant
* @return the current {@link MessageChannelSpec}.
* @see javax.jms.Session#AUTO_ACKNOWLEDGE etc.
*/
public S sessionAcknowledgeMode(int sessionAcknowledgeMode) {
this.jmsChannelFactoryBean.setSessionAcknowledgeMode(sessionAcknowledgeMode);
return _this();
}
/**
* Configure transactional sessions for both the
* {@link org.springframework.jms.core.JmsTemplate} (sends and polled receives) and
* {@link org.springframework.jms.listener.DefaultMessageListenerContainer}
* (message-driven receives).
* @param sessionTransacted the sessionTransacted.
* @return the current {@link MessageChannelSpec}.
*/
public S sessionTransacted(boolean sessionTransacted) {
this.jmsChannelFactoryBean.setSessionTransacted(sessionTransacted);
return _this();
}
@Override
protected AbstractJmsChannel doGet() {
try {
this.channel = this.jmsChannelFactoryBean.getObject();
}
catch (Exception e) {
throw new BeanCreationException("Cannot create the JMS MessageChannel", e);
}
return super.doGet();
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import javax.jms.ConnectionFactory;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
/**
* A {@link JmsMessageChannelSpec} for a {@link org.springframework.integration.jms.SubscribableJmsChannel}
* configured with a topic.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsPublishSubscribeMessageChannelSpec
extends JmsMessageChannelSpec<JmsPublishSubscribeMessageChannelSpec> {
JmsPublishSubscribeMessageChannelSpec(ConnectionFactory connectionFactory) {
super(connectionFactory);
this.jmsChannelFactoryBean.setPubSubDomain(true);
}
/**
* @param durable the durable.
* @return the current {@link JmsPublishSubscribeMessageChannelSpec}.
* @see org.springframework.jms.listener.AbstractMessageListenerContainer#setSubscriptionDurable(boolean)
*/
public JmsPublishSubscribeMessageChannelSpec subscriptionDurable(boolean durable) {
this.jmsChannelFactoryBean.setSubscriptionDurable(durable);
return _this();
}
/**
* @param durableSubscriptionName the durableSubscriptionName.
* @return the current {@link JmsPublishSubscribeMessageChannelSpec}.
* @see org.springframework.jms.listener.AbstractMessageListenerContainer#setDurableSubscriptionName(String)
*/
public JmsPublishSubscribeMessageChannelSpec durableSubscriptionName(String durableSubscriptionName) {
this.jmsChannelFactoryBean.setDurableSubscriptionName(durableSubscriptionName);
return _this();
}
/**
* @param clientId the clientId.
* @return the current {@link JmsPublishSubscribeMessageChannelSpec}.
* @see org.springframework.jms.listener.AbstractMessageListenerContainer#setClientId(String)
*/
public JmsPublishSubscribeMessageChannelSpec clientId(String clientId) {
this.jmsChannelFactoryBean.setClientId(clientId);
return _this();
}
/**
* Only applies if the {@link #containerType(Class)} is a {@link DefaultMessageListenerContainer}
* or a {@link org.springframework.jms.listener.SimpleMessageListenerContainer}.
* @param pubSubNoLocal the pubSubNoLocal.
* @return the current {@link JmsPublishSubscribeMessageChannelSpec}.
* @see org.springframework.jms.listener.DefaultMessageListenerContainer#setPubSubNoLocal(boolean)
* @see org.springframework.jms.listener.SimpleMessageListenerContainer#setPubSubNoLocal(boolean)
*/
public JmsPublishSubscribeMessageChannelSpec pubSubNoLocal(boolean pubSubNoLocal) {
this.jmsChannelFactoryBean.setPubSubNoLocal(pubSubNoLocal);
return _this();
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import org.springframework.integration.jms.DynamicJmsTemplate;
import org.springframework.jms.support.converter.MessageConverter;
/**
* A {@link JmsDestinationAccessorSpec} for a {@link DynamicJmsTemplate}.
*
* @author Artem Bilan
* @since 5.0
*/
public class JmsTemplateSpec extends JmsDestinationAccessorSpec<JmsTemplateSpec, DynamicJmsTemplate> {
JmsTemplateSpec() {
super(new DynamicJmsTemplate());
}
/**
* @param messageConverter the messageConverter.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setMessageConverter(MessageConverter)
*/
public JmsTemplateSpec jmsMessageConverter(MessageConverter messageConverter) {
this.target.setMessageConverter(messageConverter);
return _this();
}
/**
* @param deliveryPersistent the deliveryPersistent.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setDeliveryPersistent(boolean)
*/
public JmsTemplateSpec deliveryPersistent(boolean deliveryPersistent) {
this.target.setDeliveryPersistent(deliveryPersistent);
return _this();
}
/**
* @param explicitQosEnabled the explicitQosEnabled.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setExplicitQosEnabled(boolean)
*/
public JmsTemplateSpec explicitQosEnabled(boolean explicitQosEnabled) {
this.target.setExplicitQosEnabled(explicitQosEnabled);
return _this();
}
/**
* May be overridden at run time by the message priority header.
* @param priority the priority.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setPriority(int)
*/
public JmsTemplateSpec priority(int priority) {
this.target.setPriority(priority);
return _this();
}
/**
* @param timeToLive the timeToLive.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setTimeToLive(long)
*/
public JmsTemplateSpec timeToLive(long timeToLive) {
this.target.setTimeToLive(timeToLive);
return _this();
}
/**
* @param receiveTimeout the receiveTimeout.
* @return the spec.
* @see org.springframework.jms.core.JmsTemplate#setReceiveTimeout(long)
*/
public JmsTemplateSpec receiveTimeout(long receiveTimeout) {
this.target.setReceiveTimeout(receiveTimeout);
return _this();
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides JMS Component support for the Java DSL.
*/
package org.springframework.integration.jms.dsl;

View File

@@ -0,0 +1,434 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.jms.dsl;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.channel.ChannelInterceptorAware;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.FixedSubscriberChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.config.GlobalChannelInterceptor;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlowDefinition;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.Pollers;
import org.springframework.integration.dsl.channel.MessageChannels;
import org.springframework.integration.endpoint.MethodInvokingMessageSource;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptorAdapter;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Artem Bilan
* @author Gary Russell
* @author Nasko Vasilev
*
* @since 5.0
*/
@RunWith(SpringRunner.class)
@DirtiesContext
public class JmsTests {
@Autowired
private ListableBeanFactory beanFactory;
@Autowired
private ControlBusGateway controlBus;
@Autowired
@Qualifier("flow1QueueChannel")
private PollableChannel outputChannel;
@Autowired
@Qualifier("jmsOutboundFlow.input")
private MessageChannel jmsOutboundInboundChannel;
@Autowired
@Qualifier("jmsOutboundInboundReplyChannel")
private PollableChannel jmsOutboundInboundReplyChannel;
@Autowired
@Qualifier("jmsOutboundGatewayFlow.input")
private MessageChannel jmsOutboundGatewayChannel;
@Autowired
private TestChannelInterceptor testChannelInterceptor;
@Autowired
private ConnectionFactory jmsConnectionFactory;
@Autowired
private PollableChannel jmsPubSubBridgeChannel;
@Autowired
@Qualifier("jmsOutboundGateway.handler")
private MessageHandler jmsOutboundGatewayHandler;
@Autowired
private AtomicBoolean jmsMessageDrivenChannelCalled;
@Autowired
private AtomicBoolean jmsInboundGatewayChannelCalled;
@Test
public void testPollingFlow() {
this.controlBus.send("@'jmsTests.ContextConfiguration.integerMessageSource.inboundChannelAdapter'.start()");
assertThat(this.beanFactory.getBean("integerChannel"), instanceOf(FixedSubscriberChannel.class));
for (int i = 0; i < 5; i++) {
Message<?> message = this.outputChannel.receive(20000);
assertNotNull(message);
assertEquals("" + i, message.getPayload());
}
this.controlBus.send("@'jmsTests.ContextConfiguration.integerMessageSource.inboundChannelAdapter'.stop()");
assertTrue(((ChannelInterceptorAware) this.outputChannel).getChannelInterceptors()
.contains(this.testChannelInterceptor));
assertThat(this.testChannelInterceptor.invoked.get(), Matchers.greaterThanOrEqualTo(5));
}
@Test
public void testJmsOutboundInboundFlow() {
this.jmsOutboundInboundChannel.send(MessageBuilder.withPayload("hello THROUGH the JMS")
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "jmsInbound")
.build());
Message<?> receive = this.jmsOutboundInboundReplyChannel.receive(10000);
assertNotNull(receive);
assertEquals("HELLO THROUGH THE JMS", receive.getPayload());
this.jmsOutboundInboundChannel.send(MessageBuilder.withPayload("hello THROUGH the JMS")
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "jmsMessageDriven")
.build());
receive = this.jmsOutboundInboundReplyChannel.receive(10000);
assertNotNull(receive);
assertEquals("hello through the jms", receive.getPayload());
assertTrue(this.jmsMessageDrivenChannelCalled.get());
this.jmsOutboundInboundChannel.send(MessageBuilder.withPayload(" foo ")
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "containerSpecDestination")
.build());
receive = this.jmsOutboundInboundReplyChannel.receive(10000);
assertNotNull(receive);
assertEquals("foo", receive.getPayload());
}
@Test
public void testJmsPipelineFlow() {
assertEquals(new Long(10000),
TestUtils.getPropertyValue(this.jmsOutboundGatewayHandler, "idleReplyContainerTimeout", Long.class));
PollableChannel replyChannel = new QueueChannel();
Message<String> message = MessageBuilder.withPayload("hello through the jms pipeline")
.setReplyChannel(replyChannel)
.setHeader("destination", "jmsPipelineTest")
.build();
this.jmsOutboundGatewayChannel.send(message);
Message<?> receive = replyChannel.receive(5000);
assertNotNull(receive);
assertEquals("HELLO THROUGH THE JMS PIPELINE", receive.getPayload());
assertTrue(this.jmsInboundGatewayChannelCalled.get());
}
@Test
public void testPubSubFlow() {
JmsTemplate template = new JmsTemplate(this.jmsConnectionFactory);
template.setPubSubDomain(true);
template.setDefaultDestinationName("pubsub");
template.convertAndSend("foo");
Message<?> received = this.jmsPubSubBridgeChannel.receive(5000);
assertNotNull(received);
assertEquals("foo", received.getPayload());
}
@Autowired
private CountDownLatch redeliveryLatch;
@Test
public void testJmsRedeliveryFlow() throws InterruptedException {
this.jmsOutboundInboundChannel.send(MessageBuilder.withPayload("foo")
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "jmsMessageDrivenRedelivery")
.build());
assertTrue(this.redeliveryLatch.await(10, TimeUnit.SECONDS));
}
@MessagingGateway(defaultRequestChannel = "controlBus.input")
private interface ControlBusGateway {
void send(String command);
}
@Configuration
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public static class ContextConfiguration {
@Bean
public ConnectionFactory cachingConnectionFactory() {
return new CachingConnectionFactory(jmsConnectionFactory());
}
@Bean
public ActiveMQConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
"vm://localhost?broker.persistent=false");
activeMQConnectionFactory.setTrustAllPackages(true);
return activeMQConnectionFactory;
}
@Bean
public JmsTemplate jmsTemplate() {
return new JmsTemplate(jmsConnectionFactory());
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedRate(500).get();
}
@Bean
public IntegrationFlow controlBus() {
return IntegrationFlowDefinition::controlBus;
}
@Bean
@InboundChannelAdapter(value = "flow1.input", autoStartup = "false", poller = @Poller(fixedRate = "100"))
public MessageSource<?> integerMessageSource() {
MethodInvokingMessageSource source = new MethodInvokingMessageSource();
source.setObject(new AtomicInteger());
source.setMethodName("getAndIncrement");
return source;
}
@Bean
public IntegrationFlow flow1() {
return f -> f
.fixedSubscriberChannel("integerChannel")
.transform("payload.toString()")
.channel(Jms.pollableChannel("flow1QueueChannel", cachingConnectionFactory())
.destination("flow1QueueChannel"));
}
@Bean
public IntegrationFlow jmsOutboundFlow() {
return f -> f.handle(Jms.outboundAdapter(jmsConnectionFactory())
.destinationExpression("headers." + SimpMessageHeaderAccessor.DESTINATION_HEADER));
}
@Bean
public MessageChannel jmsOutboundInboundReplyChannel() {
return MessageChannels.queue().get();
}
@Bean
public IntegrationFlow jmsInboundFlow() {
return IntegrationFlows
.from(Jms.inboundAdapter(cachingConnectionFactory()).destination("jmsInbound"))
.<String, String>transform(String::toUpperCase)
.channel(this.jmsOutboundInboundReplyChannel())
.get();
}
@Bean
public IntegrationFlow pubSubFlow() {
return IntegrationFlows
.from(Jms.publishSubscribeChannel(jmsConnectionFactory())
.destination("pubsub"))
.channel(c -> c.queue("jmsPubSubBridgeChannel"))
.get();
}
@Bean
public IntegrationFlow jmsMessageDrivenFlow() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory())
.outputChannel(jmsMessageDrivenInputChannel())
.destination("jmsMessageDriven"))
.<String, String>transform(String::toLowerCase)
.channel(jmsOutboundInboundReplyChannel())
.get();
}
@Bean
public AtomicBoolean jmsMessageDrivenChannelCalled() {
return new AtomicBoolean();
}
@Bean
public MessageChannel jmsMessageDrivenInputChannel() {
DirectChannel directChannel = new DirectChannel();
directChannel.addInterceptor(new ChannelInterceptorAdapter() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
jmsMessageDrivenChannelCalled().set(true);
return super.preSend(message, channel);
}
});
return directChannel;
}
@Bean
public IntegrationFlow jmsMessageDrivenFlowWithContainer() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(
Jms.container(jmsConnectionFactory(), "containerSpecDestination")
.pubSubDomain(false)
.taskExecutor(Executors.newCachedThreadPool())
.get()))
.transform(String::trim)
.channel(jmsOutboundInboundReplyChannel())
.get();
}
@Bean
public IntegrationFlow jmsOutboundGatewayFlow() {
return f -> f.handle(Jms.outboundGateway(jmsConnectionFactory())
.replyContainer(c -> c.idleReplyContainerTimeout(10))
.requestDestination("jmsPipelineTest"),
e -> e.id("jmsOutboundGateway"));
}
@Bean
public IntegrationFlow jmsInboundGatewayFlow() {
return IntegrationFlows.from(Jms.inboundGateway(jmsConnectionFactory())
.requestChannel(jmsInboundGatewayInputChannel())
.destination("jmsPipelineTest"))
.<String, String>transform(String::toUpperCase)
.get();
}
@Bean
public AtomicBoolean jmsInboundGatewayChannelCalled() {
return new AtomicBoolean();
}
@Bean
public MessageChannel jmsInboundGatewayInputChannel() {
DirectChannel directChannel = new DirectChannel();
directChannel.addInterceptor(new ChannelInterceptorAdapter() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
jmsInboundGatewayChannelCalled().set(true);
return super.preSend(message, channel);
}
});
return directChannel;
}
@Bean
public IntegrationFlow jmsMessageDrivenRedeliveryFlow() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory())
.errorChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
.destination("jmsMessageDrivenRedelivery"))
.<String, String>transform(p -> {
throw new RuntimeException("intentional");
})
.get();
}
@Bean
public CountDownLatch redeliveryLatch() {
return new CountDownLatch(3);
}
@Bean
public IntegrationFlow errorHandlingFlow() {
return IntegrationFlows.from(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
.handle(m -> {
MessagingException exception = (MessagingException) m.getPayload();
redeliveryLatch().countDown();
throw exception;
})
.get();
}
}
@Component
@GlobalChannelInterceptor(patterns = "flow1QueueChannel")
public static class TestChannelInterceptor extends ChannelInterceptorAdapter {
private final AtomicInteger invoked = new AtomicInteger();
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
this.invoked.incrementAndGet();
return message;
}
}
}