@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 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();
  }
  @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));
  }
 /**
  * @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);
   }
 }
  /**
   * 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);
  }
  @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 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));
  }
  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));
 }