Search in sources :

Example 1 with StompReceiptEvent

use of org.springframework.integration.stomp.event.StompReceiptEvent in project spring-integration by spring-projects.

the class StompServerIntegrationTests method testStompAdapters.

@Test
public void testStompAdapters() throws Exception {
    ConfigurableApplicationContext context1 = new AnnotationConfigApplicationContext(ContextConfiguration.class);
    ConfigurableApplicationContext context2 = new AnnotationConfigApplicationContext(ContextConfiguration.class);
    PollableChannel stompEvents1 = context1.getBean("stompEvents", PollableChannel.class);
    PollableChannel stompEvents2 = context2.getBean("stompEvents", PollableChannel.class);
    PollableChannel stompInputChannel1 = context1.getBean("stompInputChannel", PollableChannel.class);
    PollableChannel stompInputChannel2 = context2.getBean("stompInputChannel", PollableChannel.class);
    MessageChannel stompOutputChannel1 = context1.getBean("stompOutputChannel", MessageChannel.class);
    MessageChannel stompOutputChannel2 = context2.getBean("stompOutputChannel", MessageChannel.class);
    Message<?> eventMessage;
    do {
        eventMessage = stompEvents1.receive(10000);
    } while (eventMessage != null && !(eventMessage.getPayload() instanceof StompSessionConnectedEvent));
    assertNotNull(eventMessage);
    eventMessage = stompEvents1.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompReceiptEvent.class));
    StompReceiptEvent stompReceiptEvent = (StompReceiptEvent) eventMessage.getPayload();
    assertEquals(StompCommand.SUBSCRIBE, stompReceiptEvent.getStompCommand());
    assertEquals("/topic/myTopic", stompReceiptEvent.getDestination());
    eventMessage = stompEvents2.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompSessionConnectedEvent.class));
    eventMessage = stompEvents2.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompReceiptEvent.class));
    stompReceiptEvent = (StompReceiptEvent) eventMessage.getPayload();
    assertEquals(StompCommand.SUBSCRIBE, stompReceiptEvent.getStompCommand());
    assertEquals("/topic/myTopic", stompReceiptEvent.getDestination());
    stompOutputChannel1.send(new GenericMessage<byte[]>("Hello, Client#2!".getBytes()));
    Message<?> receive11 = stompInputChannel1.receive(10000);
    Message<?> receive21 = stompInputChannel2.receive(10000);
    assertNotNull(receive11);
    assertNotNull(receive21);
    assertArrayEquals("Hello, Client#2!".getBytes(), (byte[]) receive11.getPayload());
    assertArrayEquals("Hello, Client#2!".getBytes(), (byte[]) receive21.getPayload());
    stompOutputChannel2.send(new GenericMessage<byte[]>("Hello, Client#1!".getBytes()));
    Message<?> receive12 = stompInputChannel1.receive(10000);
    Message<?> receive22 = stompInputChannel2.receive(10000);
    assertNotNull(receive12);
    assertNotNull(receive22);
    assertArrayEquals("Hello, Client#1!".getBytes(), (byte[]) receive12.getPayload());
    assertArrayEquals("Hello, Client#1!".getBytes(), (byte[]) receive22.getPayload());
    eventMessage = stompEvents2.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompReceiptEvent.class));
    stompReceiptEvent = (StompReceiptEvent) eventMessage.getPayload();
    assertEquals(StompCommand.SEND, stompReceiptEvent.getStompCommand());
    assertEquals("/topic/myTopic", stompReceiptEvent.getDestination());
    assertArrayEquals("Hello, Client#1!".getBytes(), (byte[]) stompReceiptEvent.getMessage().getPayload());
    Lifecycle stompInboundChannelAdapter2 = context2.getBean("stompInboundChannelAdapter", Lifecycle.class);
    stompInboundChannelAdapter2.stop();
    stompOutputChannel1.send(new GenericMessage<byte[]>("How do you do?".getBytes()));
    Message<?> receive13 = stompInputChannel1.receive(10000);
    assertNotNull(receive13);
    Message<?> receive23 = stompInputChannel2.receive(100);
    assertNull(receive23);
    stompInboundChannelAdapter2.start();
    eventMessage = stompEvents2.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompReceiptEvent.class));
    stompReceiptEvent = (StompReceiptEvent) eventMessage.getPayload();
    assertEquals(StompCommand.SUBSCRIBE, stompReceiptEvent.getStompCommand());
    assertEquals("/topic/myTopic", stompReceiptEvent.getDestination());
    stompOutputChannel1.send(new GenericMessage<byte[]>("???".getBytes()));
    Message<?> receive24 = stompInputChannel2.receive(10000);
    assertNotNull(receive24);
    assertArrayEquals("???".getBytes(), (byte[]) receive24.getPayload());
    activeMQBroker.stop();
    do {
        eventMessage = stompEvents1.receive(10000);
        assertNotNull(eventMessage);
    } while (!(eventMessage.getPayload() instanceof StompConnectionFailedEvent));
    try {
        stompOutputChannel1.send(new GenericMessage<byte[]>("foo".getBytes()));
        fail("MessageDeliveryException is expected");
    } catch (Exception e) {
        assertThat(e, instanceOf(MessageDeliveryException.class));
        assertThat(e.getMessage(), containsString("could not deliver message"));
    }
    activeMQBroker.start(false);
    do {
        eventMessage = stompEvents1.receive(20000);
        assertNotNull(eventMessage);
    } while (!(eventMessage.getPayload() instanceof StompReceiptEvent));
    do {
        eventMessage = stompEvents2.receive(10000);
        assertNotNull(eventMessage);
    } while (!(eventMessage.getPayload() instanceof StompReceiptEvent));
    stompOutputChannel1.send(new GenericMessage<byte[]>("foo".getBytes()));
    Message<?> receive25 = stompInputChannel2.receive(10000);
    assertNotNull(receive25);
    assertArrayEquals("foo".getBytes(), (byte[]) receive25.getPayload());
    context1.close();
    context2.close();
}
Also used : ConfigurableApplicationContext(org.springframework.context.ConfigurableApplicationContext) StompReceiptEvent(org.springframework.integration.stomp.event.StompReceiptEvent) StompConnectionFailedEvent(org.springframework.integration.stomp.event.StompConnectionFailedEvent) AnnotationConfigApplicationContext(org.springframework.context.annotation.AnnotationConfigApplicationContext) MessageChannel(org.springframework.messaging.MessageChannel) Lifecycle(org.springframework.context.Lifecycle) PollableChannel(org.springframework.messaging.PollableChannel) StompSessionConnectedEvent(org.springframework.integration.stomp.event.StompSessionConnectedEvent) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) Test(org.junit.Test)

