@Test
  public void sendAndReceiveTimeout() throws InterruptedException {

    final CountDownLatch latch = new CountDownLatch(1);

    this.template.setReceiveTimeout(1);
    this.template.setThrowExceptionOnLateReply(true);

    SubscribableChannel channel = new ExecutorSubscribableChannel(this.executor);
    channel.subscribe(
        new MessageHandler() {
          @Override
          public void handleMessage(Message<?> message) throws MessagingException {
            try {
              Thread.sleep(500);
              MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
              replyChannel.send(new GenericMessage<String>("response"));
              fail("Expected exception");
            } catch (InterruptedException e) {
              fail("Unexpected exception " + e.getMessage());
            } catch (MessageDeliveryException ex) {
              assertEquals(
                  "Reply message received but the receiving thread has already received a reply",
                  ex.getMessage());
            } finally {
              latch.countDown();
            }
          }
        });

    assertNull(this.template.convertSendAndReceive(channel, "request", String.class));

    assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
  }
  @Test
  public void testUnicastReceiverException() throws Exception {
    SubscribableChannel channel = new DirectChannel();
    int port = SocketUtils.findAvailableUdpSocket();
    UnicastReceivingChannelAdapter adapter = new UnicastReceivingChannelAdapter(port);
    adapter.setOutputChannel(channel);
    //		SocketUtils.setLocalNicIfPossible(adapter);
    adapter.setOutputChannel(channel);
    ServiceActivatingHandler handler = new ServiceActivatingHandler(new FailingService());
    channel.subscribe(handler);
    QueueChannel errorChannel = new QueueChannel();
    adapter.setErrorChannel(errorChannel);
    adapter.start();
    SocketTestUtils.waitListening(adapter);

    Message<byte[]> message = MessageBuilder.withPayload("ABCD".getBytes()).build();
    DatagramPacketMessageMapper mapper = new DatagramPacketMessageMapper();
    DatagramPacket packet = mapper.fromMessage(message);
    packet.setSocketAddress(new InetSocketAddress("localhost", port));
    DatagramSocket datagramSocket = new DatagramSocket(SocketUtils.findAvailableUdpSocket());
    datagramSocket.send(packet);
    datagramSocket.close();
    Message<?> receivedMessage = errorChannel.receive(2000);
    assertNotNull(receivedMessage);
    assertEquals("Failed", ((Exception) receivedMessage.getPayload()).getCause().getMessage());
    adapter.stop();
  }
 /**
  * @param object a payload to send
  * @return the returned messages payload
  */
 public Object sendAndReceive(Object object) {
   replyChannel.subscribe(handler);
   requestChannel.send(new GenericMessage<Object>(object));
   try {
     return reference.get();
   } finally {
     replyChannel.unsubscribe(handler);
   }
 }
  @Test
  public void integrationTest() throws Exception {
    TestingUtilities.waitListening(serverCf, null);
    outbound.send(new GenericMessage<String>("Hello, world!"));
    Message<?> m = inbound.receive(1000);
    assertNotNull(m);
    String connectionId = m.getHeaders().get(IpHeaders.CONNECTION_ID, String.class);

    // assert we use the same connection from the pool
    outbound.send(new GenericMessage<String>("Hello, world!"));
    m = inbound.receive(1000);
    assertNotNull(m);
    assertEquals(connectionId, m.getHeaders().get(IpHeaders.CONNECTION_ID, String.class));
  }
  @Override
  protected void setupApplicationContext(ApplicationContext context) {
    MessageChannel containerControlChannel =
        context.getBean("containerControlChannel", MessageChannel.class);
    SubscribableChannel deployChannel = context.getBean("deployChannel", SubscribableChannel.class);
    SubscribableChannel undeployChannel =
        context.getBean("undeployChannel", SubscribableChannel.class);

    BridgeHandler handler = new BridgeHandler();
    handler.setOutputChannel(containerControlChannel);
    handler.setComponentName("xd.local.control.bridge");
    deployChannel.subscribe(handler);
    undeployChannel.subscribe(handler);
  }
  @Test
  public void sendAndReceive() {

    SubscribableChannel channel = new ExecutorSubscribableChannel(this.executor);
    channel.subscribe(
        new MessageHandler() {
          @Override
          public void handleMessage(Message<?> message) throws MessagingException {
            MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
            replyChannel.send(new GenericMessage<String>("response"));
          }
        });

    String actual = this.template.convertSendAndReceive(channel, "request", String.class);

    assertEquals("response", actual);
  }
  @Test
  public void gatewayIntegrationTest() throws Exception {
    final List<String> connectionIds = new ArrayList<String>();
    final AtomicBoolean okToRun = new AtomicBoolean(true);
    Executors.newSingleThreadExecutor()
        .execute(
            new Runnable() {
              @Override
              public void run() {
                while (okToRun.get()) {
                  Message<?> m = inbound.receive(1000);
                  if (m != null) {
                    connectionIds.add((String) m.getHeaders().get(IpHeaders.CONNECTION_ID));
                    replies.send(
                        MessageBuilder.withPayload("foo:" + new String((byte[]) m.getPayload()))
                            .copyHeaders(m.getHeaders())
                            .build());
                  }
                }
              }
            });
    TestingUtilities.waitListening(serverCf, null);
    toGateway.send(new GenericMessage<String>("Hello, world!"));
    Message<?> m = fromGateway.receive(1000);
    assertNotNull(m);
    assertEquals("foo:" + "Hello, world!", new String((byte[]) m.getPayload()));

    // wait a short time to allow the connection to be returned to the pool
    Thread.sleep(1000);

    // assert we use the same connection from the pool
    toGateway.send(new GenericMessage<String>("Hello, world2!"));
    m = fromGateway.receive(1000);
    assertNotNull(m);
    assertEquals("foo:" + "Hello, world2!", new String((byte[]) m.getPayload()));

    assertEquals(2, connectionIds.size());
    assertEquals(connectionIds.get(0), connectionIds.get(1));

    okToRun.set(false);
  }
  @Test
  public void testAggregationByExpression() {
    MessageChannel input = (MessageChannel) context.getBean("aggregatorWithExpressionsInput");
    SubscribableChannel outputChannel =
        (SubscribableChannel) context.getBean("aggregatorWithExpressionsOutput");
    final AtomicReference<Message<?>> aggregatedMessage = new AtomicReference<Message<?>>();
    outputChannel.subscribe(aggregatedMessage::set);
    List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
    outboundMessages.add(MessageBuilder.withPayload("123").setHeader("foo", "1").build());
    outboundMessages.add(MessageBuilder.withPayload("456").setHeader("foo", "1").build());
    outboundMessages.add(MessageBuilder.withPayload("789").setHeader("foo", "1").build());

    outboundMessages.forEach(input::send);

    assertEquals(
        "The aggregated message payload is not correct",
        "[123]",
        aggregatedMessage.get().getPayload().toString());
    Object mbf = context.getBean(IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
    Object handler = context.getBean("aggregatorWithExpressions.handler");
    assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.messageBuilderFactory"));
    assertTrue(TestUtils.getPropertyValue(handler, "expireGroupsUponTimeout", Boolean.class));
  }
  /**
   * Code to execute before running any tests
   *
   * @throws SecurityException
   * @throws NoSuchMethodException
   */
  @BeforeClass
  private void setup() throws SecurityException, NoSuchMethodException {
    // make sure we autowired everything ok
    Assert.assertNotNull(jobLauncher);
    Assert.assertNotNull(jobExplorer);
    Assert.assertNotNull(outboundMessageChannel);
    Assert.assertNotNull(listeningMessageChannel);

    // setup a messagingTemplate to send messages
    messagingTemplate = new MessagingTemplate();
    messagingTemplate.setReceiveTimeout(MESSAGE_TIMEOUT);

    // subscribe to the "wasp.channel.notification.default" broadcast channel
    listeningMessageChannel.subscribe(this);
  }
  private void testRealGuts(
      AbstractClientConnectionFactory client1,
      AbstractClientConnectionFactory client2,
      AbstractServerConnectionFactory server1,
      AbstractServerConnectionFactory server2)
      throws Exception {
    int port1;
    int port2;
    Executor exec = Executors.newCachedThreadPool();
    client1.setTaskExecutor(exec);
    client2.setTaskExecutor(exec);
    server1.setTaskExecutor(exec);
    server2.setTaskExecutor(exec);
    ApplicationEventPublisher pub =
        new ApplicationEventPublisher() {

          @Override
          public void publishEvent(ApplicationEvent event) {}

          @Override
          public void publishEvent(Object event) {}
        };
    client1.setApplicationEventPublisher(pub);
    client2.setApplicationEventPublisher(pub);
    server1.setApplicationEventPublisher(pub);
    server2.setApplicationEventPublisher(pub);
    TcpInboundGateway gateway1 = new TcpInboundGateway();
    gateway1.setConnectionFactory(server1);
    SubscribableChannel channel = new DirectChannel();
    final AtomicReference<String> connectionId = new AtomicReference<String>();
    channel.subscribe(
        new MessageHandler() {
          @Override
          public void handleMessage(Message<?> message) throws MessagingException {
            connectionId.set((String) message.getHeaders().get(IpHeaders.CONNECTION_ID));
            ((MessageChannel) message.getHeaders().getReplyChannel()).send(message);
          }
        });
    gateway1.setRequestChannel(channel);
    gateway1.setBeanFactory(mock(BeanFactory.class));
    gateway1.afterPropertiesSet();
    gateway1.start();
    TcpInboundGateway gateway2 = new TcpInboundGateway();
    gateway2.setConnectionFactory(server2);
    gateway2.setRequestChannel(channel);
    gateway2.setBeanFactory(mock(BeanFactory.class));
    gateway2.afterPropertiesSet();
    gateway2.start();
    TestingUtilities.waitListening(server1, null);
    TestingUtilities.waitListening(server2, null);
    List<AbstractClientConnectionFactory> factories =
        new ArrayList<AbstractClientConnectionFactory>();
    factories.add(client1);
    factories.add(client2);
    FailoverClientConnectionFactory failFactory = new FailoverClientConnectionFactory(factories);
    boolean singleUse = client1.isSingleUse();
    failFactory.setSingleUse(singleUse);
    failFactory.setBeanFactory(mock(BeanFactory.class));
    failFactory.afterPropertiesSet();
    TcpOutboundGateway outGateway = new TcpOutboundGateway();
    outGateway.setConnectionFactory(failFactory);
    outGateway.start();
    QueueChannel replyChannel = new QueueChannel();
    outGateway.setReplyChannel(replyChannel);
    Message<String> message = new GenericMessage<String>("foo");
    outGateway.setRemoteTimeout(120000);
    outGateway.handleMessage(message);
    Socket socket = getSocket(client1);
    port1 = socket.getLocalPort();
    assertTrue(singleUse | connectionId.get().contains(Integer.toString(port1)));
    Message<?> replyMessage = replyChannel.receive(10000);
    assertNotNull(replyMessage);
    server1.stop();
    TestingUtilities.waitUntilFactoryHasThisNumberOfConnections(client1, 0);
    outGateway.handleMessage(message);
    socket = getSocket(client2);
    port2 = socket.getLocalPort();
    assertTrue(singleUse | connectionId.get().contains(Integer.toString(port2)));
    replyMessage = replyChannel.receive(10000);
    assertNotNull(replyMessage);
    gateway2.stop();
    outGateway.stop();
  }
 private void bridgeSubscribableToPollableChannel(
     SubscribableChannel sharedChannel, MessageChannel inputChannel) {
   sharedChannel.subscribe(new MessageChannelBinderSupport.DirectHandler(inputChannel));
 }
 /** Code to execute after running all tests */
 @AfterClass
 public void teardown() {
   // unsubscribe from the "wasp.channel.notification.default" broadcast channel
   listeningMessageChannel.unsubscribe(this);
 }