@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");
  }