Example 2 with StompReceiptEvent

use of org.springframework.integration.stomp.event.StompReceiptEvent in project spring-integration by spring-projects.

the class StompInboundChannelAdapterWebSocketIntegrationTests method testWebSocketStompClient.

@Test
public void testWebSocketStompClient() throws Exception {
    Message<?> eventMessage = this.stompEvents.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompSessionConnectedEvent.class));
    Message<?> receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(StompReceiptEvent.class));
    StompReceiptEvent stompReceiptEvent = (StompReceiptEvent) receive.getPayload();
    assertEquals(StompCommand.SUBSCRIBE, stompReceiptEvent.getStompCommand());
    assertEquals("/topic/myTopic", stompReceiptEvent.getDestination());
    waitForSubscribe("/topic/myTopic");
    SimpMessagingTemplate messagingTemplate = this.serverContext.getBean("brokerMessagingTemplate", SimpMessagingTemplate.class);
    StompHeaderAccessor stompHeaderAccessor = StompHeaderAccessor.create(StompCommand.MESSAGE);
    stompHeaderAccessor.setContentType(MediaType.APPLICATION_JSON);
    stompHeaderAccessor.updateStompCommandAsServerMessage();
    stompHeaderAccessor.setLeaveMutable(true);
    messagingTemplate.send("/topic/myTopic", MessageBuilder.createMessage("{\"foo\": \"bar\"}".getBytes(), stompHeaderAccessor.getMessageHeaders()));
    receive = this.stompInputChannel.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(Map.class));
    @SuppressWarnings("unchecked") Map<String, String> payload = (Map<String, String>) receive.getPayload();
    String foo = payload.get("foo");
    assertNotNull(foo);
    assertEquals("bar", foo);
    this.stompInboundChannelAdapter.removeDestination("/topic/myTopic");
    waitForUnsubscribe("/topic/myTopic");
    messagingTemplate.convertAndSend("/topic/myTopic", "foo");
    receive = this.errorChannel.receive(100);
    assertNull(receive);
    this.stompInboundChannelAdapter.addDestination("/topic/myTopic");
    receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    waitForSubscribe("/topic/myTopic");
    messagingTemplate.convertAndSend("/topic/myTopic", "foo");
    receive = this.errorChannel.receive(10000);
    assertNotNull(receive);
    assertThat(receive, instanceOf(ErrorMessage.class));
    ErrorMessage errorMessage = (ErrorMessage) receive;
    Throwable throwable = errorMessage.getPayload();
    assertThat(throwable, instanceOf(MessageHandlingException.class));
    assertThat(throwable.getCause(), instanceOf(MessageConversionException.class));
    assertThat(throwable.getMessage(), containsString("No suitable converter for payload type [interface java.util.Map]"));
    this.serverContext.close();
    eventMessage = this.stompEvents.receive(10000);
    assertNotNull(eventMessage);
    assertThat(eventMessage.getPayload(), instanceOf(StompConnectionFailedEvent.class));
    this.serverContext.refresh();
    do {
        eventMessage = this.stompEvents.receive(10000);
        assertNotNull(eventMessage);
    } while (!(eventMessage.getPayload() instanceof StompSessionConnectedEvent));
    waitForSubscribe("/topic/myTopic");
    messagingTemplate = this.serverContext.getBean("brokerMessagingTemplate", SimpMessagingTemplate.class);
    messagingTemplate.convertAndSend("/topic/myTopic", "foo");
    receive = this.errorChannel.receive(10000);
    assertNotNull(receive);
    assertEquals(0, ((QueueChannel) this.errorChannel).getQueueSize());
}
Also used : SimpMessagingTemplate(org.springframework.messaging.simp.SimpMessagingTemplate) MessageConversionException(org.springframework.messaging.converter.MessageConversionException) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) Matchers.containsString(org.hamcrest.Matchers.containsString) MessageHandlingException(org.springframework.messaging.MessageHandlingException) StompReceiptEvent(org.springframework.integration.stomp.event.StompReceiptEvent) StompConnectionFailedEvent(org.springframework.integration.stomp.event.StompConnectionFailedEvent) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Map(java.util.Map) MultiValueMap(org.springframework.util.MultiValueMap) StompSessionConnectedEvent(org.springframework.integration.stomp.event.StompSessionConnectedEvent) Test(org.junit.Test)

