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();
}
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());
}
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 + "]");
}
}
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 + "]");
}
});
}
}
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());
}
Aggregations