/* * Copyright (C) 2015 SoftIndex LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.datakernel.stream.net; import com.google.common.collect.Lists; import com.google.common.net.InetAddresses; import io.datakernel.async.ConnectCallback; import io.datakernel.bytebuf.ByteBuf; import io.datakernel.bytebuf.ByteBufPool; import io.datakernel.eventloop.AsyncTcpSocket; import io.datakernel.eventloop.AsyncTcpSocketImpl; import io.datakernel.eventloop.Eventloop; import io.datakernel.eventloop.SimpleServer; import io.datakernel.eventloop.SimpleServer.SocketHandlerProvider; import io.datakernel.serializer.asm.BufferSerializers; import io.datakernel.stream.StreamConsumers; import io.datakernel.stream.StreamForwarder; import io.datakernel.stream.StreamProducers; import io.datakernel.stream.TestStreamConsumers; import io.datakernel.stream.processor.StreamBinaryDeserializer; import io.datakernel.stream.processor.StreamBinarySerializer; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import java.net.InetSocketAddress; import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.List; import static io.datakernel.bytebuf.ByteBufPool.*; import static io.datakernel.eventloop.FatalErrorHandlers.rethrowOnAnyError; import static io.datakernel.serializer.asm.BufferSerializers.intSerializer; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; @SuppressWarnings("unchecked") public final class SocketStreamingConnectionTest { private static final int LISTEN_PORT = 1234; private static final InetSocketAddress address = new InetSocketAddress(InetAddresses.forString("127.0.0.1"), LISTEN_PORT); @Before public void setUp() throws Exception { ByteBufPool.clear(); ByteBufPool.setSizes(0, Integer.MAX_VALUE); } @Test public void test() throws Exception { final List<Integer> source = Lists.newArrayList(); for (int i = 0; i < 5; i++) { source.add(i); } final Eventloop eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError()); final StreamConsumers.ToList<Integer> consumerToList = StreamConsumers.toList(eventloop); SocketHandlerProvider socketHandlerProvider = new SocketHandlerProvider() { @Override public AsyncTcpSocket.EventHandler createSocketHandler(AsyncTcpSocket asyncTcpSocket) { SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); StreamBinaryDeserializer<Integer> streamDeserializer = StreamBinaryDeserializer.create(eventloop, intSerializer()); streamDeserializer.getOutput().streamTo(consumerToList); connection.receiveStreamTo(streamDeserializer.getInput()); return connection; } }; SimpleServer server = SimpleServer.create(eventloop, socketHandlerProvider) .withListenAddress(address) .withAcceptOnce(); server.listen(); final StreamBinarySerializer<Integer> streamSerializer = StreamBinarySerializer.create(eventloop, intSerializer()) .withDefaultBufferSize(1); eventloop.connect(address, new ConnectCallback() { @Override public void onConnect(SocketChannel socketChannel) { AsyncTcpSocketImpl asyncTcpSocket = AsyncTcpSocketImpl.wrapChannel(eventloop, socketChannel); SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); connection.sendStreamFrom(streamSerializer.getOutput()); StreamProducers.ofIterable(eventloop, source).streamTo(streamSerializer.getInput()); asyncTcpSocket.setEventHandler(connection); asyncTcpSocket.register(); } @Override public void onException(Exception exception) { fail(); } }); eventloop.run(); assertEquals(source, consumerToList.getList()); assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems()); } @Test public void testLoopback() throws Exception { final List<Integer> source = Lists.newArrayList(); for (int i = 0; i < 100; i++) { source.add(i); } final Eventloop eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError()); final StreamConsumers.ToList<Integer> consumerToList = StreamConsumers.toList(eventloop); SocketHandlerProvider socketHandlerProvider = new SocketHandlerProvider() { @Override public AsyncTcpSocket.EventHandler createSocketHandler(AsyncTcpSocket asyncTcpSocket) { SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); StreamForwarder<ByteBuf> forwarder = StreamForwarder.create(eventloop); connection.receiveStreamTo(forwarder.getInput()); connection.sendStreamFrom(forwarder.getOutput()); return connection; } }; SimpleServer server = SimpleServer.create(eventloop, socketHandlerProvider) .withListenAddress(address) .withAcceptOnce(); server.listen(); final StreamBinarySerializer<Integer> streamSerializer = StreamBinarySerializer.create(eventloop, intSerializer()) .withDefaultBufferSize(1); final StreamBinaryDeserializer<Integer> streamDeserializer = StreamBinaryDeserializer.create(eventloop, intSerializer()); eventloop.connect(address, new ConnectCallback() { @Override public void onConnect(SocketChannel socketChannel) { AsyncTcpSocketImpl asyncTcpSocket = AsyncTcpSocketImpl.wrapChannel(eventloop, socketChannel); SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); connection.sendStreamFrom(streamSerializer.getOutput()); connection.receiveStreamTo(streamDeserializer.getInput()); StreamProducers.ofIterable(eventloop, source).streamTo(streamSerializer.getInput()); streamDeserializer.getOutput().streamTo(consumerToList); asyncTcpSocket.setEventHandler(connection); asyncTcpSocket.register(); } @Override public void onException(Exception exception) { fail(); } }); eventloop.run(); assertEquals(source, consumerToList.getList()); assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems()); } @Ignore // TODO(vmykhalko): check this test @Test public void testLoopbackWithError() throws Exception { final List<Integer> source = Lists.newArrayList(); for (int i = 0; i < 100; i++) { source.add(i); } final Eventloop eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError()); List<Integer> list = new ArrayList<>(); final TestStreamConsumers.TestConsumerToList<Integer> consumerToListWithError = new TestStreamConsumers.TestConsumerToList<Integer>(eventloop, list) { @Override public void onData(Integer item) { super.onData(item); if (list.size() == 50) { closeWithError(new Exception("Test Exception")); return; } } }; SocketHandlerProvider socketHandlerProvider = new SocketHandlerProvider() { @Override public AsyncTcpSocket.EventHandler createSocketHandler(AsyncTcpSocket asyncTcpSocket) { SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); StreamForwarder<ByteBuf> forwarder = StreamForwarder.create(eventloop); connection.receiveStreamTo(forwarder.getInput()); connection.sendStreamFrom(forwarder.getOutput()); return connection; } }; SimpleServer server = SimpleServer.create(eventloop, socketHandlerProvider) .withListenAddress(address) .withAcceptOnce(); server.listen(); final StreamBinarySerializer<Integer> streamSerializer = StreamBinarySerializer.create(eventloop, BufferSerializers.intSerializer()) .withDefaultBufferSize(1); final StreamBinaryDeserializer<Integer> streamDeserializer = StreamBinaryDeserializer.create(eventloop, BufferSerializers.intSerializer()); eventloop.connect(address, new ConnectCallback() { @Override public void onConnect(SocketChannel socketChannel) { AsyncTcpSocketImpl asyncTcpSocket = AsyncTcpSocketImpl.wrapChannel(eventloop, socketChannel); SocketStreamingConnection connection = SocketStreamingConnection.createSocketStreamingConnection(eventloop, asyncTcpSocket); connection.sendStreamFrom(streamSerializer.getOutput()); connection.receiveStreamTo(streamDeserializer.getInput()); StreamProducers.ofIterable(eventloop, source).streamTo(streamSerializer.getInput()); streamDeserializer.getOutput().streamTo(consumerToListWithError); asyncTcpSocket.setEventHandler(connection); asyncTcpSocket.register(); } @Override public void onException(Exception exception) { fail(); } }); eventloop.run(); assertEquals(list.size(), 50); assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems()); } }