@Test public void testPublisherReturnsWithMandatoryExpression() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final List<Message> returns = new ArrayList<Message>(); templateWithReturnsEnabled.setReturnCallback( new ReturnCallback() { @Override public void returnedMessage( Message message, int replyCode, String replyText, String exchange, String routingKey) { returns.add(message); latch.countDown(); } }); Expression mandatoryExpression = new SpelExpressionParser().parseExpression("'message'.bytes == body"); templateWithReturnsEnabled.setMandatoryExpression(mandatoryExpression); templateWithReturnsEnabled.convertAndSend( ROUTE + "junk", (Object) "message", new CorrelationData("abc")); templateWithReturnsEnabled.convertAndSend( ROUTE + "junk", (Object) "foo", new CorrelationData("abc")); assertTrue(latch.await(1000, TimeUnit.MILLISECONDS)); assertEquals(1, returns.size()); Message message = returns.get(0); assertEquals("message", new String(message.getBody(), "utf-8")); }
private Message<?> sendAndReceive( String exchangeName, String routingKey, Message<?> requestMessage, CorrelationData correlationData) { Assert.isInstanceOf( RabbitTemplate.class, this.amqpTemplate, "RabbitTemplate implementation is required for publisher confirms"); MessageConverter converter = ((RabbitTemplate) this.amqpTemplate).getMessageConverter(); MessageProperties amqpMessageProperties = new MessageProperties(); org.springframework.amqp.core.Message amqpMessage = converter.toMessage(requestMessage.getPayload(), amqpMessageProperties); this.headerMapper.fromHeadersToRequest(requestMessage.getHeaders(), amqpMessageProperties); checkDeliveryMode(requestMessage, amqpMessageProperties); org.springframework.amqp.core.Message amqpReplyMessage = ((RabbitTemplate) this.amqpTemplate) .sendAndReceive(exchangeName, routingKey, amqpMessage, correlationData); if (amqpReplyMessage == null) { return null; } Object replyObject = converter.fromMessage(amqpReplyMessage); AbstractIntegrationMessageBuilder<?> builder = (replyObject instanceof Message) ? this.getMessageBuilderFactory().fromMessage((Message<?>) replyObject) : this.getMessageBuilderFactory().withPayload(replyObject); Map<String, ?> headers = this.headerMapper.toHeadersFromReply(amqpReplyMessage.getMessageProperties()); builder.copyHeadersIfAbsent(headers); return builder.build(); }
@Override public Object invoke(MethodInvocation invocation) throws Throwable { String id = null; Message message = null; boolean redelivered = false; try { message = (Message) invocation.getArguments()[1]; MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties.getMessageId() == null) { id = UUID.randomUUID().toString(); messageProperties.setMessageId(id); } redelivered = messageProperties.isRedelivered(); return invocation.proceed(); } catch (Exception e) { if (id != null && redelivered) { if (logger.isDebugEnabled()) { logger.debug("Canceling delivery of retried message that has no ID"); } throw new ListenerExecutionFailedException( "Cannot retry message without an ID", new AmqpRejectAndDontRequeueException(e), message); } else { throw e; } } finally { if (id != null) { retryContextCache.remove(id); } } }
@Test public void testReplyToOneDeepCustomCorrelationKey() throws Exception { ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class); Connection mockConnection = mock(Connection.class); Channel mockChannel = mock(Channel.class); when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection); when(mockConnection.isOpen()).thenReturn(true); when(mockConnection.createChannel()).thenReturn(mockChannel); final RabbitTemplate template = new RabbitTemplate(new SingleConnectionFactory(mockConnectionFactory)); template.setCorrelationKey(CORRELATION_HEADER); Queue replyQueue = new Queue("new.replyTo"); template.setReplyQueue(replyQueue); MessageProperties messageProperties = new MessageProperties(); messageProperties.setReplyTo("replyTo1"); messageProperties.setCorrelationId("saveThis".getBytes()); Message message = new Message("Hello, world!".getBytes(), messageProperties); final AtomicReference<String> replyTo = new AtomicReference<String>(); final AtomicReference<String> correlationId = new AtomicReference<String>(); doAnswer( new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { BasicProperties basicProps = (BasicProperties) invocation.getArguments()[4]; replyTo.set(basicProps.getReplyTo()); correlationId.set((String) basicProps.getHeaders().get(CORRELATION_HEADER)); MessageProperties springProps = new DefaultMessagePropertiesConverter() .toMessageProperties(basicProps, null, "UTF-8"); Message replyMessage = new Message("!dlrow olleH".getBytes(), springProps); template.onMessage(replyMessage); return null; } }) .when(mockChannel) .basicPublish( Mockito.any(String.class), Mockito.any(String.class), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.any(BasicProperties.class), Mockito.any(byte[].class)); Message reply = template.sendAndReceive(message); assertNotNull(reply); assertNotNull(replyTo.get()); assertEquals("new.replyTo", replyTo.get()); assertNotNull(correlationId.get()); assertEquals("replyTo1", reply.getMessageProperties().getReplyTo()); assertTrue(!"saveThis".equals(correlationId.get())); assertEquals("replyTo1", reply.getMessageProperties().getReplyTo()); }
@Override public void onMessage(Message msg) { String messageStr = new String(msg.getBody()); try { logger.debug("Facility Manager Get Request Message: " + messageStr.toString()); // TODO ResponseMessage ret = this.man.executeCommand( // ((ActionRequestMessage)engineMessage).getRequest() ); msg.getMessageProperties().getCorrelationId(); msg.getMessageProperties().getReplyTo(); // ret.setMessageID(engineMessage.getMessageID()); } catch (AmqpException e) { e.printStackTrace(); } }
@Test public void testAutoBindDLQwithRepublish() throws Exception { // pre-declare the queue with dead-lettering, users can also use a policy RabbitAdmin admin = new RabbitAdmin(this.rabbitAvailableRule.getResource()); Map<String, Object> args = new HashMap<String, Object>(); args.put("x-dead-letter-exchange", "xdbustest.DLX"); Queue queue = new Queue("xdbustest.dlqpubtest", true, false, false, args); admin.declareQueue(queue); MessageBus bus = getMessageBus(); Properties properties = new Properties(); properties.put("prefix", "xdbustest."); properties.put("autoBindDLQ", "true"); properties.put("republishToDLQ", "true"); properties.put("maxAttempts", "1"); // disable retry properties.put("requeue", "false"); DirectChannel moduleInputChannel = new DirectChannel(); moduleInputChannel.setBeanName("dlqPubTest"); moduleInputChannel.subscribe( new MessageHandler() { @Override public void handleMessage(Message<?> message) throws MessagingException { throw new RuntimeException("foo"); } }); bus.bindConsumer("dlqpubtest", moduleInputChannel, properties); RabbitTemplate template = new RabbitTemplate(this.rabbitAvailableRule.getResource()); template.convertAndSend("", "xdbustest.dlqpubtest", "foo"); int n = 0; while (n++ < 100) { org.springframework.amqp.core.Message deadLetter = template.receive("xdbustest.dlqpubtest.dlq"); if (deadLetter != null) { assertEquals("foo", new String(deadLetter.getBody())); assertNotNull(deadLetter.getMessageProperties().getHeaders().get("x-exception-stacktrace")); break; } Thread.sleep(100); } assertTrue(n < 100); bus.unbindConsumer("dlqpubtest", moduleInputChannel); admin.deleteQueue("xdbustest.dlqpubtest.dlq"); admin.deleteQueue("xdbustest.dlqpubtest"); admin.deleteExchange("xdbustest.DLX"); }
@Override public Object fromMessage(Message message) throws MessageConversionException { Object content = null; try { MessageProperties properties = message.getMessageProperties(); String encoding = properties.getContentEncoding(); if (encoding == null) { encoding = this.defaultCharset; } content = new String(message.getBody(), encoding); content = JSONObject.parse((String) content); } catch (UnsupportedEncodingException e) { throw new MessageConversionException("failed to convert text-based Message content", e); } return content; }
public Object invoke(MethodInvocation invocation) throws Throwable { String id = null; try { Message message = (Message) invocation.getArguments()[1]; MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties.getMessageId() == null) { id = UUID.randomUUID().toString(); messageProperties.setMessageId(id); } return invocation.proceed(); } catch (Throwable t) { throw new AmqpRejectAndDontRequeueException("Cannot retry message without an ID", t); } finally { if (id != null) { retryContextCache.remove(id); } } }
@SuppressWarnings("unchecked") public <T> T fromMessage(Message message, T t) { String json = ""; try { json = new String(message.getBody(), defaultCharset); } catch (Exception e) { e.printStackTrace(); } return (T) JSON.parseObject(json, t.getClass()); }
@Override public Object fromMessage(Message message) throws MessageConversionException { Object content = null; MessageProperties properties = message.getMessageProperties(); if (properties != null) { String contentType = properties.getContentType(); if (contentType != null && contentType.contains("protobuf")) { try { String classId = (String) message.getMessageProperties().getHeaders().get("__TypeId__"); if (classId == null) throw new Exception("no classId found"); Class<?> targetClass = Class.forName(classId); content = converter.deserialize(message.getBody(), targetClass); } catch (Exception e) { throw new MessageConversionException("Failed to convert json-based Message content", e); } } } if (content == null) { content = message.getBody(); } return content; }
@Override protected Object extractPayload(org.springframework.amqp.core.Message message) { MessageProperties messageProperties = message.getMessageProperties(); if (this.bean != null) { messageProperties.setTargetBean(this.bean); } if (this.method != null) { messageProperties.setTargetMethod(this.method); if (this.inferredArgumentType != null) { messageProperties.setInferredArgumentType(this.inferredArgumentType); } } return extractMessage(message); }
@Override public void onMessage(Message message, Channel channel) throws Exception { String value = new String(message.getBody()); try { int counter = count.getAndIncrement(); if (logger.isDebugEnabled() && counter % 100 == 0) { logger.debug(value + counter); } if (fail) { throw new RuntimeException("Planned failure"); } } finally { latch.countDown(); } }
@Override public Object fromMessage(Message message) throws MessageConversionException { MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties == null) throw new MessageConversionException("Cannot decode a message with no properties!"); byte[] body = message.getBody(); if (body == null) return null; String messageEncoding = messageProperties.getContentEncoding(); if (messageEncoding == null) messageEncoding = this.encoding; String messageContentType = messageProperties.getContentType(); if (this.contentType != null && !this.contentType.equalsIgnoreCase(messageContentType)) throw new MessageConversionException( "Cannot understand a message of type " + messageContentType); try { return new String(body, messageEncoding); } catch (UnsupportedEncodingException ex) { LOG.error("Cannot dencode strings as {}", this.encoding, ex); throw new MessageConversionException("Cannot dencode strings as " + this.encoding, ex); } }
@Override public Message postProcessMessage(Message message) throws AmqpException { String encoding = message.getMessageProperties().getContentEncoding(); if (encoding == null) { return message; } else { int colonAt = encoding.indexOf(':'); if (colonAt > 0) { encoding = encoding.substring(0, colonAt); } MessagePostProcessor decompressor = this.decompressors.get(encoding); if (decompressor != null) { return decompressor.postProcessMessage(message); } else { return message; } } }
@Override public void onMessage(Message message, Channel channel) throws Exception { String value = new String(message.getBody()); try { logger.debug("Received: " + value); if (count.get() == null) { count.set(1); } else { count.set(count.get() + 1); } if (count.get() == txSize && fail) { logger.debug("Failing: " + value); count.set(0); throw new RuntimeException("Planned"); } } finally { latch.countDown(); } }
@Override public void returnedMessage( org.springframework.amqp.core.Message message, int replyCode, String replyText, String exchange, String routingKey) { // safe to cast; we asserted we have a RabbitTemplate in doInit() MessageConverter converter = ((RabbitTemplate) this.amqpTemplate).getMessageConverter(); Object returnedObject = converter.fromMessage(message); AbstractIntegrationMessageBuilder<?> builder = (returnedObject instanceof Message) ? this.getMessageBuilderFactory().fromMessage((Message<?>) returnedObject) : this.getMessageBuilderFactory().withPayload(returnedObject); Map<String, ?> headers = this.headerMapper.toHeadersFromReply(message.getMessageProperties()); builder .copyHeadersIfAbsent(headers) .setHeader(AmqpHeaders.RETURN_REPLY_CODE, replyCode) .setHeader(AmqpHeaders.RETURN_REPLY_TEXT, replyText) .setHeader(AmqpHeaders.RETURN_EXCHANGE, exchange) .setHeader(AmqpHeaders.RETURN_ROUTING_KEY, routingKey); this.returnChannel.send(builder.build()); }
public Object fromMessage(Message message) throws MessageConversionException { return JSON.parseObject(message.getBody(), DataSyncCipher.class); }
@Override public void onMessage(Message message) { System.out.println("接收到消息:" + new String(message.getBody())); }
@Test public void testReplyToThreeDeepCustomCorrelationKey() throws Exception { ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class); Connection mockConnection = mock(Connection.class); Channel mockChannel = mock(Channel.class); when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection); when(mockConnection.isOpen()).thenReturn(true); when(mockConnection.createChannel()).thenReturn(mockChannel); final RabbitTemplate template = new RabbitTemplate(new SingleConnectionFactory(mockConnectionFactory)); template.setCorrelationKey(CORRELATION_HEADER); Queue replyQueue = new Queue("replyTo2"); template.setReplyQueue(replyQueue); MessageProperties messageProperties = new MessageProperties(); messageProperties.setReplyTo("replyTo1"); messageProperties.setCorrelationId("a".getBytes()); Message message = new Message("Hello, world!".getBytes(), messageProperties); final AtomicInteger count = new AtomicInteger(); final List<String> nestedReplyTo = new ArrayList<String>(); final List<String> nestedCorrelation = new ArrayList<String>(); doAnswer( new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { BasicProperties basicProps = (BasicProperties) invocation.getArguments()[4]; nestedReplyTo.add(basicProps.getReplyTo()); nestedCorrelation.add(basicProps.getCorrelationId()); MessageProperties springProps = new DefaultMessagePropertiesConverter() .toMessageProperties(basicProps, null, "UTF-8"); Message replyMessage = new Message("!dlrow olleH".getBytes(), springProps); if (count.incrementAndGet() < 2) { Message anotherMessage = new Message("Second".getBytes(), springProps); template.setReplyQueue(new Queue("replyTo3")); replyMessage = template.sendAndReceive(anotherMessage); nestedReplyTo.add(replyMessage.getMessageProperties().getReplyTo()); nestedCorrelation.add( (String) replyMessage.getMessageProperties().getHeaders().get(CORRELATION_HEADER)); } template.onMessage(replyMessage); return null; } }) .when(mockChannel) .basicPublish( Mockito.any(String.class), Mockito.any(String.class), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.any(BasicProperties.class), Mockito.any(byte[].class)); Message reply = template.sendAndReceive(message); assertNotNull(reply); assertEquals(3, nestedReplyTo.size()); assertEquals("replyTo2", nestedReplyTo.get(0)); assertEquals("replyTo3", nestedReplyTo.get(1)); assertEquals("replyTo2", nestedReplyTo.get(2)); // intermediate reply assertEquals("replyTo1", reply.getMessageProperties().getReplyTo()); assertEquals("a", new String(reply.getMessageProperties().getCorrelationId(), "UTF-8")); }
@Override protected void executeListener(Channel channel, Message message) throws Throwable { super.executeListener(channel, message); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); if (log.isDebugEnabled()) log.debug("Acknowledging message: " + new String(message.getBody())); }
@Test public void testAutoBindDLQPartioned() throws Exception { RabbitAdmin admin = new RabbitAdmin(this.rabbitAvailableRule.getResource()); MessageBus bus = getMessageBus(); Properties properties = new Properties(); properties.put("prefix", "xdbustest."); properties.put("autoBindDLQ", "true"); properties.put("maxAttempts", "1"); // disable retry properties.put("requeue", "false"); properties.put("partitionIndex", "0"); DirectChannel input0 = new DirectChannel(); input0.setBeanName("test.input0DLQ"); bus.bindConsumer("partDLQ.0", input0, properties); properties.put("partitionIndex", "1"); DirectChannel input1 = new DirectChannel(); input1.setBeanName("test.input1DLQ"); bus.bindConsumer("partDLQ.0", input1, properties); properties.clear(); properties.put("prefix", "xdbustest."); properties.put( "partitionKeyExtractorClass", "org.springframework.xd.dirt.integration.bus.PartitionTestSupport"); properties.put( "partitionSelectorClass", "org.springframework.xd.dirt.integration.bus.PartitionTestSupport"); properties.put(BusProperties.NEXT_MODULE_COUNT, "2"); DirectChannel output = new DirectChannel(); output.setBeanName("test.output"); bus.bindProducer("partDLQ.0", output, properties); 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(); } }); output.send(new GenericMessage<Integer>(1)); assertTrue(latch1.await(10, TimeUnit.SECONDS)); output.send(new GenericMessage<Integer>(0)); assertTrue(latch0.await(10, TimeUnit.SECONDS)); output.send(new GenericMessage<Integer>(1)); RabbitTemplate template = new RabbitTemplate(this.rabbitAvailableRule.getResource()); template.setReceiveTimeout(10000); String streamDLQName = "xdbustest.partDLQ.0.dlq"; org.springframework.amqp.core.Message received = template.receive(streamDLQName); assertNotNull(received); assertEquals(1, received.getMessageProperties().getHeaders().get("partition")); output.send(new GenericMessage<Integer>(0)); received = template.receive(streamDLQName); assertNotNull(received); assertEquals(0, received.getMessageProperties().getHeaders().get("partition")); admin.deleteQueue(streamDLQName); admin.deleteQueue("xdbustest.partDLQ.0-0"); admin.deleteQueue("xdbustest.partDLQ.0-1"); admin.deleteExchange("xdbustest.DLX"); }