@Test public void testContainerWithDestNameNoCorrelation() throws Exception { BeanFactory beanFactory = mock(BeanFactory.class); when(beanFactory.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) .thenReturn(true); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.initialize(); when(beanFactory.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)) .thenReturn(scheduler); final JmsOutboundGateway gateway = new JmsOutboundGateway(); gateway.setBeanFactory(beanFactory); gateway.setConnectionFactory(getConnectionFactory()); gateway.setRequestDestination(requestQueue4); gateway.setReplyDestinationName("reply4"); gateway.setUseReplyContainer(true); gateway.afterPropertiesSet(); gateway.start(); final AtomicReference<Object> reply = new AtomicReference<Object>(); final CountDownLatch latch1 = new CountDownLatch(1); final CountDownLatch latch2 = new CountDownLatch(1); Executors.newSingleThreadExecutor() .execute( () -> { latch1.countDown(); try { reply.set(gateway.handleRequestMessage(new GenericMessage<String>("foo"))); } finally { latch2.countDown(); } }); assertTrue(latch1.await(10, TimeUnit.SECONDS)); JmsTemplate template = new JmsTemplate(); template.setConnectionFactory(getConnectionFactory()); template.setReceiveTimeout(10000); javax.jms.Message request = template.receive(requestQueue4); assertNotNull(request); final javax.jms.Message jmsReply = request; template.send( request.getJMSReplyTo(), (MessageCreator) session -> { jmsReply.setJMSCorrelationID(jmsReply.getJMSMessageID()); return jmsReply; }); assertTrue(latch2.await(10, TimeUnit.SECONDS)); assertNotNull(reply.get()); gateway.stop(); scheduler.destroy(); }
@Test public void testLazyContainerWithDest() throws Exception { BeanFactory beanFactory = mock(BeanFactory.class); when(beanFactory.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) .thenReturn(true); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.initialize(); when(beanFactory.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)) .thenReturn(scheduler); final JmsOutboundGateway gateway = new JmsOutboundGateway(); gateway.setBeanFactory(beanFactory); gateway.setConnectionFactory(getConnectionFactory()); gateway.setRequestDestination(requestQueue7); gateway.setReplyDestination(replyQueue7); gateway.setCorrelationKey("JMSCorrelationID"); gateway.setUseReplyContainer(true); gateway.setIdleReplyContainerTimeout(1, TimeUnit.SECONDS); gateway.setRequiresReply(true); gateway.setReceiveTimeout(20000); gateway.afterPropertiesSet(); gateway.start(); Executors.newSingleThreadExecutor() .execute( () -> { JmsTemplate template = new JmsTemplate(); template.setConnectionFactory(getConnectionFactory()); template.setReceiveTimeout(20000); receiveAndSend(template); receiveAndSend(template); }); assertNotNull(gateway.handleRequestMessage(new GenericMessage<String>("foo"))); DefaultMessageListenerContainer container = TestUtils.getPropertyValue( gateway, "replyContainer", DefaultMessageListenerContainer.class); int n = 0; while (n++ < 100 && container.isRunning()) { Thread.sleep(100); } assertFalse(container.isRunning()); assertNotNull(gateway.handleRequestMessage(new GenericMessage<String>("foo"))); assertTrue(container.isRunning()); gateway.stop(); assertFalse(container.isRunning()); scheduler.destroy(); }
@Test public void testReplyContainerRecovery() throws Exception { JmsOutboundGateway gateway = new JmsOutboundGateway(); ConnectionFactory connectionFactory = mock(ConnectionFactory.class); gateway.setConnectionFactory(connectionFactory); gateway.setRequestDestinationName("foo"); gateway.setUseReplyContainer(true); ReplyContainerProperties replyContainerProperties = new ReplyContainerProperties(); final List<Throwable> errors = new ArrayList<Throwable>(); ErrorHandlingTaskExecutor errorHandlingTaskExecutor = new ErrorHandlingTaskExecutor( Executors.newFixedThreadPool(10), new ErrorHandler() { @Override public void handleError(Throwable t) { logger.info("Error:", t); errors.add(t); throw new RuntimeException(t); } }); replyContainerProperties.setTaskExecutor(errorHandlingTaskExecutor); replyContainerProperties.setRecoveryInterval(100L); gateway.setReplyContainerProperties(replyContainerProperties); final Connection connection = mock(Connection.class); final AtomicInteger connectionAttempts = new AtomicInteger(); doAnswer( new Answer<Connection>() { @SuppressWarnings("serial") @Override public Connection answer(InvocationOnMock invocation) throws Throwable { int theCount = connectionAttempts.incrementAndGet(); if (theCount > 1 && theCount < 4) { throw new JmsException("bar") {}; } return connection; } }) .when(connectionFactory) .createConnection(); Session session = mock(Session.class); when(connection.createSession(false, 1)).thenReturn(session); MessageConsumer consumer = mock(MessageConsumer.class); when(session.createConsumer(any(Destination.class), anyString())).thenReturn(consumer); when(session.createTemporaryQueue()).thenReturn(mock(TemporaryQueue.class)); final Message message = mock(Message.class); final AtomicInteger count = new AtomicInteger(); doAnswer( new Answer<Message>() { @SuppressWarnings("serial") @Override public Message answer(InvocationOnMock invocation) throws Throwable { int theCount = count.incrementAndGet(); if (theCount > 1 && theCount < 4) { throw new JmsException("foo") {}; } if (theCount > 4) { Thread.sleep(100); return null; } return message; } }) .when(consumer) .receive(anyLong()); when(message.getJMSCorrelationID()).thenReturn("foo"); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.initialize(); beanFactory.registerSingleton("taskScheduler", taskScheduler); gateway.setBeanFactory(beanFactory); gateway.afterPropertiesSet(); gateway.start(); try { int n = 0; while (n++ < 100 && count.get() < 5) { Thread.sleep(100); } assertTrue(count.get() > 4); assertEquals(0, errors.size()); } finally { gateway.stop(); } }