Example 3 with StompReceiptEvent

use of org.springframework.integration.stomp.event.StompReceiptEvent in project spring-integration by spring-projects.

the class StompInboundChannelAdapter method subscribeDestination.

private void subscribeDestination(final String destination) {
    if (this.stompSession != null) {
        final StompSession.Subscription subscription = this.stompSession.subscribe(destination, new StompFrameHandler() {

            @Override
            public Type getPayloadType(StompHeaders headers) {
                return StompInboundChannelAdapter.this.payloadType;
            }

            @Override
            public void handleFrame(StompHeaders headers, Object body) {
                Message<?> message;
                if (body instanceof Message) {
                    message = (Message<?>) body;
                } else {
                    message = getMessageBuilderFactory().withPayload(body).copyHeaders(StompInboundChannelAdapter.this.headerMapper.toHeaders(headers)).build();
                }
                sendMessage(message);
            }
        });
        if (this.stompSessionManager.isAutoReceiptEnabled()) {
            final ApplicationEventPublisher applicationEventPublisher = this.applicationEventPublisher;
            if (applicationEventPublisher != null) {
                subscription.addReceiptTask(() -> {
                    StompReceiptEvent event = new StompReceiptEvent(StompInboundChannelAdapter.this, destination, subscription.getReceiptId(), StompCommand.SUBSCRIBE, false);
                    applicationEventPublisher.publishEvent(event);
                });
            }
            subscription.addReceiptLostTask(() -> {
                if (applicationEventPublisher != null) {
                    StompReceiptEvent event = new StompReceiptEvent(StompInboundChannelAdapter.this, destination, subscription.getReceiptId(), StompCommand.SUBSCRIBE, true);
                    applicationEventPublisher.publishEvent(event);
                } else {
                    logger.error("The receipt [" + subscription.getReceiptId() + "] is lost for [" + subscription.getSubscriptionId() + "] on destination [" + destination + "]");
                }
            });
        }
        this.subscriptions.put(destination, subscription);
    } else {
        logger.warn("The StompInboundChannelAdapter [" + getComponentName() + "] ins't connected to StompSession. Check the state of [" + this.stompSessionManager + "]");
    }
}
Also used : StompReceiptEvent(org.springframework.integration.stomp.event.StompReceiptEvent) StompFrameHandler(org.springframework.messaging.simp.stomp.StompFrameHandler) Type(java.lang.reflect.Type) StompSession(org.springframework.messaging.simp.stomp.StompSession) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Message(org.springframework.messaging.Message) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) StompHeaders(org.springframework.messaging.simp.stomp.StompHeaders)

