Example usage for org.springframework.messaging SubscribableChannel subscribe

List of usage examples for org.springframework.messaging SubscribableChannel subscribe

Introduction

In this page you can find the example usage for org.springframework.messaging SubscribableChannel subscribe.

Prototype

boolean subscribe(MessageHandler handler);

Source Link

Document

Register a message handler.

Usage

From source file:com.acme.ModuleConfigurationTest.java

@Test
public void test() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    Properties properties = new Properties();
    properties.put("prefix", "foo");
    properties.put("suffix", "bar");
    context.getEnvironment().getPropertySources().addLast(new PropertiesPropertySource("options", properties));
    context.register(TestConfiguration.class);
    context.refresh();//from  ww  w  . j a  v a  2s .c o m

    MessageChannel input = context.getBean("input", MessageChannel.class);
    SubscribableChannel output = context.getBean("output", SubscribableChannel.class);

    final AtomicBoolean handled = new AtomicBoolean();
    output.subscribe(new MessageHandler() {
        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            handled.set(true);
            assertEquals("foohellobar", message.getPayload());
        }
    });
    input.send(new GenericMessage<String>("hello"));
    assertTrue(handled.get());
}

From source file:org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.java

/**
 * Register an error channel for the destination when an async send error is received.
 * Bridge the channel to the global error channel (if present).
 * @param destination the destination.//from w  w w.j  a v a 2 s.  c  o  m
 * @return the channel.
 */
private SubscribableChannel registerErrorInfrastructure(ProducerDestination destination) {
    ConfigurableListableBeanFactory beanFactory = getApplicationContext().getBeanFactory();
    String errorChannelName = errorsBaseName(destination);
    SubscribableChannel errorChannel = null;
    if (getApplicationContext().containsBean(errorChannelName)) {
        Object errorChannelObject = getApplicationContext().getBean(errorChannelName);
        if (!(errorChannelObject instanceof SubscribableChannel)) {
            throw new IllegalStateException(
                    "Error channel '" + errorChannelName + "' must be a SubscribableChannel");
        }
        errorChannel = (SubscribableChannel) errorChannelObject;
    } else {
        errorChannel = new PublishSubscribeChannel();
        beanFactory.registerSingleton(errorChannelName, errorChannel);
        errorChannel = (PublishSubscribeChannel) beanFactory.initializeBean(errorChannel, errorChannelName);
    }
    MessageChannel defaultErrorChannel = null;
    if (getApplicationContext().containsBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) {
        defaultErrorChannel = getApplicationContext().getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME,
                MessageChannel.class);
    }
    if (defaultErrorChannel != null) {
        BridgeHandler errorBridge = new BridgeHandler();
        errorBridge.setOutputChannel(defaultErrorChannel);
        errorChannel.subscribe(errorBridge);
        String errorBridgeHandlerName = getErrorBridgeName(destination);
        beanFactory.registerSingleton(errorBridgeHandlerName, errorBridge);
        beanFactory.initializeBean(errorBridge, errorBridgeHandlerName);
    }
    return errorChannel;
}

From source file:org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.java

/**
 * Build an errorChannelRecoverer that writes to a pub/sub channel for the destination
 * when an exception is thrown to a consumer.
 * @param destination the destination./* w  w w  . j a  v a  2 s  .c o  m*/
 * @param group the group.
 * @param consumerProperties the properties.
 * @param true if this is for a polled consumer.
 * @return the ErrorInfrastructure which is a holder for the error channel, the recoverer and the
 * message handler that is subscribed to the channel.
 */
