@Test
  public void testUndeploySucceeds() {
    TapDefinition tapDefinition = new TapDefinition("tap1", "test", "tap @test | file");
    repository.save(tapDefinition);
    final AtomicInteger deployCount = new AtomicInteger();
    final AtomicInteger undeployCount = new AtomicInteger();
    deployChannel.subscribe(
        new MessageHandler() {

          @Override
          public void handleMessage(Message<?> message) throws MessagingException {
            deployCount.getAndIncrement();
          }
        });
    undeployChannel.subscribe(
        new MessageHandler() {

          @Override
          public void handleMessage(Message<?> message) throws MessagingException {
            undeployCount.getAndIncrement();
          }
        });
    tapDeployer.deploy("tap1");
    tapDeployer.undeploy("tap1");
    assertEquals(2, deployCount.get());
    assertEquals(2, undeployCount.get());
  }
 @Test
 public void testFlowCommit() {
   ApplicationContext applicationContext =
       new ClassPathXmlApplicationContext(
           "/TransactionalFlowTest-context.xml", "/txmanager-config.xml");
   MessageChannel inputChannel = applicationContext.getBean("inputC", MessageChannel.class);
   SubscribableChannel outputChannel =
       applicationContext.getBean("outputC", SubscribableChannel.class);
   StubTransactionManager transactionManager =
       applicationContext.getBean(StubTransactionManager.class);
   Handler handler = new Handler();
   outputChannel.subscribe(handler);
   inputChannel.send(new GenericMessage<String>("hello"));
   assertTrue(handler.messageReceived);
   assertTrue(transactionManager.committed);
   assertFalse(transactionManager.rolledback);
 }
 @Test
 public void testFlowDirectRollback() {
   ApplicationContext applicationContext =
       new ClassPathXmlApplicationContext(
           "/META-INF/spring/integration/flows/transactional-flow/flow-context.xml",
           "/txmanager-config.xml");
   MessageChannel inputChannel = applicationContext.getBean("inputChannel", MessageChannel.class);
   SubscribableChannel outputChannel =
       applicationContext.getBean("outputChannel", SubscribableChannel.class);
   StubTransactionManager transactionManager =
       applicationContext.getBean(StubTransactionManager.class);
   Handler handler = new Handler();
   outputChannel.subscribe(handler);
   try {
     inputChannel.send(new GenericMessage<String>("rollback"));
     fail("should throw exception");
   } catch (Exception e) {
     assertFalse(handler.messageReceived);
     assertTrue(transactionManager.rolledback);
     assertFalse(transactionManager.committed);
   }
 }
  @Test
  public void testFlowRollbackWithGatewayErrorChannel() {
    ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext(
            "/TransactionalFlowTest-context.xml", "/txmanager-config.xml");
    MessageChannel inputChannel = applicationContext.getBean("inputC", MessageChannel.class);
    SubscribableChannel errorChannel =
        applicationContext.getBean("errorChannel", SubscribableChannel.class);
    StubTransactionManager transactionManager =
        applicationContext.getBean(StubTransactionManager.class);
    Handler handler = new Handler();
    errorChannel.subscribe(handler);

    inputChannel.send(new GenericMessage<String>("rollback"));

    assertTrue(handler.messageReceived);
    assertTrue(handler.message instanceof ErrorMessage);
    assertEquals(
        FlowConstants.FLOW_HANDLER_EXCEPTION_HEADER_VALUE,
        handler.message.getHeaders().get(FlowConstants.FLOW_OUTPUT_PORT_HEADER));
    assertTrue(transactionManager.rolledback);
    assertFalse(transactionManager.committed);
  }
  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) {}
        };
    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() {
          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.start();
    TcpInboundGateway gateway2 = new TcpInboundGateway();
    gateway2.setConnectionFactory(server2);
    gateway2.setRequestChannel(channel);
    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.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();
  }
 @After
 public void cleanup() {
   replies.unsubscribe(handler);
 }
 @Before
 public void start() {
   replies.subscribe(handler);
 }