Example 4 with StompReceiptEvent

use of org.springframework.integration.stomp.event.StompReceiptEvent in project spring-integration by spring-projects.

the class StompMessageHandler method handleMessageInternal.

@Override
protected void handleMessageInternal(final Message<?> message) throws Exception {
    try {
        connectIfNecessary();
    } catch (Exception e) {
        throw new MessageDeliveryException(message, "The [" + this + "] could not deliver message.", e);
    }
    StompSession stompSession = this.stompSession;
    StompHeaders stompHeaders = new StompHeaders();
    this.headerMapper.fromHeaders(message.getHeaders(), stompHeaders);
    if (stompHeaders.getDestination() == null) {
        Assert.state(this.destinationExpression != null, "One of 'destination' or 'destinationExpression' must be" + " provided, if message header doesn't supply 'destination' STOMP header.");
        String destination = this.destinationExpression.getValue(this.evaluationContext, message, String.class);
        stompHeaders.setDestination(destination);
    }
    final StompSession.Receiptable receiptable = stompSession.send(stompHeaders, message.getPayload());
    if (receiptable.getReceiptId() != null) {
        final String destination = stompHeaders.getDestination();
        final ApplicationEventPublisher applicationEventPublisher = this.applicationEventPublisher;
        if (applicationEventPublisher != null) {
            receiptable.addReceiptTask(() -> {
                StompReceiptEvent event = new StompReceiptEvent(StompMessageHandler.this, destination, receiptable.getReceiptId(), StompCommand.SEND, false);
                event.setMessage(message);
                applicationEventPublisher.publishEvent(event);
            });
        }
        receiptable.addReceiptLostTask(() -> {
            if (applicationEventPublisher != null) {
                StompReceiptEvent event = new StompReceiptEvent(StompMessageHandler.this, destination, receiptable.getReceiptId(), StompCommand.SEND, true);
                event.setMessage(message);
                applicationEventPublisher.publishEvent(event);
            } else {
                logger.error("The receipt [" + receiptable.getReceiptId() + "] is lost for [" + message + "] on destination [" + destination + "]");
            }
        });
    }
}
Also used : StompReceiptEvent(org.springframework.integration.stomp.event.StompReceiptEvent) StompSession(org.springframework.messaging.simp.stomp.StompSession) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) StompHeaders(org.springframework.messaging.simp.stomp.StompHeaders) MessagingException(org.springframework.messaging.MessagingException) ConnectionLostException(org.springframework.messaging.simp.stomp.ConnectionLostException) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException)

Example 5 with StompReceiptEvent

use of org.springframework.integration.stomp.event.StompReceiptEvent in project spring-integration by spring-projects.

the class StompMessageHandlerWebSocketIntegrationTests method testStompMessageHandler.

