@Test public void test() throws Exception { int port = SocketUtils.findAvailableServerSocket(); TcpNetServerConnectionFactory server = new TcpNetServerConnectionFactory(port); server.registerListener( new TcpListener() { public boolean onMessage(Message<?> message) { return false; } }); TcpNetClientConnectionFactory client = new TcpNetClientConnectionFactory("localhost", port); client.registerSender( new TcpSender() { public void addNewConnection(TcpConnection connection) {} public void removeDeadConnection(TcpConnection connection) {} }); client.registerListener( new TcpListener() { public boolean onMessage(Message<?> message) { return false; } }); server.start(); TestingUtilities.waitListening(server, null); client.start(); TcpConnection connection = client.getConnection(); Socket socket = TestUtils.getPropertyValue(connection, "socket", Socket.class); // should default to 0 (infinite) timeout assertEquals(0, socket.getSoTimeout()); connection.close(); server.stop(); client.stop(); }
private void testCloseOnTimeoutGuts(AbstractClientConnectionFactory cf) throws Exception { TestingUtilities.waitListening(serverCf, null); cf.setSoTimeout(100); CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(cf, 1); cccf.start(); TcpConnection connection = cccf.getConnection(); int n = 0; while (n++ < 100 && connection.isOpen()) { Thread.sleep(100); } assertFalse(connection.isOpen()); cccf.stop(); }
@Test public void testEnlargePool() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); TcpConnectionSupport mockConn3 = makeMockConnection("conn3"); TcpConnectionSupport mockConn4 = makeMockConnection("conn4"); when(factory.getConnection()).thenReturn(mockConn1, mockConn2, mockConn3, mockConn4); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); TcpConnection conn2 = cachingFactory.getConnection(); assertNotSame(conn1, conn2); Semaphore semaphore = TestUtils.getPropertyValue( TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class); assertEquals(0, semaphore.availablePermits()); cachingFactory.setPoolSize(4); TcpConnection conn3 = cachingFactory.getConnection(); TcpConnection conn4 = cachingFactory.getConnection(); assertEquals(0, semaphore.availablePermits()); conn1.close(); conn1.close(); conn2.close(); conn3.close(); conn4.close(); assertEquals(4, semaphore.availablePermits()); }
protected final void addStandardHeaders( TcpConnection connection, AbstractIntegrationMessageBuilder<?> messageBuilder) { String connectionId = connection.getConnectionId(); messageBuilder .setHeader(IpHeaders.HOSTNAME, connection.getHostName()) .setHeader(IpHeaders.IP_ADDRESS, connection.getHostAddress()) .setHeader(IpHeaders.REMOTE_PORT, connection.getPort()) .setHeader(IpHeaders.CONNECTION_ID, connectionId); if (this.applySequence) { messageBuilder .setCorrelationId(connectionId) .setSequenceNumber((int) connection.incrementAndGetConnectionSequence()); } }
/** Sends a Message */ public void sendMessage(Message msg) throws IOException { if (tcp_conn != null) { last_time = System.currentTimeMillis(); byte[] data = msg.toString().getBytes(); Log.e("Final Message: ", msg.toString()); int endindex = msg.toString().indexOf("image/jpeg") + 10; String headers = msg.toString().substring(0, endindex) + "\n \n"; Log.e("Initial Header:", headers); byte[] headerBytes = headers.getBytes(); byte[] imageBytes = JpegImage.imageBytes; byte[] finalBytes = new byte[headerBytes.length + imageBytes.length]; System.arraycopy(headerBytes, 0, finalBytes, 0, headerBytes.length); System.arraycopy(imageBytes, 0, finalBytes, headerBytes.length, imageBytes.length); // for(int i=0;i<headerBytes.length;i++){ // finalBytes[i] = headerBytes[i]; // } // int j=0; // for(int i=headerBytes.length;j<(imageBytes.length);i++){ // finalBytes[i]=imageBytes[j]; // j++; // } // Log.e("ImageBytes: ", // "Length:"+String.valueOf(finalBytes[finalBytes.length])+"read:"+String.valueOf(imageBytes[imageBytes.length])); Log.e("Modified headers: ", headers); // tcp_conn.send(data); Log.e("TCPTransport: ", "Total Image length=" + finalBytes.length); tcp_conn.send(finalBytes); } }
@Override public Message<?> toMessage(TcpConnection connection) throws Exception { Message<Object> message = null; Object payload = connection.getPayload(); if (payload != null) { AbstractIntegrationMessageBuilder<Object> messageBuilder = this.messageBuilderFactory.withPayload(payload); this.addStandardHeaders(connection, messageBuilder); this.addCustomHeaders(connection, messageBuilder); message = messageBuilder.build(); } else { if (logger.isWarnEnabled()) { logger.warn("Null payload from connection " + connection.getConnectionId()); } } return message; }
/** * @throws IOException * @throws SocketException * @throws Exception */ @Override protected TcpConnection obtainConnection() throws Exception { TcpConnection theConnection = this.getTheConnection(); if (theConnection != null && theConnection.isOpen()) { return theConnection; } if (logger.isDebugEnabled()) { logger.debug("Opening new socket connection to " + this.getHost() + ":" + this.getPort()); } Socket socket = createSocket(this.getHost(), this.getPort()); setSocketAttributes(socket); TcpConnection connection = new TcpNetConnection(socket, false, this.isLookupHost()); connection = wrapConnection(connection); initializeConnection(connection, socket); this.getTaskExecutor().execute(connection); this.harvestClosedConnections(); return connection; }
/** When new data is received through the TcpConnection. */ public void onReceivedData(TcpConnection tcp_conn, byte[] data, int len) { last_time = System.currentTimeMillis(); text += new String(data, 0, len); SipParser par = new SipParser(text); Message msg = par.getSipMessage(); while (msg != null) { // System.out.println("DEBUG: message len: "+msg.getLength()); msg.setRemoteAddress(tcp_conn.getRemoteAddress().toString()); msg.setRemotePort(tcp_conn.getRemotePort()); msg.setTransport(PROTO_TCP); msg.setConnectionId(connection_id); if (listener != null) listener.onReceivedMessage(this, msg); text = par.getRemainingString(); // System.out.println("DEBUG: text left: "+text.length()); par = new SipParser(text); msg = par.getSipMessage(); } }
/** When TcpConnection terminates. */ public void onConnectionTerminated(TcpConnection tcp_conn, Exception error) { if (listener != null) listener.onTransportTerminated(this, error); TcpSocket socket = tcp_conn.getSocket(); if (socket != null) try { socket.close(); } catch (Exception e) { } this.tcp_conn = null; this.listener = null; }
@Test public void testCachedFailover() throws Exception { // Failover AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); TcpConnectionSupport mockConn1 = makeMockConnection(); TcpConnectionSupport mockConn2 = makeMockConnection(); when(factory1.getConnection()).thenReturn(mockConn1); when(factory2.getConnection()).thenReturn(mockConn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class)); doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return null; } }) .when(mockConn2) .send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); // Cache CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(failoverFactory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); GenericMessage<String> message = new GenericMessage<String>("foo"); conn1 = cachingFactory.getConnection(); conn1.send(message); Mockito.verify(mockConn2).send(message); }
protected TcpConnection wrapConnection(TcpConnection connection) throws Exception { if (this.interceptorFactoryChain == null) { return connection; } TcpConnectionInterceptorFactory[] interceptorFactories = this.interceptorFactoryChain.getInterceptorFactories(); if (interceptorFactories == null) { return connection; } for (TcpConnectionInterceptorFactory factory : interceptorFactories) { TcpConnectionInterceptor 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; }
/** Stops the server. */ @Override public void stop() { this.active = false; synchronized (this.connections) { Iterator<Entry<String, TcpConnectionSupport>> iterator = this.connections.entrySet().iterator(); while (iterator.hasNext()) { TcpConnection connection = iterator.next().getValue(); connection.close(); iterator.remove(); } } synchronized (this.lifecycleMonitor) { if (this.privateExecutor) { ExecutorService executorService = (ExecutorService) this.taskExecutor; executorService.shutdown(); try { if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) { logger.debug("Forcing executor shutdown"); executorService.shutdownNow(); if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) { logger.debug("Executor failed to shutdown"); } } } catch (InterruptedException e) { executorService.shutdownNow(); Thread.currentThread().interrupt(); } finally { this.taskExecutor = null; this.privateExecutor = false; } } } if (logger.isInfoEnabled()) { logger.info("stopped " + this); } }
@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")); }
@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(); }
private void doTestCloseOnSendError( TcpConnection conn1, TcpConnection conn2, CachingClientConnectionFactory cccf) throws Exception { TcpConnection cached1 = cccf.getConnection(); try { cached1.send(new GenericMessage<String>("foo")); fail("Expected IOException"); } catch (IOException e) { assertEquals("Foo", e.getMessage()); } // Before INT-3163 this failed with a timeout - connection not returned to pool after failure on // send() TcpConnection cached2 = cccf.getConnection(); assertTrue(cached1.getConnectionId().contains(conn1.getConnectionId())); assertTrue(cached2.getConnectionId().contains(conn2.getConnectionId())); }
@Test public void testReducePool() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1", true); TcpConnectionSupport mockConn2 = makeMockConnection("conn2", true); TcpConnectionSupport mockConn3 = makeMockConnection("conn3", true); TcpConnectionSupport mockConn4 = makeMockConnection("conn4", true); when(factory.getConnection()) .thenReturn(mockConn1) .thenReturn(mockConn2) .thenReturn(mockConn3) .thenReturn(mockConn4); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 4); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); TcpConnection conn2 = cachingFactory.getConnection(); TcpConnection conn3 = cachingFactory.getConnection(); TcpConnection conn4 = cachingFactory.getConnection(); Semaphore semaphore = TestUtils.getPropertyValue( TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class); assertEquals(0, semaphore.availablePermits()); conn1.close(); assertEquals(1, semaphore.availablePermits()); cachingFactory.setPoolSize(2); assertEquals(0, semaphore.availablePermits()); assertEquals(3, cachingFactory.getActiveCount()); conn2.close(); assertEquals(0, semaphore.availablePermits()); assertEquals(2, cachingFactory.getActiveCount()); conn3.close(); assertEquals(1, cachingFactory.getActiveCount()); assertEquals(1, cachingFactory.getIdleCount()); conn4.close(); assertEquals(2, semaphore.availablePermits()); assertEquals(0, cachingFactory.getActiveCount()); assertEquals(2, cachingFactory.getIdleCount()); verify(mockConn1).close(); verify(mockConn2).close(); }
/** * Transfers attributes such as (de)serializers, singleUse etc to a new connection. When the * connection factory has a reference to a TCPListener (to read responses), or for single use * connections, the connection is executed. Single use connections need to read from the * connection in order to close it after the socket timeout. * * @param connection The new connection. * @param socket The new socket. */ protected void initializeConnection(TcpConnection connection, Socket socket) { TcpListener listener = this.getListener(); if (listener != null) { connection.registerListener(listener); } TcpSender sender = this.getSender(); if (sender != null) { connection.registerSender(sender); } connection.setMapper(this.getMapper()); connection.setDeserializer(this.getDeserializer()); connection.setSerializer(this.getSerializer()); connection.setSingleUse(this.isSingleUse()); }
/** Stops running */ public void halt() { if (tcp_conn != null) tcp_conn.halt(); }
/** Gets the remote IpAddress */ public IpAddress getRemoteAddress() { if (tcp_conn != null) return tcp_conn.getRemoteAddress(); else return null; }
/** Gets a String representation of the Object */ public String toString() { if (tcp_conn != null) return tcp_conn.toString(); else return null; }
/** Gets the remote port */ public int getRemotePort() { if (tcp_conn != null) return tcp_conn.getRemotePort(); else return 0; }
public void runIt(Object perThrData[]) { // Create per-thread cache if (endpoint.isRunning()) { Socket s = null; try { s = endpoint.acceptSocket(); } finally { // Continue accepting on another thread... if (endpoint.isRunning()) { endpoint.tp.runIt(this); } } if (null != s) { TcpConnection con = null; int step = 1; try { // 1: Set socket options: timeout, linger, etc endpoint.setSocketOptions(s); // 2: SSL handshake step = 2; if (endpoint.getServerSocketFactory() != null) { endpoint.getServerSocketFactory().handshake(s); } // 3: Process the connection step = 3; con = (TcpConnection) perThrData[0]; con.setEndpoint(endpoint); con.setSocket(s); endpoint.getConnectionHandler().processConnection(con, (Object[]) perThrData[1]); } catch (SocketException se) { endpoint.log.error( "Remote Host " + s.getInetAddress() + " SocketException: " + se.getMessage()); // Try to close the socket try { s.close(); } catch (IOException e) { } } catch (Throwable t) { if (step == 2) { endpoint.log.debug("Handshake failed", t); } else { endpoint.log.error("Unexpected error", t); } // Try to close the socket try { s.close(); } catch (IOException e) { } } finally { if (con != null) { con.recycle(); } } } } }