protected final ErrorInfrastructure registerErrorInfrastructure(ConsumerDestination destination, String group,
        C consumerProperties, boolean polled) {

    ErrorMessageStrategy errorMessageStrategy = getErrorMessageStrategy();
    ConfigurableListableBeanFactory beanFactory = getApplicationContext().getBeanFactory();
    String errorChannelName = errorsBaseName(destination, group, consumerProperties);
    SubscribableChannel errorChannel = null;
    if (getApplicationContext().containsBean(errorChannelName)) {
        Object errorChannelObject = getApplicationContext().getBean(errorChannelName);
        if (!(errorChannelObject instanceof SubscribableChannel)) {
            throw new IllegalStateException(
                    "Error channel '" + errorChannelName + "' must be a SubscribableChannel");
        }
        errorChannel = (SubscribableChannel) errorChannelObject;
    } else {
        errorChannel = new BinderErrorChannel();
        beanFactory.registerSingleton(errorChannelName, errorChannel);
        errorChannel = (LastSubscriberAwareChannel) beanFactory.initializeBean(errorChannel, errorChannelName);
    }
    ErrorMessageSendingRecoverer recoverer;
    if (errorMessageStrategy == null) {
        recoverer = new ErrorMessageSendingRecoverer(errorChannel);
    } else {
        recoverer = new ErrorMessageSendingRecoverer(errorChannel, errorMessageStrategy);
    }
    String recovererBeanName = getErrorRecovererName(destination, group, consumerProperties);
    beanFactory.registerSingleton(recovererBeanName, recoverer);
    beanFactory.initializeBean(recoverer, recovererBeanName);
    MessageHandler handler;
    if (polled) {
        handler = getPolledConsumerErrorMessageHandler(destination, group, consumerProperties);
    } else {
        handler = getErrorMessageHandler(destination, group, consumerProperties);
    }
    MessageChannel defaultErrorChannel = null;
    if (getApplicationContext().containsBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) {
        defaultErrorChannel = getApplicationContext().getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME,
                MessageChannel.class);
    }
    if (handler == null && errorChannel instanceof LastSubscriberAwareChannel) {
        handler = getDefaultErrorMessageHandler((LastSubscriberAwareChannel) errorChannel,
                defaultErrorChannel != null);
    }
    String errorMessageHandlerName = getErrorMessageHandlerName(destination, group, consumerProperties);
    if (handler != null) {
        beanFactory.registerSingleton(errorMessageHandlerName, handler);
        beanFactory.initializeBean(handler, errorMessageHandlerName);
        errorChannel.subscribe(handler);
    }
    if (defaultErrorChannel != null) {
        BridgeHandler errorBridge = new BridgeHandler();
        errorBridge.setOutputChannel(defaultErrorChannel);
        errorChannel.subscribe(errorBridge);
        String errorBridgeHandlerName = getErrorBridgeName(destination, group, consumerProperties);
        beanFactory.registerSingleton(errorBridgeHandlerName, errorBridge);
        beanFactory.initializeBean(errorBridge, errorBridgeHandlerName);
    }
    return new ErrorInfrastructure(errorChannel, recoverer, handler);
}

From source file:org.springframework.cloud.stream.binder.rabbit.RabbitBinderTests.java

