/** * Cleans up this.connections by removing any closed connections. * * @return a list of open connection ids. */ private List<String> removeClosedConnectionsAndReturnOpenConnectionIds() { synchronized (this.connections) { List<String> openConnectionIds = new ArrayList<String>(); Iterator<Entry<String, TcpConnectionSupport>> iterator = this.connections.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, TcpConnectionSupport> entry = iterator.next(); TcpConnectionSupport connection = entry.getValue(); if (!connection.isOpen()) { iterator.remove(); if (logger.isDebugEnabled()) { logger.debug( getComponentName() + ": Removed closed connection: " + connection.getConnectionId()); } } else { openConnectionIds.add(entry.getKey()); if (logger.isTraceEnabled()) { logger.trace( getComponentName() + ": Connection is open: " + connection.getConnectionId()); } } } return openConnectionIds; } }
protected TcpConnectionSupport wrapConnection(TcpConnectionSupport connection) throws Exception { try { if (this.interceptorFactoryChain == null) { return connection; } TcpConnectionInterceptorFactory[] interceptorFactories = this.interceptorFactoryChain.getInterceptorFactories(); if (interceptorFactories == null) { return connection; } for (TcpConnectionInterceptorFactory factory : interceptorFactories) { TcpConnectionInterceptorSupport wrapper = factory.getInterceptor(); wrapper.setTheConnection(connection); // if no ultimate listener or sender, register each wrapper in turn if (this.listener == null) { connection.registerListener(wrapper); } if (this.sender == null) { connection.registerSender(wrapper); } connection = wrapper; } return connection; } finally { this.addConnection(connection); } }
private TcpConnectionSupport makeMockConnection(String name, boolean closeOk) { TcpConnectionSupport mockConn1 = mock(TcpConnectionSupport.class); when(mockConn1.getConnectionId()).thenReturn(name); when(mockConn1.toString()).thenReturn(name); when(mockConn1.isOpen()).thenReturn(true); if (!closeOk) { doThrow(new RuntimeException("close() not expected")).when(mockConn1).close(); } return mockConn1; }
protected void addConnection(TcpConnectionSupport connection) { synchronized (this.connections) { if (!this.active) { connection.close(); return; } this.connections.put(connection.getConnectionId(), connection); if (logger.isDebugEnabled()) { logger.debug( getComponentName() + ": Added new connection: " + connection.getConnectionId()); } } }
/** Closes this connection. */ @Override public void close() { this.setNoReadErrorOnClose(true); try { this.socket.close(); } catch (Exception e) { } super.close(); }
@Test public void testReuse() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); when(factory.getConnection()).thenReturn(mockConn1).thenReturn(mockConn2); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); conn1.close(); conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); TcpConnection conn2 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn2.toString(), conn2.toString()); conn1.close(); conn2.close(); }
/** * Close a connection with the specified connection id. * * @param connectionId the connection id. * @return true if the connection was closed. */ public boolean closeConnection(String connectionId) { Assert.notNull(connectionId, "'connectionId' to close must not be null"); // closed connections are removed from #connections in #harvestClosedConnections() synchronized (this.connections) { boolean closed = false; TcpConnectionSupport connection = this.connections.get(connectionId); if (connection != null) { try { connection.close(); closed = true; } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failed to close connection " + connectionId, e); } connection.publishConnectionExceptionEvent(e); } } return closed; } }
@Test public void testStop() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); int i = 3; when(factory.getConnection()) .thenReturn(mockConn1) .thenReturn(mockConn2) .thenReturn(makeMockConnection("conn" + (i++))); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); conn1.close(); conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); TcpConnection conn2 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn2.toString(), conn2.toString()); cachingFactory.stop(); Answer<Object> answer = new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return null; } }; doAnswer(answer).when(mockConn1).close(); doAnswer(answer).when(mockConn2).close(); when(factory.isRunning()).thenReturn(false); conn1.close(); conn2.close(); verify(mockConn1).close(); verify(mockConn2).close(); when(mockConn1.isOpen()).thenReturn(false); when(mockConn2.isOpen()).thenReturn(false); when(factory.isRunning()).thenReturn(true); TcpConnection conn3 = cachingFactory.getConnection(); assertNotSame( TestUtils.getPropertyValue(conn1, "theConnection"), TestUtils.getPropertyValue(conn3, "theConnection")); assertNotSame( TestUtils.getPropertyValue(conn2, "theConnection"), TestUtils.getPropertyValue(conn3, "theConnection")); }
public TcpConnectionSupport makeMockConnection() { TcpConnectionSupport connection = mock(TcpConnectionSupport.class); when(connection.isOpen()).thenReturn(true); return connection; }
public void testObtainConnectionIds(AbstractServerConnectionFactory serverFactory) throws Exception { final List<IpIntegrationEvent> events = Collections.synchronizedList(new ArrayList<IpIntegrationEvent>()); int expectedEvents = serverFactory instanceof TcpNetServerConnectionFactory ? 7 // Listening, + OPEN, CLOSE, EXCEPTION for each side : 5; // Listening, + OPEN, CLOSE (but we *might* get exceptions, depending on timing). final CountDownLatch serverListeningLatch = new CountDownLatch(1); final CountDownLatch eventLatch = new CountDownLatch(expectedEvents); ApplicationEventPublisher publisher = new ApplicationEventPublisher() { @Override public void publishEvent(ApplicationEvent event) { LogFactory.getLog(this.getClass()).trace("Received: " + event); events.add((IpIntegrationEvent) event); if (event instanceof TcpConnectionServerListeningEvent) { serverListeningLatch.countDown(); } eventLatch.countDown(); } @Override public void publishEvent(Object event) {} }; serverFactory.setBeanName("serverFactory"); serverFactory.setApplicationEventPublisher(publisher); serverFactory = spy(serverFactory); final CountDownLatch serverConnectionInitLatch = new CountDownLatch(1); doAnswer( invocation -> { Object result = invocation.callRealMethod(); serverConnectionInitLatch.countDown(); return result; }) .when(serverFactory) .wrapConnection(any(TcpConnectionSupport.class)); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); scheduler.afterPropertiesSet(); BeanFactory bf = mock(BeanFactory.class); when(bf.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)).thenReturn(true); when(bf.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)) .thenReturn(scheduler); serverFactory.setBeanFactory(bf); TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter(); adapter.setOutputChannel(new NullChannel()); adapter.setConnectionFactory(serverFactory); adapter.start(); assertTrue("Listening event not received", serverListeningLatch.await(10, TimeUnit.SECONDS)); assertThat(events.get(0), instanceOf(TcpConnectionServerListeningEvent.class)); assertThat( ((TcpConnectionServerListeningEvent) events.get(0)).getPort(), equalTo(serverFactory.getPort())); int port = serverFactory.getPort(); TcpNetClientConnectionFactory clientFactory = new TcpNetClientConnectionFactory("localhost", port); clientFactory.registerListener(message -> false); clientFactory.setBeanName("clientFactory"); clientFactory.setApplicationEventPublisher(publisher); clientFactory.start(); TcpConnectionSupport client = clientFactory.getConnection(); List<String> clients = clientFactory.getOpenConnectionIds(); assertEquals(1, clients.size()); assertTrue(clients.contains(client.getConnectionId())); assertTrue( "Server connection failed to register", serverConnectionInitLatch.await(1, TimeUnit.SECONDS)); List<String> servers = serverFactory.getOpenConnectionIds(); assertEquals(1, servers.size()); assertTrue(serverFactory.closeConnection(servers.get(0))); servers = serverFactory.getOpenConnectionIds(); assertEquals(0, servers.size()); int n = 0; clients = clientFactory.getOpenConnectionIds(); while (n++ < 100 && clients.size() > 0) { Thread.sleep(100); clients = clientFactory.getOpenConnectionIds(); } assertEquals(0, clients.size()); assertTrue(eventLatch.await(10, TimeUnit.SECONDS)); assertThat( "Expected at least " + expectedEvents + " events; got: " + events.size() + " : " + events, events.size(), greaterThanOrEqualTo(expectedEvents)); FooEvent event = new FooEvent(client, "foo"); client.publishEvent(event); assertThat( "Expected at least " + expectedEvents + " events; got: " + events.size() + " : " + events, events.size(), greaterThanOrEqualTo(expectedEvents + 1)); try { event = new FooEvent(mock(TcpConnectionSupport.class), "foo"); client.publishEvent(event); fail("Expected exception"); } catch (IllegalArgumentException e) { assertTrue("Can only publish events with this as the source".equals(e.getMessage())); } SocketAddress address = serverFactory.getServerSocketAddress(); if (address instanceof InetSocketAddress) { InetSocketAddress inetAddress = (InetSocketAddress) address; assertEquals(port, inetAddress.getPort()); } serverFactory.stop(); scheduler.shutdown(); }