@Override public int read(ScatteringByteChannel channel) throws IOException { int read = 0; if (sizeBuffer.hasRemaining()) { int num = channel.read(sizeBuffer); if (num < 0) { throw new IOException("end-of-stream reached"); } read += num; if (sizeBuffer.hasRemaining()) { return read; } else { sizeBuffer.flip(); size = sizeBuffer.getInt(); contentBuffer = ByteBuffer.allocate(size); } } if (!sizeBuffer.hasRemaining()) { int num = channel.read(contentBuffer); if (num < 0) { throw new IOException("end-of-stream reached"); } read += num; if (!contentBuffer.hasRemaining()) { contentBuffer.flip(); complete = true; } } return read; }
@Override public int writeBytes(ScatteringByteChannel in, int length) throws IOException { byte[] array = new byte[length]; int read = in.read(ByteBuffer.wrap(array)); writeBytes(array, 0, read); return read; }
@Override public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { ensureAccessible(); try { return in.read( (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length)); } catch (ClosedChannelException e) { return -1; } }
@Override public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { checkIndex(index, length); ByteBuffer tmpNioBuf = internalNioBuffer(); index = idx(index); tmpNioBuf.clear().position(index).limit(index + length); try { return in.read(tmpNioBuf); } catch (ClosedChannelException e) { return -1; } }
public int setBytes(int var1, ScatteringByteChannel var2, int var3) throws IOException { this.checkIndex(var1, var3); ByteBuffer var4 = this.internalNioBuffer(); var1 = this.idx(var1); var4.clear().position(var1).limit(var1 + var3); try { return var2.read(var4); } catch (ClosedChannelException var6) { return -1; } }
@Override public long readFrom(ScatteringByteChannel channel) throws IOException { long read = channel.read(buffers); remaining += read; return read; }
@Test public void testSendDatagramWithoutCallback() throws Exception { // Single datagram sending Pipe readPipe = Pipe.open(); Pipe writePipe = Pipe.open(); GatheringByteChannel gatheringByteChannel = writePipe.sink(); ScatteringByteChannel scatteringByteChannel = readPipe.source(); SelectionKeyRegistrationReference registrationReference = (SelectionKeyRegistrationReference) _selectorIntraband.registerChannel(writePipe.source(), readPipe.sink()); Thread wakeUpThread = new Thread(new WakeUpRunnable(_selectorIntraband)); wakeUpThread.start(); Selector selector = _selectorIntraband.selector; synchronized (selector) { wakeUpThread.interrupt(); wakeUpThread.join(); Datagram requestDatagram = Datagram.createRequestDatagram(_type, _data); _selectorIntraband.sendDatagram(registrationReference, requestDatagram); SelectionKey writeSelectionKey = registrationReference.writeSelectionKey; ChannelContext channelContext = (ChannelContext) writeSelectionKey.attachment(); Queue<Datagram> sendingQueue = channelContext.getSendingQueue(); Assert.assertEquals(1, sendingQueue.size()); Assert.assertSame(requestDatagram, sendingQueue.peek()); } Datagram receiveDatagram = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(_type, receiveDatagram.getType()); ByteBuffer dataByteBuffer = receiveDatagram.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); // Two datagrams continuous sending Datagram requestDatagram1 = Datagram.createRequestDatagram(_type, _data); Datagram requestDatagram2 = Datagram.createRequestDatagram(_type, _data); wakeUpThread = new Thread(new WakeUpRunnable(_selectorIntraband)); wakeUpThread.start(); synchronized (selector) { wakeUpThread.interrupt(); wakeUpThread.join(); _selectorIntraband.sendDatagram(registrationReference, requestDatagram1); _selectorIntraband.sendDatagram(registrationReference, requestDatagram2); SelectionKey writeSelectionKey = registrationReference.writeSelectionKey; ChannelContext channelContext = (ChannelContext) writeSelectionKey.attachment(); Queue<Datagram> sendingQueue = channelContext.getSendingQueue(); Assert.assertEquals(2, sendingQueue.size()); Datagram[] datagrams = sendingQueue.toArray(new Datagram[2]); Assert.assertSame(requestDatagram1, datagrams[0]); Assert.assertSame(requestDatagram2, datagrams[1]); } Datagram receiveDatagram1 = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(_type, receiveDatagram1.getType()); dataByteBuffer = receiveDatagram1.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); Datagram receiveDatagram2 = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(_type, receiveDatagram2.getType()); dataByteBuffer = receiveDatagram2.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); // Two datagrams delay sending requestDatagram1 = Datagram.createRequestDatagram(_type, _data); requestDatagram2 = Datagram.createRequestDatagram(_type, _data); wakeUpThread = new Thread(new WakeUpRunnable(_selectorIntraband)); wakeUpThread.start(); SelectionKey writeSelectionKey = registrationReference.writeSelectionKey; ChannelContext channelContext = (ChannelContext) writeSelectionKey.attachment(); Queue<Datagram> sendingQueue = channelContext.getSendingQueue(); synchronized (writeSelectionKey) { synchronized (selector) { wakeUpThread.interrupt(); wakeUpThread.join(); _selectorIntraband.sendDatagram(registrationReference, requestDatagram1); Assert.assertEquals(1, sendingQueue.size()); Assert.assertSame(requestDatagram1, sendingQueue.peek()); } receiveDatagram1 = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(_type, receiveDatagram1.getType()); dataByteBuffer = receiveDatagram1.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); Thread pollingThread = _selectorIntraband.pollingThread; while (pollingThread.getState() == Thread.State.RUNNABLE) ; _selectorIntraband.sendDatagram(registrationReference, requestDatagram2); Assert.assertEquals(1, sendingQueue.size()); Assert.assertSame(requestDatagram2, sendingQueue.peek()); } receiveDatagram2 = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(_type, receiveDatagram2.getType()); dataByteBuffer = receiveDatagram2.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); // Huge datagram sending int hugeBufferSize = 1024 * 1024 * 10; ByteBuffer hugeBuffer = ByteBuffer.allocate(hugeBufferSize); for (int i = 0; i < hugeBufferSize; i++) { hugeBuffer.put(i, (byte) i); } _selectorIntraband.sendDatagram( registrationReference, Datagram.createRequestDatagram(_type, hugeBuffer)); receiveDatagram = DatagramHelper.createReceiveDatagram(); channelContext = (ChannelContext) writeSelectionKey.attachment(); int count = 0; while (!DatagramHelper.readFrom(receiveDatagram, scatteringByteChannel)) { count++; } Assert.assertTrue(count > 0); sendingQueue = channelContext.getSendingQueue(); Assert.assertTrue(sendingQueue.isEmpty()); dataByteBuffer = receiveDatagram.getDataByteBuffer(); Assert.assertArrayEquals(hugeBuffer.array(), dataByteBuffer.array()); unregisterChannels(registrationReference); gatheringByteChannel.close(); scatteringByteChannel.close(); }
@AdviseWith(adviceClasses = {Jdk14LogImplAdvice.class}) @Test public void testSendDatagramWithCallback() throws Exception { // Submitted callback Pipe readPipe = Pipe.open(); Pipe writePipe = Pipe.open(); GatheringByteChannel gatheringByteChannel = writePipe.sink(); ScatteringByteChannel scatteringByteChannel = readPipe.source(); RegistrationReference registrationReference = _selectorIntraband.registerChannel(writePipe.source(), readPipe.sink()); Object attachment = new Object(); RecordCompletionHandler<Object> recordCompletionHandler = new RecordCompletionHandler<Object>(); _selectorIntraband.sendDatagram( registrationReference, Datagram.createRequestDatagram(_type, _data), attachment, EnumSet.of(CompletionType.SUBMITTED), recordCompletionHandler); Datagram receiveDatagram = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); recordCompletionHandler.waitUntilSubmitted(); Assert.assertSame(attachment, recordCompletionHandler.getAttachment()); Assert.assertEquals(_type, receiveDatagram.getType()); ByteBuffer dataByteBuffer = receiveDatagram.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); CaptureHandler captureHandler = null; try { // Callback timeout, with log captureHandler = JDKLoggerTestUtil.configureJDKLogger(BaseIntraband.class.getName(), Level.WARNING); List<LogRecord> logRecords = captureHandler.getLogRecords(); recordCompletionHandler = new RecordCompletionHandler<Object>(); _selectorIntraband.sendDatagram( registrationReference, Datagram.createRequestDatagram(_type, _data), attachment, EnumSet.of(CompletionType.DELIVERED), recordCompletionHandler, 10, TimeUnit.MILLISECONDS); Selector selector = _selectorIntraband.selector; recordCompletionHandler.waitUntilTimeouted(selector); Assert.assertSame(attachment, recordCompletionHandler.getAttachment()); Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith( logRecords.get(0), "Removed timeout response waiting datagram"); // Callback timeout, without log logRecords = captureHandler.resetLogLevel(Level.OFF); recordCompletionHandler = new RecordCompletionHandler<Object>(); _selectorIntraband.sendDatagram( registrationReference, Datagram.createRequestDatagram(_type, _data), attachment, EnumSet.of(CompletionType.DELIVERED), recordCompletionHandler, 10, TimeUnit.MILLISECONDS); recordCompletionHandler.waitUntilTimeouted(selector); Assert.assertSame(attachment, recordCompletionHandler.getAttachment()); Assert.assertTrue(logRecords.isEmpty()); } finally { if (captureHandler != null) { captureHandler.close(); } } // Callback timeout, completion handler causes NPE captureHandler = JDKLoggerTestUtil.configureJDKLogger(SelectorIntraband.class.getName(), Level.SEVERE); try { List<LogRecord> logRecords = captureHandler.getLogRecords(); recordCompletionHandler = new RecordCompletionHandler<Object>() { @Override public void timedOut(Object attachment) { super.timedOut(attachment); throw new NullPointerException(); } }; Jdk14LogImplAdvice.reset(); Selector selector = _selectorIntraband.selector; try { _selectorIntraband.sendDatagram( registrationReference, Datagram.createRequestDatagram(_type, _data), attachment, EnumSet.of(CompletionType.DELIVERED), recordCompletionHandler, 10, TimeUnit.MILLISECONDS); } finally { recordCompletionHandler.waitUntilTimeouted(selector); Jdk14LogImplAdvice.waitUntilErrorCalled(); } Assert.assertFalse(selector.isOpen()); Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith( logRecords.get(0), SelectorIntraband.class + ".threadFactory-1 exiting exceptionally"); gatheringByteChannel.close(); scatteringByteChannel.close(); } finally { captureHandler.close(); } }
@AdviseWith(adviceClasses = {Jdk14LogImplAdvice.class}) @Test public void testReceiveDatagram() throws Exception { Pipe readPipe = Pipe.open(); Pipe writePipe = Pipe.open(); GatheringByteChannel gatheringByteChannel = writePipe.sink(); ScatteringByteChannel scatteringByteChannel = readPipe.source(); SelectionKeyRegistrationReference registrationReference = (SelectionKeyRegistrationReference) _selectorIntraband.registerChannel(writePipe.source(), readPipe.sink()); long sequenceId = 100; CaptureHandler captureHandler = null; try { // Receive ACK response, no ACK request, with log captureHandler = JDKLoggerTestUtil.configureJDKLogger(BaseIntraband.class.getName(), Level.WARNING); List<LogRecord> logRecords = captureHandler.getLogRecords(); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo( DatagramHelper.createACKResponseDatagram(sequenceId), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilWarnCalled(); } Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith( logRecords.get(0), "Dropped ownerless ACK response "); // Receive ACK response, no ACK request, without log logRecords = captureHandler.resetLogLevel(Level.OFF); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo( DatagramHelper.createACKResponseDatagram(sequenceId), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilIsWarnEnableCalled(); } Assert.assertTrue(logRecords.isEmpty()); // Receive ACK response, with ACK request Datagram requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setAttachment(requestDatagram, new Object()); RecordCompletionHandler<Object> recordCompletionHandler = new RecordCompletionHandler<Object>(); DatagramHelper.setCompletionHandler(requestDatagram, recordCompletionHandler); DatagramHelper.setSequenceId(requestDatagram, sequenceId); DatagramHelper.setTimeout(requestDatagram, 10000); BaseIntrabandHelper.addResponseWaitingDatagram(_selectorIntraband, requestDatagram); DatagramHelper.writeTo( DatagramHelper.createACKResponseDatagram(sequenceId), gatheringByteChannel); recordCompletionHandler.waitUntilDelivered(); Assert.assertSame( DatagramHelper.getAttachment(requestDatagram), recordCompletionHandler.getAttachment()); // Receive response, no request, with log logRecords = captureHandler.resetLogLevel(Level.WARNING); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo( Datagram.createResponseDatagram(requestDatagram, _data), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilWarnCalled(); } Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith(logRecords.get(0), "Dropped ownerless response "); // Receive response, no request, without log logRecords = captureHandler.resetLogLevel(Level.OFF); Jdk14LogImplAdvice.reset(); try { requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setSequenceId(requestDatagram, sequenceId); DatagramHelper.writeTo( Datagram.createResponseDatagram(requestDatagram, _data), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilIsWarnEnableCalled(); } Assert.assertTrue(logRecords.isEmpty()); // Receive response, with request, with replied completion handler requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setAttachment(requestDatagram, new Object()); recordCompletionHandler = new RecordCompletionHandler<Object>(); DatagramHelper.setCompletionHandler(requestDatagram, recordCompletionHandler); DatagramHelper.setCompletionTypes(requestDatagram, EnumSet.of(CompletionType.REPLIED)); DatagramHelper.setSequenceId(requestDatagram, sequenceId); DatagramHelper.setTimeout(requestDatagram, 10000); BaseIntrabandHelper.addResponseWaitingDatagram(_selectorIntraband, requestDatagram); DatagramHelper.writeTo( Datagram.createResponseDatagram(requestDatagram, _data), gatheringByteChannel); recordCompletionHandler.waitUntilReplied(); Assert.assertSame( DatagramHelper.getAttachment(requestDatagram), recordCompletionHandler.getAttachment()); // Receive response, with request, without replied completion // handler, with log logRecords = captureHandler.resetLogLevel(Level.WARNING); requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setCompletionTypes(requestDatagram, EnumSet.noneOf(CompletionType.class)); recordCompletionHandler = new RecordCompletionHandler<Object>(); DatagramHelper.setCompletionHandler(requestDatagram, recordCompletionHandler); DatagramHelper.setSequenceId(requestDatagram, sequenceId); DatagramHelper.setTimeout(requestDatagram, 10000); BaseIntrabandHelper.addResponseWaitingDatagram(_selectorIntraband, requestDatagram); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo( Datagram.createResponseDatagram(requestDatagram, _data), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilWarnCalled(); } Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith(logRecords.get(0), "Dropped unconcerned response "); // Receive response, with request, without replied completion // handler, without log logRecords = captureHandler.resetLogLevel(Level.OFF); requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setCompletionTypes(requestDatagram, EnumSet.noneOf(CompletionType.class)); recordCompletionHandler = new RecordCompletionHandler<Object>(); DatagramHelper.setCompletionHandler(requestDatagram, recordCompletionHandler); DatagramHelper.setSequenceId(requestDatagram, sequenceId); DatagramHelper.setTimeout(requestDatagram, 10000); BaseIntrabandHelper.addResponseWaitingDatagram(_selectorIntraband, requestDatagram); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo( Datagram.createResponseDatagram(requestDatagram, _data), gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilIsWarnEnableCalled(); } Assert.assertTrue(logRecords.isEmpty()); // Receive request, requires ACK, no datagram receive handler, // with log logRecords = captureHandler.resetLogLevel(Level.WARNING); requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setAckRequest(requestDatagram); DatagramHelper.setSequenceId(requestDatagram, sequenceId); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo(requestDatagram, gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilWarnCalled(); } Datagram ackResponseDatagram = IntrabandTestUtil.readDatagramFully(scatteringByteChannel); Assert.assertEquals(sequenceId, DatagramHelper.getSequenceId(ackResponseDatagram)); Assert.assertTrue(DatagramHelper.isAckResponse(ackResponseDatagram)); ByteBuffer dataByteBuffer = ackResponseDatagram.getDataByteBuffer(); Assert.assertEquals(0, dataByteBuffer.capacity()); Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith(logRecords.get(0), "Dropped ownerless request "); // Receive request, no datagram receive handler, without log logRecords = captureHandler.resetLogLevel(Level.OFF); requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setSequenceId(requestDatagram, sequenceId); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo(requestDatagram, gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilIsWarnEnableCalled(); } Assert.assertTrue(logRecords.isEmpty()); // Receive request, with datagram receive handler, logRecords = captureHandler.resetLogLevel(Level.SEVERE); requestDatagram = Datagram.createRequestDatagram(_type, _data); DatagramHelper.setSequenceId(requestDatagram, sequenceId); RecordDatagramReceiveHandler recordDatagramReceiveHandler = new RecordDatagramReceiveHandler(); _selectorIntraband.registerDatagramReceiveHandler(_type, recordDatagramReceiveHandler); Jdk14LogImplAdvice.reset(); try { DatagramHelper.writeTo(requestDatagram, gatheringByteChannel); } finally { Jdk14LogImplAdvice.waitUntilErrorCalled(); } Datagram receiveDatagram = recordDatagramReceiveHandler.getReceiveDatagram(); Assert.assertEquals(sequenceId, DatagramHelper.getSequenceId(receiveDatagram)); Assert.assertEquals(_type, receiveDatagram.getType()); dataByteBuffer = receiveDatagram.getDataByteBuffer(); Assert.assertArrayEquals(_data, dataByteBuffer.array()); Assert.assertEquals(1, logRecords.size()); IntrabandTestUtil.assertMessageStartWith(logRecords.get(0), "Unable to dispatch"); unregisterChannels(registrationReference); gatheringByteChannel.close(); scatteringByteChannel.close(); } finally { if (captureHandler != null) { captureHandler.close(); } } }