private void testAutoBindDLQPartionedConsumerFirstWithRepublishGuts(final boolean withRetry) throws Exception {
    RabbitTestBinder binder = getBinder();
    ExtendedConsumerProperties<RabbitConsumerProperties> properties = createConsumerProperties();
    properties.getExtension().setPrefix("bindertest.");
    properties.getExtension().setAutoBindDlq(true);
    properties.getExtension().setRepublishToDlq(true);
    properties.getExtension().setRepublishDeliveyMode(MessageDeliveryMode.NON_PERSISTENT);
    properties.setMaxAttempts(withRetry ? 2 : 1);
    properties.setPartitioned(true);/*from   ww  w  .  j  a  va 2s . c o m*/
    properties.setInstanceIndex(0);
    DirectChannel input0 = createBindableChannel("input", createConsumerBindingProperties(properties));
    input0.setBeanName("test.input0DLQ");
    Binding<MessageChannel> input0Binding = binder.bindConsumer("partPubDLQ.0", "dlqPartGrp", input0,
            properties);
    Binding<MessageChannel> defaultConsumerBinding1 = binder.bindConsumer("partPubDLQ.0", "default",
            new QueueChannel(), properties);
    properties.setInstanceIndex(1);
    DirectChannel input1 = createBindableChannel("input1", createConsumerBindingProperties(properties));
    input1.setBeanName("test.input1DLQ");
    Binding<MessageChannel> input1Binding = binder.bindConsumer("partPubDLQ.0", "dlqPartGrp", input1,
            properties);
    Binding<MessageChannel> defaultConsumerBinding2 = binder.bindConsumer("partPubDLQ.0", "default",
            new QueueChannel(), properties);

    ExtendedProducerProperties<RabbitProducerProperties> producerProperties = createProducerProperties();
    producerProperties.getExtension().setPrefix("bindertest.");
    producerProperties.getExtension().setAutoBindDlq(true);
    producerProperties.setPartitionKeyExtractorClass(PartitionTestSupport.class);
    producerProperties.setPartitionSelectorClass(PartitionTestSupport.class);
    producerProperties.setPartitionCount(2);
    BindingProperties bindingProperties = createProducerBindingProperties(producerProperties);
    DirectChannel output = createBindableChannel("output", bindingProperties);
    output.setBeanName("test.output");
    Binding<MessageChannel> outputBinding = binder.bindProducer("partPubDLQ.0", output, producerProperties);

    final CountDownLatch latch0 = new CountDownLatch(1);
    input0.subscribe(new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            if (latch0.getCount() <= 0) {
                throw new RuntimeException("dlq");
            }
            latch0.countDown();
        }

    });

    final CountDownLatch latch1 = new CountDownLatch(1);
    input1.subscribe(new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            if (latch1.getCount() <= 0) {
                throw new RuntimeException("dlq");
            }
            latch1.countDown();
        }

    });

    ApplicationContext context = TestUtils.getPropertyValue(binder.getBinder(), "applicationContext",
            ApplicationContext.class);
    SubscribableChannel boundErrorChannel = context.getBean("bindertest.partPubDLQ.0.dlqPartGrp-0.errors",
            SubscribableChannel.class);
    SubscribableChannel globalErrorChannel = context.getBean("errorChannel", SubscribableChannel.class);
    final AtomicReference<Message<?>> boundErrorChannelMessage = new AtomicReference<>();
    final AtomicReference<Message<?>> globalErrorChannelMessage = new AtomicReference<>();
    final AtomicBoolean hasRecovererInCallStack = new AtomicBoolean(!withRetry);
    boundErrorChannel.subscribe(new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            boundErrorChannelMessage.set(message);
            String stackTrace = Arrays.toString(new RuntimeException().getStackTrace());
            hasRecovererInCallStack.set(stackTrace.contains("ErrorMessageSendingRecoverer"));
        }

    });
    globalErrorChannel.subscribe(new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            globalErrorChannelMessage.set(message);
        }

    });

    output.send(new GenericMessage<>(1));
    assertThat(latch1.await(10, TimeUnit.SECONDS)).isTrue();

    output.send(new GenericMessage<>(0));
    assertThat(latch0.await(10, TimeUnit.SECONDS)).isTrue();

    output.send(new GenericMessage<>(1));

    RabbitTemplate template = new RabbitTemplate(this.rabbitAvailableRule.getResource());
    template.setReceiveTimeout(10000);

    String streamDLQName = "bindertest.partPubDLQ.0.dlqPartGrp.dlq";

    org.springframework.amqp.core.Message received = template.receive(streamDLQName);
    assertThat(received).isNotNull();
    assertThat(received.getMessageProperties().getHeaders().get("x-original-routingKey"))
            .isEqualTo("partPubDLQ.0-1");
    assertThat(received.getMessageProperties().getHeaders()).doesNotContainKey(BinderHeaders.PARTITION_HEADER);
    assertThat(received.getMessageProperties().getReceivedDeliveryMode())
            .isEqualTo(MessageDeliveryMode.NON_PERSISTENT);

    output.send(new GenericMessage<>(0));
    received = template.receive(streamDLQName);
    assertThat(received).isNotNull();
    assertThat(received.getMessageProperties().getHeaders().get("x-original-routingKey"))
            .isEqualTo("partPubDLQ.0-0");
    assertThat(received.getMessageProperties().getHeaders()).doesNotContainKey(BinderHeaders.PARTITION_HEADER);

    // verify we got a message on the dedicated error channel and the global (via bridge)
    assertThat(boundErrorChannelMessage.get()).isNotNull();
    assertThat(globalErrorChannelMessage.get()).isNotNull();
    assertThat(hasRecovererInCallStack.get()).isEqualTo(withRetry);

    input0Binding.unbind();
    input1Binding.unbind();
    defaultConsumerBinding1.unbind();
    defaultConsumerBinding2.unbind();
    outputBinding.unbind();
}

