Search in sources :

Example 6 with ChannelInputStream

use of org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream in project spring-integration by spring-projects.

the class TcpNioConnectionTests method int3453RaceTest.

@Test
public void int3453RaceTest() throws Exception {
    TcpNioServerConnectionFactory factory = new TcpNioServerConnectionFactory(0);
    final CountDownLatch connectionLatch = new CountDownLatch(1);
    factory.setApplicationEventPublisher(new ApplicationEventPublisher() {

        @Override
        public void publishEvent(ApplicationEvent event) {
            if (event instanceof TcpConnectionOpenEvent) {
                connectionLatch.countDown();
            }
        }

        @Override
        public void publishEvent(Object event) {
        }
    });
    final CountDownLatch assemblerLatch = new CountDownLatch(1);
    final AtomicReference<Thread> assembler = new AtomicReference<Thread>();
    factory.registerListener(new TcpListener() {

        @Override
        public boolean onMessage(Message<?> message) {
            if (!(message instanceof ErrorMessage)) {
                assembler.set(Thread.currentThread());
                assemblerLatch.countDown();
            }
            return false;
        }
    });
    ThreadPoolTaskExecutor te = new ThreadPoolTaskExecutor();
    // selector, reader, assembler
    te.setCorePoolSize(3);
    te.setMaxPoolSize(3);
    te.setQueueCapacity(0);
    te.initialize();
    factory.setTaskExecutor(te);
    factory.start();
    TestingUtilities.waitListening(factory, 10000L);
    int port = factory.getPort();
    Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
    assertTrue(connectionLatch.await(10, TimeUnit.SECONDS));
    TcpNioConnection connection = (TcpNioConnection) TestUtils.getPropertyValue(factory, "connections", Map.class).values().iterator().next();
    Log logger = spy(TestUtils.getPropertyValue(connection, "logger", Log.class));
    DirectFieldAccessor dfa = new DirectFieldAccessor(connection);
    dfa.setPropertyValue("logger", logger);
    ChannelInputStream cis = spy(TestUtils.getPropertyValue(connection, "channelInputStream", ChannelInputStream.class));
    dfa.setPropertyValue("channelInputStream", cis);
    // 3 dataAvailable, 1 continuing
    final CountDownLatch readerLatch = new CountDownLatch(4);
    final CountDownLatch readerFinishedLatch = new CountDownLatch(1);
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            invocation.callRealMethod();
            // delay the reader thread resetting writingToPipe
            readerLatch.await(10, TimeUnit.SECONDS);
            Thread.sleep(100);
            readerFinishedLatch.countDown();
            return null;
        }
    }).when(cis).write(any(ByteBuffer.class));
    doReturn(true).when(logger).isTraceEnabled();
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            invocation.callRealMethod();
            readerLatch.countDown();
            return null;
        }
    }).when(logger).trace(contains("checking data avail"));
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            invocation.callRealMethod();
            readerLatch.countDown();
            return null;
        }
    }).when(logger).trace(contains("Nio assembler continuing"));
    socket.getOutputStream().write("foo\r\n".getBytes());
    assertTrue(assemblerLatch.await(10, TimeUnit.SECONDS));
    assertTrue(readerFinishedLatch.await(10, TimeUnit.SECONDS));
    StackTraceElement[] stackTrace = assembler.get().getStackTrace();
    assertThat(Arrays.asList(stackTrace).toString(), not(containsString("ChannelInputStream.getNextBuffer")));
    socket.close();
    factory.stop();
    te.shutdown();
}
Also used : ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) ChannelInputStream(org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream) Log(org.apache.commons.logging.Log) ApplicationEvent(org.springframework.context.ApplicationEvent) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) DirectFieldAccessor(org.springframework.beans.DirectFieldAccessor) ThreadPoolTaskExecutor(org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor) ErrorMessage(org.springframework.messaging.support.ErrorMessage) ServerSocket(java.net.ServerSocket) Socket(java.net.Socket) Test(org.junit.Test)

Example 7 with ChannelInputStream

use of org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream in project spring-integration by spring-projects.

the class TcpNioConnectionTests method testByteArrayBlocksForZeroRead.

@Test
public void testByteArrayBlocksForZeroRead() throws Exception {
    SocketChannel socketChannel = mock(SocketChannel.class);
    Socket socket = mock(Socket.class);
    when(socketChannel.socket()).thenReturn(socket);
    TcpNioConnection connection = new TcpNioConnection(socketChannel, false, false, null, null);
    final TcpNioConnection.ChannelInputStream stream = (ChannelInputStream) new DirectFieldAccessor(connection).getPropertyValue("channelInputStream");
    final CountDownLatch latch = new CountDownLatch(1);
    final byte[] out = new byte[4];
    this.executor.execute(() -> {
        try {
            stream.read(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        latch.countDown();
    });
    Thread.sleep(1000);
    assertEquals(0x00, out[0]);
    stream.write(ByteBuffer.wrap("foo".getBytes()));
    assertTrue(latch.await(10, TimeUnit.SECONDS));
    assertEquals("foo\u0000", new String(out));
}
Also used : SocketChannel(java.nio.channels.SocketChannel) ChannelInputStream(org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream) DirectFieldAccessor(org.springframework.beans.DirectFieldAccessor) IOException(java.io.IOException) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) ServerSocket(java.net.ServerSocket) Socket(java.net.Socket) ChannelInputStream(org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream) Test(org.junit.Test)

Aggregations

Socket (java.net.Socket)7 Test (org.junit.Test)7 ChannelInputStream (org.springframework.integration.ip.tcp.connection.TcpNioConnection.ChannelInputStream)7 ServerSocket (java.net.ServerSocket)6 SocketChannel (java.nio.channels.SocketChannel)6 DirectFieldAccessor (org.springframework.beans.DirectFieldAccessor)6 Matchers.containsString (org.hamcrest.Matchers.containsString)4 CountDownLatch (java.util.concurrent.CountDownLatch)2 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Log (org.apache.commons.logging.Log)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1 ApplicationEvent (org.springframework.context.ApplicationEvent)1 ApplicationEventPublisher (org.springframework.context.ApplicationEventPublisher)1 ErrorMessage (org.springframework.messaging.support.ErrorMessage)1 ThreadPoolTaskExecutor (org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor)1