@Test
public void testStompMessageHandler() throws InterruptedException {
    StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SEND);
    headers.setDestination("/app/simple");
    Message<String> message = MessageBuilder.withPayload("foo").setHeaders(headers).build();
    this.webSocketOutputChannel.send(message);
    SimpleController controller = this.serverContext.getBean(SimpleController.class);
    assertTrue(controller.latch.await(10, TimeUnit.SECONDS));
    Message<?> receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(StompSessionConnectedEvent.class));
    // Simple Broker Relay doesn't support RECEIPT Frame, so we check here the 'lost' StompReceiptEvent
    receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(StompReceiptEvent.class));
    StompReceiptEvent stompReceiptEvent = (StompReceiptEvent) receive.getPayload();
    assertEquals(StompCommand.SEND, stompReceiptEvent.getStompCommand());
    assertEquals("/app/simple", stompReceiptEvent.getDestination());
    assertTrue(stompReceiptEvent.isLost());
    assertNotNull(stompReceiptEvent.getMessage());
    headers = StompHeaderAccessor.create(StompCommand.SEND);
    headers.setDestination("/foo");
    message = MessageBuilder.withPayload("bar").setHeaders(headers).build();
    this.webSocketOutputChannel.send(message);
    receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(StompExceptionEvent.class));
    StompExceptionEvent stompExceptionEvent = (StompExceptionEvent) receive.getPayload();
    Throwable cause = stompExceptionEvent.getCause();
    assertThat(cause, instanceOf(MessageDeliveryException.class));
    MessageDeliveryException messageDeliveryException = (MessageDeliveryException) cause;
    Message<?> failedMessage = messageDeliveryException.getFailedMessage();
    assertThat((String) failedMessage.getPayload(), containsString("preSend intentional Exception"));
    receive = this.stompEvents.receive(10000);
    assertNotNull(receive);
    assertThat(receive.getPayload(), instanceOf(StompReceiptEvent.class));
    stompReceiptEvent = (StompReceiptEvent) receive.getPayload();
    assertEquals(StompCommand.SEND, stompReceiptEvent.getStompCommand());
    assertEquals("/foo", stompReceiptEvent.getDestination());
    assertTrue(stompReceiptEvent.isLost());
}
Also used : StompReceiptEvent(org.springframework.integration.stomp.event.StompReceiptEvent) StompExceptionEvent(org.springframework.integration.stomp.event.StompExceptionEvent) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) Matchers.containsString(org.hamcrest.Matchers.containsString) MessageDeliveryException(org.springframework.messaging.MessageDeliveryException) StompSessionConnectedEvent(org.springframework.integration.stomp.event.StompSessionConnectedEvent) LongRunningIntegrationTest(org.springframework.integration.test.support.LongRunningIntegrationTest) Test(org.junit.Test)

Aggregations

StompReceiptEvent (org.springframework.integration.stomp.event.StompReceiptEvent)5 Test (org.junit.Test)3 StompSessionConnectedEvent (org.springframework.integration.stomp.event.StompSessionConnectedEvent)3 MessageDeliveryException (org.springframework.messaging.MessageDeliveryException)3 Matchers.containsString (org.hamcrest.Matchers.containsString)2 ApplicationEventPublisher (org.springframework.context.ApplicationEventPublisher)2 StompConnectionFailedEvent (org.springframework.integration.stomp.event.StompConnectionFailedEvent)2 StompHeaderAccessor (org.springframework.messaging.simp.stomp.StompHeaderAccessor)2 StompHeaders (org.springframework.messaging.simp.stomp.StompHeaders)2 StompSession (org.springframework.messaging.simp.stomp.StompSession)2 ErrorMessage (org.springframework.messaging.support.ErrorMessage)2 Type (java.lang.reflect.Type)1 Map (java.util.Map)1 ConfigurableApplicationContext (org.springframework.context.ConfigurableApplicationContext)1 Lifecycle (org.springframework.context.Lifecycle)1 AnnotationConfigApplicationContext (org.springframework.context.annotation.AnnotationConfigApplicationContext)1 StompExceptionEvent (org.springframework.integration.stomp.event.StompExceptionEvent)1 LongRunningIntegrationTest (org.springframework.integration.test.support.LongRunningIntegrationTest)1 Message (org.springframework.messaging.Message)1 MessageChannel (org.springframework.messaging.MessageChannel)1