From source file:org.springframework.integration.samples.advance.testing.jms.JmsMockTests.java

/**
 * Provide a message via a mock JMS template and wait for the specified timeout to receive the message
 * on the expected channel/*from  ww  w. j  av  a  2 s . c  o  m*/
 * @param obj The message provided to the poller (currently must be a String)
 * @param expectedOutputChannel The expected output channel
 * @param handler An instance of CountDownHandler to handle (verify) the output message
 * @param timeoutMillisec The timeout period. Note that this must allow at least enough time
 * to process the entire flow. Only set if the default is
 * not long enough
 * @return true if the message was received on the expected channel
 * @throws JMSException
 * @throws InterruptedException
 */
protected boolean verifyJmsMessageOnOutputChannel(Object obj, SubscribableChannel expectedOutputChannel,
        CountDownHandler handler, int timeoutMillisec) throws JMSException, InterruptedException {

    if (!(obj instanceof String)) {
        throw new IllegalArgumentException("Only TextMessage is currently supported");
    }

    /*
     * Use mocks to create a message returned to the JMS inbound adapter. It is assumed that the JmsTemplate
     * is also a mock.
     */

    this.testMessageHolder.set((String) obj);
    CountDownLatch latch = new CountDownLatch(1);
    handler.setLatch(latch);

    expectedOutputChannel.subscribe(handler);

    this.jmsInboundChannelAdapter.start();

    boolean latchCountedToZero = latch.await(timeoutMillisec, TimeUnit.MILLISECONDS);

    if (!latchCountedToZero) {
        LOGGER.warn(String.format("The specified waiting time of the latch (%s ms) elapsed.", timeoutMillisec));
    }

    return latchCountedToZero;

}

From source file:org.springframework.integration.samples.tcpclientserver.TcpServerCustomSerializerTest.java

@Test
public void testHappyPath() {

    // add a listener to this channel, otherwise there is not one defined
    // the reason we use a listener here is so we can assert truths on the
    // message and/or payload
    SubscribableChannel channel = (SubscribableChannel) incomingServerChannel;
    channel.subscribe(new AbstractReplyProducingMessageHandler() {

        @Override//from   www .  j a  va2  s  . co  m
        protected Object handleRequestMessage(Message<?> requestMessage) {
            CustomOrder payload = (CustomOrder) requestMessage.getPayload();

            // we assert during the processing of the messaging that the
            // payload is just the content we wanted to send without the
            // framing bytes (STX/ETX)
            assertEquals(123, payload.getNumber());
            assertEquals("PINGPONG02", payload.getSender());
            assertEquals("You got it to work!", payload.getMessage());
            return requestMessage;
        }
    });

    String sourceMessage = "123PINGPONG02000019You got it to work!";

    // use the java socket API to make the connection to the server
    Socket socket = null;
    Writer out = null;
    BufferedReader in = null;

    try {
        socket = new Socket("localhost", this.serverConnectionFactory.getPort());
        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        out.write(sourceMessage);
        out.flush();

        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        StringBuffer str = new StringBuffer();

        int c;
        while ((c = in.read()) != -1) {
            str.append((char) c);
        }

        String response = str.toString();
        assertEquals(sourceMessage, response);

    } catch (IOException e) {
        LOGGER.error(e.getMessage(), e);
        fail(String.format("Test (port: %s) ended with an exception: %s",
                this.serverConnectionFactory.getPort(), e.getMessage()));
    } finally {
        try {
            socket.close();
            out.close();
            in.close();

        } catch (Exception e) {
            // swallow exception
        }

    }
}