You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2023/03/21 22:41:54 UTC
[qpid-protonj2] branch main updated: PROTON-2694 Ensure that the AMQP test peer work on Netty 4 and 5
This is an automated email from the ASF dual-hosted git repository.
tabish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-protonj2.git
The following commit(s) were added to refs/heads/main by this push:
new ba7bb1ee PROTON-2694 Ensure that the AMQP test peer work on Netty 4 and 5
ba7bb1ee is described below
commit ba7bb1eee4d5e5bfea6a0e6974c533ecb37207c5
Author: Timothy Bish <ta...@gmail.com>
AuthorDate: Tue Mar 21 18:40:47 2023 -0400
PROTON-2694 Ensure that the AMQP test peer work on Netty 4 and 5
Allows users with applications that currently use Netty 4 and want to test
AMQP behaviors to use the test peer.
---
protonj2-test-driver/pom.xml | 33 ++
.../qpid/protonj2/test/driver/AMQPTestDriver.java | 199 ++++-----
.../qpid/protonj2/test/driver/FrameDecoder.java | 79 ++--
.../qpid/protonj2/test/driver/FrameEncoder.java | 110 ++---
.../qpid/protonj2/test/driver/LinkTracker.java | 6 +-
.../protonj2/test/driver/ProtonTestClient.java | 78 +---
.../protonj2/test/driver/ProtonTestServer.java | 72 +---
.../qpid/protonj2/test/driver/ReceiverTracker.java | 6 +-
.../qpid/protonj2/test/driver/ScriptedAction.java | 21 +-
.../qpid/protonj2/test/driver/SenderTracker.java | 6 +-
.../qpid/protonj2/test/driver/SessionTracker.java | 7 +-
.../actions/AbstractPerformativeInjectAction.java | 6 +-
.../driver/actions/ByteBufferInjectAction.java | 8 +-
.../test/driver/actions/RawBytesInjectAction.java | 12 +-
.../test/driver/actions/TransferInjectAction.java | 78 ++--
.../protonj2/test/driver/codec/ArrayElement.java | 98 ++---
.../protonj2/test/driver/codec/BinaryElement.java | 45 +-
.../protonj2/test/driver/codec/BooleanElement.java | 15 +-
.../protonj2/test/driver/codec/ByteElement.java | 23 +-
.../protonj2/test/driver/codec/CharElement.java | 17 +-
.../qpid/protonj2/test/driver/codec/Codec.java | 8 +-
.../qpid/protonj2/test/driver/codec/CodecImpl.java | 34 +-
.../test/driver/codec/Decimal128Element.java | 21 +-
.../test/driver/codec/Decimal32Element.java | 19 +-
.../test/driver/codec/Decimal64Element.java | 21 +-
.../test/driver/codec/DescribedTypeElement.java | 27 +-
.../protonj2/test/driver/codec/DoubleElement.java | 17 +-
.../qpid/protonj2/test/driver/codec/Element.java | 4 +-
.../protonj2/test/driver/codec/FloatElement.java | 17 +-
.../protonj2/test/driver/codec/IntegerElement.java | 22 +-
.../protonj2/test/driver/codec/ListElement.java | 55 +--
.../protonj2/test/driver/codec/LongElement.java | 38 +-
.../protonj2/test/driver/codec/MapElement.java | 53 +--
.../protonj2/test/driver/codec/NullElement.java | 13 +-
.../protonj2/test/driver/codec/ShortElement.java | 23 +-
.../protonj2/test/driver/codec/StringElement.java | 47 ++-
.../protonj2/test/driver/codec/SymbolElement.java | 43 +-
.../test/driver/codec/TimestampElement.java | 28 +-
.../protonj2/test/driver/codec/TypeDecoder.java | 395 +++++++++--------
.../protonj2/test/driver/codec/UUIDElement.java | 22 +-
.../test/driver/codec/UnsignedByteElement.java | 25 +-
.../test/driver/codec/UnsignedIntegerElement.java | 53 +--
.../test/driver/codec/UnsignedLongElement.java | 53 +--
.../test/driver/codec/UnsignedShortElement.java | 25 +-
.../test/driver/codec/transport/Attach.java | 5 +-
.../test/driver/codec/transport/Begin.java | 5 +-
.../test/driver/codec/transport/Close.java | 5 +-
.../test/driver/codec/transport/Detach.java | 5 +-
.../test/driver/codec/transport/Disposition.java | 5 +-
.../protonj2/test/driver/codec/transport/End.java | 5 +-
.../protonj2/test/driver/codec/transport/Flow.java | 5 +-
.../test/driver/codec/transport/HeartBeat.java | 4 +-
.../protonj2/test/driver/codec/transport/Open.java | 5 +-
.../codec/transport/PerformativeDescribedType.java | 25 +-
.../test/driver/codec/transport/Transfer.java | 5 +-
.../driver/expectations/AMQPHeaderExpectation.java | 12 +-
.../driver/expectations/AbstractExpectation.java | 30 +-
.../driver/expectations/AttachExpectation.java | 5 +-
.../test/driver/expectations/BeginExpectation.java | 5 +-
.../test/driver/expectations/CloseExpectation.java | 5 +-
.../driver/expectations/DetachExpectation.java | 5 +-
.../expectations/DispositionExpectation.java | 5 +-
.../test/driver/expectations/EndExpectation.java | 5 +-
.../test/driver/expectations/FlowExpectation.java | 5 +-
.../test/driver/expectations/OpenExpectation.java | 5 +-
.../driver/expectations/TransferExpectation.java | 22 +-
.../messaging/AbstractMessageSectionMatcher.java | 7 +-
.../transport/TransferPayloadCompositeMatcher.java | 149 ++++---
.../matchers/types/EncodedAmqpTypeMatcher.java | 12 +-
.../EncodedCompositingDataSectionMatcher.java | 86 ++--
.../types/EncodedPartialDataSectionMatcher.java | 76 ++--
.../protonj2/test/driver/netty/NettyClient.java | 468 ++-------------------
.../protonj2/test/driver/netty/NettyEventLoop.java | 52 +++
.../protonj2/test/driver/netty/NettyIOBuilder.java | 80 ++++
.../protonj2/test/driver/netty/NettyServer.java | 421 ++----------------
.../{NettyClient.java => netty4/Netty4Client.java} | 199 +++++----
.../netty4/Netty4EventLoop.java} | 36 +-
.../{NettyServer.java => netty4/Netty4Server.java} | 258 +++++++-----
.../netty4/Netty4Support.java} | 46 +-
.../test/driver/netty/{ => netty4}/SslSupport.java | 10 +-
.../{NettyClient.java => netty5/Netty5Client.java} | 63 ++-
.../netty5/Netty5EventLoop.java} | 36 +-
.../{NettyServer.java => netty5/Netty5Server.java} | 74 +++-
.../netty5/Netty5Support.java} | 46 +-
.../test/driver/netty/{ => netty5}/SslSupport.java | 6 +-
.../qpid/protonj2/codec/benchmark/Benchmark.java | 103 +++--
.../protonj2/test/driver/codec/DataImplTest.java | 82 ++--
...LegacyCodecTransferFramesTestDataGenerator.java | 32 +-
.../EncodedCompositingDataSectionMatcherTest.java | 216 +++++-----
.../EncodedPartialDataSectionMatcherTest.java | 120 +++---
90 files changed, 2262 insertions(+), 2576 deletions(-)
diff --git a/protonj2-test-driver/pom.xml b/protonj2-test-driver/pom.xml
index 45a338ce..8f5df1cf 100644
--- a/protonj2-test-driver/pom.xml
+++ b/protonj2-test-driver/pom.xml
@@ -28,26 +28,59 @@
<name>Qpid ProtonJ2 AMQP Test Driver</name>
<dependencies>
+ <!-- Netty 4 Development dependencies -->
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ <scope>${netty-scope}</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ <scope>${netty-scope}</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ <scope>${netty-scope}</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
+ <scope>${netty-scope}</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec-http</artifactId>
+ <scope>${netty-scope}</scope>
+ </dependency>
+ <!-- Netty 5 Development dependencies -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-buffer</artifactId>
+ <scope>${netty5-scope}</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-common</artifactId>
+ <scope>${netty5-scope}</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-handler</artifactId>
+ <scope>${netty5-scope}</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-transport</artifactId>
+ <scope>${netty5-scope}</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty5-codec-http</artifactId>
+ <scope>${netty5-scope}</scope>
</dependency>
+ <!-- All other test peer dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/AMQPTestDriver.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/AMQPTestDriver.java
index f3bf0e2b..a277de7a 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/AMQPTestDriver.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/AMQPTestDriver.java
@@ -18,6 +18,9 @@ package org.apache.qpid.protonj2.test.driver;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
@@ -33,14 +36,10 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.HeartBeat;
import org.apache.qpid.protonj2.test.driver.codec.transport.Open;
import org.apache.qpid.protonj2.test.driver.codec.transport.PerformativeDescribedType;
import org.apache.qpid.protonj2.test.driver.exceptions.UnexpectedPerformativeError;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.CompositeBuffer;
-import io.netty5.channel.EventLoop;
-
/**
* Test driver object used to drive inputs and inspect outputs of an Engine.
*/
@@ -59,9 +58,9 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
private final Consumer<ByteBuffer> frameConsumer;
private final Consumer<AssertionError> assertionConsumer;
- private final Supplier<EventLoop> schedulerSupplier;
+ private final Supplier<NettyEventLoop> schedulerSupplier;
- private volatile CompositeBuffer deferredWrites;
+ private volatile List<ByteBuffer> deferredWrites = new ArrayList<>();
private volatile AssertionError failureCause;
private int advertisedIdleTimeout = 0;
@@ -90,7 +89,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param scheduler
* A {@link Supplier} that will provide this driver with a scheduler service for delayed actions
*/
- public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Supplier<EventLoop> scheduler) {
+ public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Supplier<NettyEventLoop> scheduler) {
this(name, frameConsumer, null, scheduler);
}
@@ -106,7 +105,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param scheduler
* A {@link Supplier} that will provide this driver with a scheduler service for delayed actions
*/
- public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
+ public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<NettyEventLoop> scheduler) {
this.frameConsumer = frameConsumer;
this.assertionConsumer = assertionConsumer;
this.schedulerSupplier = scheduler;
@@ -207,28 +206,22 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
//----- Accepts encoded AMQP frames for processing
- @Override
- public void accept(ByteBuffer buffer) {
- try (Buffer copy = BufferAllocator.onHeapUnpooled().copyOf(buffer)) {
- accept(copy);
- }
- }
-
/**
- * Supply incoming bytes read to the test driver via an Netty {@link Buffer} instance.
+ * Supply incoming bytes read to the test driver via an Netty {@link ByteBuffer} instance.
*
* @param buffer
- * The Netty {@link Buffer} that contains new incoming bytes read.
+ * The Netty {@link ByteBuffer} that contains new incoming bytes read.
*/
- public void accept(Buffer buffer) {
- LOG.trace("{} processing new inbound buffer of size: {}", driverName, buffer.readableBytes());
+ @Override
+ public void accept(ByteBuffer buffer) {
+ LOG.trace("{} processing new inbound buffer of size: {}", driverName, buffer.remaining());
try {
// Process off all encoded frames from this buffer one at a time.
- while (buffer.readableBytes() > 0 && failureCause == null) {
- LOG.trace("{} ingesting {} bytes.", driverName, buffer.readableBytes());
+ while (buffer.remaining() > 0 && failureCause == null) {
+ LOG.trace("{} ingestion of {} bytes starting now.", driverName, buffer.remaining());
frameParser.ingest(buffer);
- LOG.trace("{} ingestion completed cycle, remaining bytes in buffer: {}", driverName, buffer.readableBytes());
+ LOG.trace("{} ingestion completed cycle, remaining bytes in buffer: {}", driverName, buffer.remaining());
}
} catch (AssertionError e) {
signalFailure(e);
@@ -284,7 +277,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- void handleSaslPerformative(int frameSize, SaslDescribedType sasl, int channel, Buffer payload) throws AssertionError {
+ void handleSaslPerformative(int frameSize, SaslDescribedType sasl, int channel, ByteBuffer payload) throws AssertionError {
synchronized (script) {
final ScriptedElement scriptEntry = script.poll();
if (scriptEntry == null) {
@@ -316,7 +309,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- void handlePerformative(int frameSize, PerformativeDescribedType amqp, int channel, Buffer payload) throws AssertionError {
+ void handlePerformative(int frameSize, PerformativeDescribedType amqp, int channel, ByteBuffer payload) throws AssertionError {
switch (amqp.getPerformativeType()) {
case HEARTBEAT:
break;
@@ -368,7 +361,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
*/
public synchronized void afterDelay(int delay, ScriptedAction action) {
Objects.requireNonNull(schedulerSupplier, "This driver cannot schedule delayed events, no scheduler available");
- EventLoop scheduler = schedulerSupplier.get();
+ NettyEventLoop scheduler = schedulerSupplier.get();
Objects.requireNonNull(scheduler, "This driver cannot schedule delayed events, no scheduler available");
scheduler.schedule(() -> {
@@ -503,7 +496,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param payload
* The payload to include in the encoded frame.
*/
- public final void sendAMQPFrame(int channel, DescribedType performative, Buffer payload) {
+ public final void sendAMQPFrame(int channel, DescribedType performative, ByteBuffer payload) {
sendAMQPFrame(channel, performative, payload, false);
}
@@ -520,14 +513,10 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param splitWrite
* Should the data be written in multiple chunks
*/
- public void deferAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
+ public void deferAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
LOG.trace("{} Deferring write of performative: {}", driverName, performative);
- try (Buffer buffer = frameEncoder.handleWrite(performative, channel, payload, null)) {
- if (deferredWrites == null) {
- deferredWrites = BufferAllocator.onHeapUnpooled().compose();
- }
-
- deferredWrites.extendWith(buffer.send());
+ try {
+ deferredWrites.add(frameEncoder.handleWrite(performative, channel, payload, null));
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
}
@@ -551,12 +540,8 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
LOG.trace("{} Deferring SASL performative write: {}", driverName, performative);
- try (Buffer buffer = frameEncoder.handleWrite(performative, channel)) {
- if (deferredWrites == null) {
- deferredWrites = BufferAllocator.onHeapUnpooled().compose();
- }
-
- deferredWrites.extendWith(buffer.send());
+ try {
+ deferredWrites.add(frameEncoder.handleWrite(performative, channel));
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
}
@@ -572,11 +557,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
public void deferHeader(AMQPHeader header) {
LOG.trace("{} Deferring AMQP Header write: {}", driverName, header);
try {
- if (deferredWrites == null) {
- deferredWrites = BufferAllocator.onHeapUnpooled().compose();
- }
-
- deferredWrites.extendWith(BufferAllocator.onHeapUnpooled().copyOf(header.getBuffer()).send());
+ deferredWrites.add(ByteBuffer.wrap(Arrays.copyOf(header.getBuffer(), AMQPHeader.HEADER_SIZE_BYTES)));
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not consumed due to error.", t));
}
@@ -594,7 +575,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param splitWrite
* Should the data be written in multiple chunks
*/
- public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
+ public void sendAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
LOG.trace("{} Sending performative: {}", driverName, performative);
if (performative instanceof PerformativeDescribedType) {
@@ -606,35 +587,37 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- try (Buffer buffer = frameEncoder.handleWrite(performative, channel, payload, null)) {
- final Buffer buffered;
- if (deferredWrites != null) {
- deferredWrites.extendWith(buffer.send());
- buffered = deferredWrites;
- deferredWrites = null;
- LOG.trace("{} appending deferred buffer {} to next write.", driverName, buffered);
- } else {
- buffered = buffer;
+ final ByteBuffer output;
+ final ByteBuffer buffer = frameEncoder.handleWrite(performative, channel, payload, null);
+
+ if (deferredWrites != null) {
+ deferredWrites.add(buffer);
+ try {
+ output = composeDefferedWrites(deferredWrites).asReadOnlyBuffer();
+ } finally {
+ deferredWrites.clear();
}
+ LOG.trace("{} appending deferred buffer {} to next write.", driverName, output);
+ } else {
+ output = buffer;
+ }
- LOG.trace("{} Writing out buffer {} to consumer: {}", driverName, buffered, frameConsumer);
+ try {
+ LOG.trace("{} Writing out buffer {} to consumer: {}", driverName, output, frameConsumer);
if (splitWrite) {
- final int bufferSplitPoint = buffered.readableBytes() / 2;
+ final int bufferSplitPoint = output.remaining() / 2;
- final ByteBuffer front = ByteBuffer.allocate(bufferSplitPoint - buffered.readerOffset());
- final ByteBuffer rear = ByteBuffer.allocate(buffered.readableBytes() - bufferSplitPoint);
+ final byte[] front = new byte[bufferSplitPoint - output.position()];
+ final byte[] rear = new byte[output.remaining() - bufferSplitPoint];
- buffered.readBytes(front);
- buffered.readBytes(rear);
+ output.get(front);
+ output.get(rear);
- frameConsumer.accept(front.flip());
- frameConsumer.accept(rear.flip());
+ frameConsumer.accept(ByteBuffer.wrap(front));
+ frameConsumer.accept(ByteBuffer.wrap(rear));
} else {
- final ByteBuffer output = ByteBuffer.allocate(buffered.readableBytes());
- buffered.readBytes(output);
-
- frameConsumer.accept(output.flip());
+ frameConsumer.accept(output);
}
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
@@ -656,23 +639,26 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
frameParser.resetToExpectingHeader();
}
- try (Buffer buffer = frameEncoder.handleWrite(performative, channel)) {
- final Buffer buffered;
+ final ByteBuffer output;
+
+ try {
+ final ByteBuffer buffer = frameEncoder.handleWrite(performative, channel);
+
if (deferredWrites != null) {
- deferredWrites.extendWith(buffer.send());
- buffered = deferredWrites;
- deferredWrites = null;
- LOG.trace("{} appending deferred buffer {} to next write.", driverName, buffered);
+ deferredWrites.add(buffer);
+ try {
+ output = composeDefferedWrites(deferredWrites).asReadOnlyBuffer();
+ } finally {
+ deferredWrites.clear();
+ }
+ LOG.trace("{} appending deferred buffer {} to next write.", driverName, output);
} else {
- buffered = buffer;
+ output = buffer;
}
LOG.trace("{} Sending SASL performative: {}", driverName, performative);
- final ByteBuffer output = ByteBuffer.allocate(buffered.readableBytes());
- buffered.readBytes(output);
-
- frameConsumer.accept(output.flip());
+ frameConsumer.accept(output);
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
}
@@ -690,17 +676,19 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
if (deferredWrites != null) {
LOG.trace("{} appending deferred buffer {} to next write.", driverName, deferredWrites);
- deferredWrites.extendWith(BufferAllocator.onHeapUnpooled().copyOf(header.getBuffer()).send());
- output = ByteBuffer.allocate(deferredWrites.readableBytes());
- deferredWrites.readBytes(output);
- output.flip();
- deferredWrites = null;
+ deferredWrites.add(ByteBuffer.wrap(header.getBuffer()).asReadOnlyBuffer());
+
+ try {
+ output = composeDefferedWrites(deferredWrites).asReadOnlyBuffer();
+ } finally {
+ deferredWrites.clear();
+ }
} else {
- output = ByteBuffer.wrap(header.getBuffer());
+ output = ByteBuffer.wrap(header.getBuffer()).asReadOnlyBuffer();
}
LOG.trace("{} Sending AMQP Header: {}", driverName, header);
- frameConsumer.accept(ByteBuffer.wrap(header.getBuffer()));
+ frameConsumer.accept(output);
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not consumed due to error.", t));
}
@@ -713,11 +701,8 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* the channel on which to send the empty frame.
*/
public void sendEmptyFrame(int channel) {
- try (Buffer buffer = frameEncoder.handleWrite(null, channel, null, null)) {
- final ByteBuffer output = ByteBuffer.allocate(buffer.readableBytes());
- buffer.readBytes(output);
-
- frameConsumer.accept(output.flip());
+ try {
+ frameConsumer.accept(frameEncoder.handleWrite(null, channel, null, null));
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not consumed due to error.", t));
}
@@ -738,24 +723,6 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- /**
- * Send the specific ProtonBuffer bytes to the remote frame consumer.
-
- * @param buffer
- * The buffer whose contents are to be written to the frame consumer.
- */
- public void sendBytes(Buffer buffer) {
- LOG.trace("{} Sending bytes from ProtonBuffer: {}", driverName, buffer);
- try (Buffer bytes = buffer) {
- final ByteBuffer output = ByteBuffer.allocate(bytes.readableBytes());
- buffer.readBytes(output);
-
- frameConsumer.accept(output.flip());
- } catch (Throwable t) {
- signalFailure(new AssertionError("Buffer was not consumed due to error.", t));
- }
- }
-
/**
* Throw an exception from processing incoming data which should be handled by the peer under test.
*
@@ -796,6 +763,22 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
//----- Internal implementation
+ private static final ByteBuffer composeDefferedWrites(List<ByteBuffer> deferredWrites) {
+ int totalSize = 0;
+ for (ByteBuffer component : deferredWrites) {
+ totalSize += component.remaining();
+ }
+
+ final ByteBuffer composite = ByteBuffer.allocate(totalSize);
+ for (ByteBuffer component : deferredWrites) {
+ composite.put(component);
+ }
+
+ deferredWrites.clear();
+
+ return composite.flip().asReadOnlyBuffer();
+ }
+
private void searchForScriptioCompletionAndTrigger() {
script.forEach(element -> {
if (element instanceof ScriptCompleteAction) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameDecoder.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameDecoder.java
index 6d3a3aed..3826bbe6 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameDecoder.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameDecoder.java
@@ -16,6 +16,8 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.Codec;
import org.apache.qpid.protonj2.test.driver.codec.security.SaslDescribedType;
import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader;
@@ -24,9 +26,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.PerformativeDescribe
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
class FrameDecoder {
private static final Logger LOG = LoggerFactory.getLogger(AMQPTestDriver.class);
@@ -49,7 +48,7 @@ class FrameDecoder {
this.driver = driver;
}
- public void ingest(Buffer buffer) throws AssertionError {
+ public void ingest(ByteBuffer buffer) throws AssertionError {
try {
// Parses in-incoming data and emit one complete frame before returning, caller should
// ensure that the input buffer is drained into the engine or stop if the engine
@@ -103,11 +102,11 @@ class FrameDecoder {
* based on the contents of that data.
*
* @param input
- * The ByteBuf containing new data to be parsed.
+ * The buffer containing new data to be parsed.
*
* @throws AssertionError if an error occurs while parsing incoming data.
*/
- void parse(Buffer input) throws AssertionError;
+ void parse(ByteBuffer input) throws AssertionError;
/**
* Reset the stage to its defaults for a new cycle of parsing.
@@ -130,9 +129,9 @@ class FrameDecoder {
private int headerByte;
@Override
- public void parse(Buffer incoming) throws AssertionError {
- while (incoming.readableBytes() > 0 && headerByte < AMQPHeader.HEADER_SIZE_BYTES) {
- headerBytes[headerByte++] = incoming.readByte();
+ public void parse(ByteBuffer incoming) throws AssertionError {
+ while (incoming.remaining() > 0 && headerByte < AMQPHeader.HEADER_SIZE_BYTES) {
+ headerBytes[headerByte++] = incoming.get();
}
if (headerByte == AMQPHeader.HEADER_SIZE_BYTES) {
@@ -163,9 +162,9 @@ class FrameDecoder {
private int multiplier = FRAME_SIZE_BYTES;
@Override
- public void parse(Buffer input) throws AssertionError {
- while (input.readableBytes() > 0) {
- frameSize |= (input.readByte() & 0xFF) << (--multiplier * Byte.SIZE);
+ public void parse(ByteBuffer input) throws AssertionError {
+ while (input.remaining() > 0) {
+ frameSize |= (input.get() & 0xFF) << (--multiplier * Byte.SIZE);
if (multiplier == 0) {
break;
}
@@ -177,7 +176,7 @@ class FrameDecoder {
// Normalize the frame size to the reminder portion
int length = frameSize - FRAME_SIZE_BYTES;
- if (input.readableBytes() < length) {
+ if (input.remaining() < length) {
transitionToFrameBufferingStage(length);
} else {
initializeFrameBodyParsingStage(length);
@@ -209,23 +208,25 @@ class FrameDecoder {
private class FrameBufferingStage implements FrameParserStage {
- private Buffer buffer;
+ private ByteBuffer buffer;
@Override
- public void parse(Buffer input) throws AssertionError {
- if (input.readableBytes() < buffer.writableBytes()) {
- buffer.writeBytes(input);
+ public void parse(ByteBuffer input) throws AssertionError {
+ if (input.remaining() < buffer.remaining()) {
+ buffer.put(input);
} else {
- final int remaining = buffer.writableBytes();
+ final int oldLimit = input.limit();
- input.copyInto(input.readerOffset(), buffer, buffer.writerOffset(), remaining);
- input.skipReadableBytes(remaining);
- buffer.skipWritableBytes(remaining);
+ try {
+ buffer.put(input.limit(input.position() + buffer.remaining())).flip();
+ } finally {
+ input.limit(oldLimit);
+ }
// Now we can consume the buffer frame body.
- initializeFrameBodyParsingStage(buffer.readableBytes());
- try (Buffer frame = buffer.makeReadOnly()){
- stage.parse(frame);
+ initializeFrameBodyParsingStage(buffer.remaining());
+ try {
+ stage.parse(buffer.asReadOnlyBuffer());
} finally {
buffer = null;
}
@@ -234,7 +235,7 @@ class FrameDecoder {
@Override
public FrameBufferingStage reset(int frameSize) {
- buffer = BufferAllocator.onHeapUnpooled().allocate(frameSize).implicitCapacityLimit(frameSize);
+ buffer = ByteBuffer.allocate(frameSize);
return this;
}
}
@@ -244,30 +245,30 @@ class FrameDecoder {
private int frameSize;
@Override
- public void parse(Buffer input) throws AssertionError {
- int dataOffset = (input.readByte() << 2) & 0x3FF;
+ public void parse(ByteBuffer input) throws AssertionError {
+ int dataOffset = (input.get() << 2) & 0x3FF;
int frameSize = this.frameSize + FRAME_SIZE_BYTES;
validateDataOffset(dataOffset, frameSize);
- int type = input.readByte() & 0xFF;
- short channel = input.readShort();
+ int type = input.get() & 0xFF;
+ short channel = input.getShort();
// note that this skips over the extended header if it's present
if (dataOffset != 8) {
- input.readerOffset(input.readerOffset() + dataOffset - 8);
+ input.position(input.position() + dataOffset - 8);
}
final int frameBodySize = frameSize - dataOffset;
- Buffer payload = null;
+ ByteBuffer payload = null;
Object val = null;
if (frameBodySize > 0) {
- int frameBodyStartIndex = input.readerOffset();
+ final int decodedBytes;
try {
- codec.decode(input);
+ decodedBytes = (int) codec.decode(input);
} catch (Exception e) {
throw new AssertionError("Decoder failed reading remote input:", e);
}
@@ -287,12 +288,14 @@ class FrameDecoder {
// Slice to the known Frame body size and use that as the buffer for any payload once
// the actual Performative has been decoded. The implies that the data comprising the
// performative will be held as long as the payload buffer is kept.
- if (input.readableBytes() > 0) {
+ if (input.remaining() > 0) {
// Check that the remaining bytes aren't part of another frame.
- int payloadSize = frameBodySize - (input.readerOffset() - frameBodyStartIndex);
+ // TODO int payloadSize = frameBodySize - (input.position() - frameBodyStartIndex);
+ int payloadSize = frameBodySize - decodedBytes;
if (payloadSize > 0) {
- payload = input.copy(input.readerOffset(), payloadSize, true);
- input.skipReadableBytes(payloadSize);
+ final byte[] payloadBytes = new byte[payloadSize];
+ input.get(payloadBytes);
+ payload = ByteBuffer.wrap(payloadBytes);
}
}
} else {
@@ -349,7 +352,7 @@ class FrameDecoder {
}
@Override
- public void parse(Buffer input) throws AssertionError {
+ public void parse(ByteBuffer input) throws AssertionError {
throw parsingError;
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameEncoder.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameEncoder.java
index e0577695..b9fa20e0 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameEncoder.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/FrameEncoder.java
@@ -16,12 +16,14 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.Codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* Encodes AMQP performatives into frames for transmission
*/
@@ -31,13 +33,15 @@ public class FrameEncoder {
public static final byte SASL_FRAME_TYPE = (byte) 1;
private static final int AMQP_PERFORMATIVE_PAD = 512;
- private static final int FRAME_HEADER_SIZE = 8;
private static final int FRAME_START_BYTE = 0;
private static final int FRAME_DOFF_BYTE = 4;
private static final int FRAME_DOFF_SIZE = 2;
private static final int FRAME_TYPE_BYTE = 5;
private static final int FRAME_CHANNEL_BYTE = 6;
+ private static final int FRAME_HEADER_SIZE = 8;
+
+ private static final byte[] FRAME_HEADER_RESERVED = new byte[FRAME_HEADER_SIZE];
private final AMQPTestDriver driver;
@@ -47,70 +51,80 @@ public class FrameEncoder {
this.driver = driver;
}
- public Buffer handleWrite(DescribedType performative, int channel, Buffer payload, Runnable payloadToLarge) {
+ public ByteBuffer handleWrite(DescribedType performative, int channel, ByteBuffer payload, Runnable payloadToLarge) {
return writeFrame(performative, payload, AMQP_FRAME_TYPE, channel, driver.getOutboundMaxFrameSize(), payloadToLarge);
}
- public Buffer handleWrite(DescribedType performative, int channel) {
+ public ByteBuffer handleWrite(DescribedType performative, int channel) {
return writeFrame(performative, null, SASL_FRAME_TYPE, (short) 0, driver.getOutboundMaxFrameSize(), null);
}
- private Buffer writeFrame(DescribedType performative, Buffer payload, byte frameType, int channel, int maxFrameSize, Runnable onPayloadTooLarge) {
- final int outputBufferSize = AMQP_PERFORMATIVE_PAD + (payload != null ? payload.readableBytes() : 0);
- final Buffer output = BufferAllocator.onHeapUnpooled().allocate(outputBufferSize);
+ private ByteBuffer writeFrame(DescribedType performative, ByteBuffer payload, byte frameType, int channel, int maxFrameSize, Runnable onPayloadTooLarge) {
+ final int outputBufferSize = AMQP_PERFORMATIVE_PAD + (payload != null ? payload.remaining() : 0);
- final int performativeSize = writePerformative(performative, payload, maxFrameSize, output, onPayloadTooLarge);
- final int capacity = maxFrameSize > 0 ? maxFrameSize - performativeSize : Integer.MAX_VALUE;
- final int payloadSize = Math.min(payload == null ? 0 : payload.readableBytes(), capacity);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream(outputBufferSize)) {
- if (payloadSize > 0) {
- payload.copyInto(payload.readerOffset(), output, output.writerOffset(), payloadSize);
- payload.skipReadableBytes(payloadSize);
- output.skipWritableBytes(payloadSize);
- }
+ final int performativeSize = writePerformative(performative, payload, maxFrameSize, baos, onPayloadTooLarge);
+ final int capacity = maxFrameSize > 0 ? maxFrameSize - performativeSize : Integer.MAX_VALUE;
+ final int payloadSize = Math.min(payload == null ? 0 : payload.remaining(), capacity);
+
+ if (payloadSize > 0) {
+ byte[] payloadArray = new byte[payloadSize];
+ payload.get(payloadArray);
+ baos.write(payloadArray);
+ }
- endFrame(output, frameType, channel);
+ final ByteBuffer output = ByteBuffer.wrap(baos.toByteArray());
- return output;
+ endFrame(output, frameType, channel);
+
+ return output.asReadOnlyBuffer();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
- private int writePerformative(DescribedType performative, Buffer payload, int maxFrameSize, Buffer output, Runnable onPayloadTooLarge) {
- output.writerOffset(FRAME_HEADER_SIZE);
+ private int writePerformative(DescribedType performative, ByteBuffer payload, int maxFrameSize, ByteArrayOutputStream output, Runnable onPayloadTooLarge) {
+ try {
+ output.write(FRAME_HEADER_RESERVED); // Reserve space for later Frame preamble
- long encodedSize = 0;
- final int startIndex = output.writerOffset();
+ long encodedSize = 0;
- if (performative != null) {
- try {
- codec.putDescribedType(performative);
- encodedSize = codec.encode(output);
- } finally {
- codec.clear();
+ if (performative != null) {
+ try {
+ codec.putDescribedType(performative);
+ encodedSize = codec.encode(output);
+ } finally {
+ codec.clear();
+ }
}
- }
- int performativeSize = output.writerOffset() - startIndex;
+ int performativeSize = output.size() - FRAME_HEADER_SIZE;
- if (performativeSize != encodedSize) {
- throw new IllegalStateException(String.format(
- "Unable to encode performative %s of %d bytes into provided proton buffer, only wrote %d bytes",
- performative, performativeSize, encodedSize));
- }
+ if (performativeSize != encodedSize) {
+ throw new IllegalStateException(String.format(
+ "Unable to encode performative %s of %d bytes into provided proton buffer, only wrote %d bytes",
+ performative, performativeSize, encodedSize));
+ }
- if (onPayloadTooLarge != null && maxFrameSize > 0 && payload != null && (payload.readableBytes() + performativeSize) > maxFrameSize) {
- // Next iteration will re-encode the frame body again with updates from the <payload-to-large>
- // handler and then we can move onto the body portion.
- onPayloadTooLarge.run();
- performativeSize = writePerformative(performative, payload, maxFrameSize, output, null);
- }
+ if (onPayloadTooLarge != null && maxFrameSize > 0 && payload != null && (payload.remaining() + performativeSize) > maxFrameSize) {
+ // Next iteration will re-encode the frame body again with updates from the <payload-to-large>
+ // handler and then we can move onto the body portion.
+ onPayloadTooLarge.run();
+ output.reset();
+ performativeSize = writePerformative(performative, payload, maxFrameSize, output, null);
+ }
- return performativeSize;
+ return performativeSize;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
- private static void endFrame(Buffer output, byte frameType, int channel) {
- output.setInt(FRAME_START_BYTE, output.readableBytes());
- output.setByte(FRAME_DOFF_BYTE, (byte) FRAME_DOFF_SIZE);
- output.setByte(FRAME_TYPE_BYTE, frameType);
- output.setShort(FRAME_CHANNEL_BYTE, (short) channel);
+ private static void endFrame(ByteBuffer output, byte frameType, int channel) {
+ output.putInt(FRAME_START_BYTE, output.remaining());
+ output.put(FRAME_DOFF_BYTE, (byte) FRAME_DOFF_SIZE);
+ output.put(FRAME_TYPE_BYTE, frameType);
+ output.putShort(FRAME_CHANNEL_BYTE, (short) channel);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/LinkTracker.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/LinkTracker.java
index 04e764b9..4a495c1d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/LinkTracker.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/LinkTracker.java
@@ -16,6 +16,8 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.messaging.Source;
import org.apache.qpid.protonj2.test.driver.codec.messaging.Target;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
@@ -28,8 +30,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Role;
import org.apache.qpid.protonj2.test.driver.codec.transport.SenderSettleMode;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-
/**
* Tracks information about links that are opened be the client under test.
*/
@@ -149,7 +149,7 @@ public abstract class LinkTracker {
return this;
}
- protected abstract void handleTransfer(Transfer transfer, Buffer payload);
+ protected abstract void handleTransfer(Transfer transfer, ByteBuffer payload);
protected abstract void handleFlow(Flow flow);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestClient.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestClient.java
index c940d42c..b9eade1d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestClient.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestClient.java
@@ -23,16 +23,12 @@ import java.util.function.Supplier;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader;
+import org.apache.qpid.protonj2.test.driver.netty.NettyIOBuilder;
import org.apache.qpid.protonj2.test.driver.netty.NettyClient;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.SimpleChannelInboundHandler;
-
/**
* Test Client for AMQP server testing, allows for scripting the expected inputs from
* the server and outputs from the client back to the server.
@@ -42,7 +38,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(ProtonTestClient.class);
private final AMQPTestDriver driver;
- private final NettyTestDriverClient client;
+ private final NettyClient client;
/**
* Creates a Socket Test Peer using all default Server options.
@@ -63,8 +59,12 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
* The options that control the behavior of the client connection.
*/
public ProtonTestClient(ProtonTestClientOptions options) {
- this.driver = new NettyAwareAMQPTestDriver(this::processDriverOutput, this::processDriverAssertion, this::eventLoop);
- this.client = new NettyTestDriverClient(options);
+ this.driver = new NettyAwareAMQPTestDriver(this::processDriverOutput,
+ this::processDriverAssertion,
+ this::eventLoop);
+ this.client = NettyIOBuilder.createClient(options,
+ this::processConnectionEstablished,
+ this::processChannelInput);
}
public void connect(String hostname, int port) throws IOException {
@@ -97,7 +97,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
client.write(frame);
}
- protected void processChannelInput(Buffer input) {
+ protected void processChannelInput(ByteBuffer input) {
LOG.trace("AMQP Test Client Channel processing: {}", input);
driver.accept(input);
}
@@ -107,7 +107,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
close();
}
- protected EventLoop eventLoop() {
+ protected NettyEventLoop eventLoop() {
return client.eventLoop();
}
@@ -115,7 +115,9 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
private final class NettyAwareAMQPTestDriver extends AMQPTestDriver {
- public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
+ public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer,
+ Consumer<AssertionError> assertionConsumer,
+ Supplier<NettyEventLoop> scheduler) {
super(getPeerName(), frameConsumer, assertionConsumer, scheduler);
}
@@ -126,8 +128,8 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
// other driver resources being used on two different threads.
@Override
- public void deferAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
- EventLoop loop = client.eventLoop();
+ public void deferAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.deferAMQPFrame(channel, performative, payload, splitWrite);
} else {
@@ -139,7 +141,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
public void deferSaslFrame(int channel, DescribedType performative) {
- EventLoop loop = client.eventLoop();
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.deferSaslFrame(channel, performative);
} else {
@@ -151,7 +153,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
public void deferHeader(AMQPHeader header) {
- EventLoop loop = client.eventLoop();
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.deferHeader(header);
} else {
@@ -162,8 +164,8 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
}
@Override
- public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
- EventLoop loop = client.eventLoop();
+ public void sendAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.sendAMQPFrame(channel, performative, payload, splitWrite);
} else {
@@ -175,7 +177,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
public void sendSaslFrame(int channel, DescribedType performative) {
- EventLoop loop = client.eventLoop();
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.sendSaslFrame(channel, performative);
} else {
@@ -187,7 +189,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
public void sendHeader(AMQPHeader header) {
- EventLoop loop = client.eventLoop();
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.sendHeader(header);
} else {
@@ -199,7 +201,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
public void sendEmptyFrame(int channel) {
- EventLoop loop = client.eventLoop();
+ NettyEventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.sendEmptyFrame(channel);
} else {
@@ -209,38 +211,4 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
}
}
}
-
- //----- Channel handler that drives IO for the test driver
-
- private final class NettyTestDriverClient extends NettyClient {
-
- public NettyTestDriverClient(ProtonTestClientOptions options) {
- super(options);
- }
-
- @Override
- protected ChannelHandler getClientHandler() {
- return new SimpleChannelInboundHandler<Buffer>() {
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- processConnectionEstablished();
- ctx.fireChannelActive();
- }
-
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
- LOG.trace("AMQP Test Client Channel read: {}", input);
-
- // Driver processes new data and may produce output based on this.
- try (Buffer copy = input.copy(true)) {
- processChannelInput(copy);
- } catch (Throwable e) {
- LOG.error("Closed AMQP Test client channel due to error: ", e);
- ctx.channel().close();
- }
- }
- };
- }
- }
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestServer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestServer.java
index 06b6eb40..ad2c2884 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestServer.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ProtonTestServer.java
@@ -25,16 +25,12 @@ import javax.net.ssl.SSLEngine;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader;
+import org.apache.qpid.protonj2.test.driver.netty.NettyIOBuilder;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
import org.apache.qpid.protonj2.test.driver.netty.NettyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.SimpleChannelInboundHandler;
-
/**
* Netty based AMQP Test Server implementation that can handle inbound connections
* and script the expected AMQP frame interchange that should occur for a given test.
@@ -44,7 +40,7 @@ public class ProtonTestServer extends ProtonTestPeer {
private static final Logger LOG = LoggerFactory.getLogger(ProtonTestServer.class);
private final AMQPTestDriver driver;
- private final NettyTestDriverServer server;
+ private final NettyServer server;
/**
* Creates a Socket Test Peer using all default Server options.
@@ -66,7 +62,9 @@ public class ProtonTestServer extends ProtonTestPeer {
*/
public ProtonTestServer(ProtonTestServerOptions options) {
this.driver = new NettyAwareAMQPTestDriver(this::processDriverOutput, this::processDriverAssertion, this::eventLoop);
- this.server = new NettyTestDriverServer(options);
+ this.server = NettyIOBuilder.createServer(options,
+ this::processConnectionEstablished,
+ this::processChannelInput);
}
/**
@@ -150,45 +148,11 @@ public class ProtonTestServer extends ProtonTestPeer {
return driver;
}
- //----- Channel handler that drives IO for the test driver
-
- private final class NettyTestDriverServer extends NettyServer {
-
- public NettyTestDriverServer(ProtonTestServerOptions options) {
- super(options);
- }
-
- @Override
- protected ChannelHandler getServerHandler() {
- return new SimpleChannelInboundHandler<Buffer>() {
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- processConnectionEstablished();
- ctx.fireChannelActive();
- }
-
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
- LOG.trace("AMQP Test Server Channel read: {}", input);
-
- // Driver processes new data and may produce output based on this.
- try (Buffer copy = input.copy(true)) {
- processChannelInput(copy);
- } catch (Throwable e) {
- LOG.error("Closed AMQP Test server channel due to error: ", e);
- ctx.channel().close();
- }
- }
- };
- }
- }
-
//----- Test driver Wrapper to ensure actions occur on the event loop
private final class NettyAwareAMQPTestDriver extends AMQPTestDriver {
- public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
+ public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<NettyEventLoop> scheduler) {
super(getPeerName(), frameConsumer, assertionConsumer, scheduler);
}
@@ -199,8 +163,8 @@ public class ProtonTestServer extends ProtonTestPeer {
// other driver resources being used on two different threads.
@Override
- public void deferAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
- EventLoop loop = server.eventLoop();
+ public void deferAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.deferAMQPFrame(channel, performative, payload, splitWrite);
} else {
@@ -212,7 +176,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
public void deferSaslFrame(int channel, DescribedType performative) {
- EventLoop loop = server.eventLoop();
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.deferSaslFrame(channel, performative);
} else {
@@ -224,7 +188,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
public void deferHeader(AMQPHeader header) {
- EventLoop loop = server.eventLoop();
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.deferHeader(header);
} else {
@@ -235,8 +199,8 @@ public class ProtonTestServer extends ProtonTestPeer {
}
@Override
- public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
- EventLoop loop = server.eventLoop();
+ public void sendAMQPFrame(int channel, DescribedType performative, ByteBuffer payload, boolean splitWrite) {
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.sendAMQPFrame(channel, performative, payload, splitWrite);
} else {
@@ -248,7 +212,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
public void sendSaslFrame(int channel, DescribedType performative) {
- EventLoop loop = server.eventLoop();
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.sendSaslFrame(channel, performative);
} else {
@@ -260,7 +224,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
public void sendHeader(AMQPHeader header) {
- EventLoop loop = server.eventLoop();
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.sendHeader(header);
} else {
@@ -272,7 +236,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
public void sendEmptyFrame(int channel) {
- EventLoop loop = server.eventLoop();
+ NettyEventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.sendEmptyFrame(channel);
} else {
@@ -311,12 +275,12 @@ public class ProtonTestServer extends ProtonTestPeer {
close();
}
- protected void processChannelInput(Buffer input) {
+ protected void processChannelInput(ByteBuffer input) {
LOG.trace("AMQP Server Channel processing: {}", input);
driver.accept(input);
}
- protected EventLoop eventLoop() {
+ protected NettyEventLoop eventLoop() {
return server.eventLoop();
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ReceiverTracker.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ReceiverTracker.java
index a9462136..57b32365 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ReceiverTracker.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ReceiverTracker.java
@@ -16,11 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-
/**
* Link Tracker that manages tracking of the peer Receiver link which will
* handle flows and receive transfers to a remote Sender link.
@@ -32,7 +32,7 @@ public class ReceiverTracker extends LinkTracker {
}
@Override
- protected void handleTransfer(Transfer transfer, Buffer payload) {
+ protected void handleTransfer(Transfer transfer, ByteBuffer payload) {
// TODO: Update internal state
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ScriptedAction.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ScriptedAction.java
index e9888530..dcf6564c 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ScriptedAction.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/ScriptedAction.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.test.driver.codec.security.SaslChallenge;
@@ -34,8 +35,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Open;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-
/**
* Entry in the test script that produces some output to be sent to the AMQP
* peer under test.
@@ -100,47 +99,47 @@ public interface ScriptedAction extends ScriptedElement {
}
@Override
- default void handleOpen(int frameSize, Open open, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleOpen(int frameSize, Open open, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Open arrived when expecting to perform an action");
}
@Override
- default void handleBegin(int frameSize, Begin begin, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleBegin(int frameSize, Begin begin, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Begin arrived when expecting to perform an action");
}
@Override
- default void handleAttach(int frameSize, Attach attach, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleAttach(int frameSize, Attach attach, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Attach arrived when expecting to perform an action");
}
@Override
- default void handleFlow(int frameSize, Flow flow, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleFlow(int frameSize, Flow flow, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Flow arrived when expecting to perform an action");
}
@Override
- default void handleTransfer(int frameSize, Transfer transfer, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleTransfer(int frameSize, Transfer transfer, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Transfer arrived when expecting to perform an action");
}
@Override
- default void handleDisposition(int frameSize, Disposition disposition, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleDisposition(int frameSize, Disposition disposition, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Disposition arrived when expecting to perform an action");
}
@Override
- default void handleDetach(int frameSize, Detach detach, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleDetach(int frameSize, Detach detach, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Detach arrived when expecting to perform an action");
}
@Override
- default void handleEnd(int frameSize, End end, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleEnd(int frameSize, End end, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("End arrived when expecting to perform an action");
}
@Override
- default void handleClose(int frameSize, Close close, Buffer payload, int channel, AMQPTestDriver context) {
+ default void handleClose(int frameSize, Close close, ByteBuffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Close arrived when expecting to perform an action");
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SenderTracker.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SenderTracker.java
index 82686c15..a0678d6b 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SenderTracker.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SenderTracker.java
@@ -16,11 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-
/**
* Link Tracker that manages tracking of the peer Sender link which will
* handle flows and initiate transfers to a remote Receiver link.
@@ -32,7 +32,7 @@ public class SenderTracker extends LinkTracker {
}
@Override
- protected void handleTransfer(Transfer transfer, Buffer payload) {
+ protected void handleTransfer(Transfer transfer, ByteBuffer payload) {
// TODO Handle sender scripted transfer by updating local state.
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SessionTracker.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SessionTracker.java
index 8ccaef8f..d5f675f4 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SessionTracker.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/SessionTracker.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver;
+import java.nio.ByteBuffer;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@@ -31,8 +32,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Role;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-
/**
* Tracks information related to an opened Session and its various links
*/
@@ -319,7 +318,7 @@ public class SessionTracker {
return tracker;
}
- public LinkTracker handleTransfer(Transfer transfer, Buffer payload) {
+ public LinkTracker handleTransfer(Transfer transfer, ByteBuffer payload) {
LinkTracker tracker = remoteLinks.get(transfer.getHandle());
if (tracker.isSender()) {
@@ -332,7 +331,7 @@ public class SessionTracker {
return tracker;
}
- public void handleLocalTransfer(Transfer transfer, Buffer payload) {
+ public void handleLocalTransfer(Transfer transfer, ByteBuffer payload) {
LinkTracker tracker = localLinks.get(transfer.getHandle());
// Pass along to local sender for processing before sending and ignore if
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/AbstractPerformativeInjectAction.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/AbstractPerformativeInjectAction.java
index 25c76487..a12e9f0d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/AbstractPerformativeInjectAction.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/AbstractPerformativeInjectAction.java
@@ -16,14 +16,14 @@
*/
package org.apache.qpid.protonj2.test.driver.actions;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.DeferrableScriptedAction;
import org.apache.qpid.protonj2.test.driver.ScriptedAction;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
/**
* Abstract base used by inject actions of AMQP Performatives
*
@@ -156,7 +156,7 @@ public abstract class AbstractPerformativeInjectAction<P extends DescribedType>
/**
* @return the buffer containing the payload that should be sent as part of this action.
*/
- public Buffer getPayload() {
+ public ByteBuffer getPayload() {
return null;
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/ByteBufferInjectAction.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/ByteBufferInjectAction.java
index 84663225..abdd5274 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/ByteBufferInjectAction.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/ByteBufferInjectAction.java
@@ -16,20 +16,20 @@
*/
package org.apache.qpid.protonj2.test.driver.actions;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedAction;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted action that will write the contents of a given buffer out through the driver.
*/
public class ByteBufferInjectAction implements ScriptedAction {
- private final Buffer buffer;
+ private final ByteBuffer buffer;
private final AMQPTestDriver driver;
- public ByteBufferInjectAction(AMQPTestDriver driver, Buffer buffer) {
+ public ByteBufferInjectAction(AMQPTestDriver driver, ByteBuffer buffer) {
this.buffer = buffer;
this.driver = driver;
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/RawBytesInjectAction.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/RawBytesInjectAction.java
index d00cbc05..502293f7 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/RawBytesInjectAction.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/RawBytesInjectAction.java
@@ -16,12 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.actions;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedAction;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* AMQP Empty Frame injection action which can be added to a driver for write at a specific time or
* following on from some other action in the test script.
@@ -29,7 +28,7 @@ import io.netty5.buffer.BufferAllocator;
public class RawBytesInjectAction implements ScriptedAction {
private final AMQPTestDriver driver;
- private Buffer buffer;
+ private ByteBuffer buffer;
public RawBytesInjectAction(AMQPTestDriver driver) {
this.driver = driver;
@@ -63,7 +62,10 @@ public class RawBytesInjectAction implements ScriptedAction {
}
public RawBytesInjectAction withBytes(byte[] bytes) {
- this.buffer = BufferAllocator.onHeapUnpooled().copyOf(bytes);
+ this.buffer = ByteBuffer.allocate(bytes.length);
+ this.buffer.put(bytes);
+ this.buffer.flip().asReadOnlyBuffer();
+
return this;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/TransferInjectAction.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/TransferInjectAction.java
index 24c0d562..fa716663 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/TransferInjectAction.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/actions/TransferInjectAction.java
@@ -16,6 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.actions;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@@ -47,9 +52,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.ErrorCondition;
import org.apache.qpid.protonj2.test.driver.codec.transport.ReceiverSettleMode;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* AMQP Close injection action which can be added to a driver for write at a specific time or
* following on from some other action in the test script.
@@ -59,7 +61,7 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
private final Transfer transfer = new Transfer();
private final DeliveryStateBuilder stateBuilder = new DeliveryStateBuilder();
- private Buffer payload;
+ private ByteBuffer payload;
private Header header;
private DeliveryAnnotations deliveryAnnotations;
@@ -81,7 +83,7 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
}
@Override
- public Buffer getPayload() {
+ public ByteBuffer getPayload() {
if (payload == null) {
payload = encodePayload();
}
@@ -212,11 +214,14 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
}
public TransferInjectAction withPayload(byte[] payload) {
- this.payload = BufferAllocator.onHeapUnpooled().copyOf(payload);
+ this.payload = ByteBuffer.allocate(payload.length);
+ this.payload.put(payload);
+ this.payload.flip().asReadOnlyBuffer();
+
return this;
}
- public TransferInjectAction withPayload(Buffer payload) {
+ public TransferInjectAction withPayload(ByteBuffer payload) {
this.payload = payload;
return this;
}
@@ -293,36 +298,43 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
return footer;
}
- private Buffer encodePayload() {
+ private ByteBuffer encodePayload() {
org.apache.qpid.protonj2.test.driver.codec.Codec codec =
org.apache.qpid.protonj2.test.driver.codec.Codec.Factory.create();
- final Buffer buffer = BufferAllocator.onHeapUnpooled().allocate(128);
- if (header != null) {
- codec.putDescribedType(header);
- }
- if (deliveryAnnotations != null) {
- codec.putDescribedType(deliveryAnnotations);
- }
- if (messageAnnotations != null) {
- codec.putDescribedType(messageAnnotations);
- }
- if (properties != null) {
- codec.putDescribedType(properties);
+ try (ByteArrayOutputStream baOS = new ByteArrayOutputStream(128);
+ DataOutputStream output = new DataOutputStream(baOS)) {
+
+ if (header != null) {
+ codec.putDescribedType(header);
+ }
+ if (deliveryAnnotations != null) {
+ codec.putDescribedType(deliveryAnnotations);
+ }
+ if (messageAnnotations != null) {
+ codec.putDescribedType(messageAnnotations);
+ }
+ if (properties != null) {
+ codec.putDescribedType(properties);
+ }
+ if (applicationProperties != null) {
+ codec.putDescribedType(applicationProperties);
+ }
+ if (body != null) {
+ codec.putDescribedType(body);
+ }
+ if (footer != null) {
+ codec.putDescribedType(footer);
+ }
+
+ codec.encode(output);
+
+ final byte[] encodedBytes = baOS.toByteArray();
+
+ return ByteBuffer.wrap(encodedBytes);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- if (applicationProperties != null) {
- codec.putDescribedType(applicationProperties);
- }
- if (body != null) {
- codec.putDescribedType(body);
- }
- if (footer != null) {
- codec.putDescribedType(footer);
- }
-
- codec.encode(buffer);
-
- return buffer.makeReadOnly();
}
protected abstract class SectionBuilder {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ArrayElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ArrayElement.java
index c705fdda..6a761ecf 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ArrayElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ArrayElement.java
@@ -16,11 +16,13 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
-import io.netty5.buffer.Buffer;
-
class ArrayElement extends AbstractElement<Object[]> {
private final boolean described;
@@ -151,134 +153,134 @@ class ArrayElement extends AbstractElement<Object[]> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
final int count = (int) count();
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
+ try {
if (!isElementOfArray()) {
if (size > 257 || count > 255) {
- buffer.writeByte((byte) 0xf0);
- buffer.writeInt(size - 5);
- buffer.writeInt(count);
+ output.writeByte((byte) 0xf0);
+ output.writeInt(size - 5);
+ output.writeInt(count);
} else {
- buffer.writeByte((byte) 0xe0);
- buffer.writeByte((byte) (size - 2));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) 0xe0);
+ output.writeByte((byte) (size - 2));
+ output.writeByte((byte) count);
}
} else {
ArrayElement parent = (ArrayElement) parent();
if (parent.constructorType() == SMALL) {
- buffer.writeByte((byte) (size - 1));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) (size - 1));
+ output.writeByte((byte) count);
} else {
- buffer.writeInt(size - 4);
- buffer.writeInt(count);
+ output.writeInt(size - 4);
+ output.writeInt(count);
}
}
Element<?> element = first;
if (isDescribed()) {
- buffer.writeByte((byte) 0);
+ output.writeByte((byte) 0);
if (element == null) {
- buffer.writeByte((byte) 0x40);
+ output.writeByte((byte) 0x40);
} else {
- element.encode(buffer);
+ element.encode(output);
element = element.next();
}
}
switch (arrayType) {
case NULL:
- buffer.writeByte((byte) 0x40);
+ output.writeByte((byte) 0x40);
break;
case BOOL:
- buffer.writeByte((byte) 0x56);
+ output.writeByte((byte) 0x56);
break;
case UBYTE:
- buffer.writeByte((byte) 0x50);
+ output.writeByte((byte) 0x50);
break;
case BYTE:
- buffer.writeByte((byte) 0x51);
+ output.writeByte((byte) 0x51);
break;
case USHORT:
- buffer.writeByte((byte) 0x60);
+ output.writeByte((byte) 0x60);
break;
case SHORT:
- buffer.writeByte((byte) 0x61);
+ output.writeByte((byte) 0x61);
break;
case UINT:
switch (constructorType()) {
case TINY:
- buffer.writeByte((byte) 0x43);
+ output.writeByte((byte) 0x43);
break;
case SMALL:
- buffer.writeByte((byte) 0x52);
+ output.writeByte((byte) 0x52);
break;
case LARGE:
- buffer.writeByte((byte) 0x70);
+ output.writeByte((byte) 0x70);
break;
}
break;
case INT:
- buffer.writeByte(constructorType == SMALL ? (byte) 0x54 : (byte) 0x71);
+ output.writeByte(constructorType == SMALL ? (byte) 0x54 : (byte) 0x71);
break;
case CHAR:
- buffer.writeByte((byte) 0x73);
+ output.writeByte((byte) 0x73);
break;
case ULONG:
switch (constructorType()) {
case TINY:
- buffer.writeByte((byte) 0x44);
+ output.writeByte((byte) 0x44);
break;
case SMALL:
- buffer.writeByte((byte) 0x53);
+ output.writeByte((byte) 0x53);
break;
case LARGE:
- buffer.writeByte((byte) 0x80);
+ output.writeByte((byte) 0x80);
break;
}
break;
case LONG:
- buffer.writeByte(constructorType == SMALL ? (byte) 0x55 : (byte) 0x81);
+ output.writeByte(constructorType == SMALL ? (byte) 0x55 : (byte) 0x81);
break;
case TIMESTAMP:
- buffer.writeByte((byte) 0x83);
+ output.writeByte((byte) 0x83);
break;
case FLOAT:
- buffer.writeByte((byte) 0x72);
+ output.writeByte((byte) 0x72);
break;
case DOUBLE:
- buffer.writeByte((byte) 0x82);
+ output.writeByte((byte) 0x82);
break;
case DECIMAL32:
- buffer.writeByte((byte) 0x74);
+ output.writeByte((byte) 0x74);
break;
case DECIMAL64:
- buffer.writeByte((byte) 0x84);
+ output.writeByte((byte) 0x84);
break;
case DECIMAL128:
- buffer.writeByte((byte) 0x94);
+ output.writeByte((byte) 0x94);
break;
case UUID:
- buffer.writeByte((byte) 0x98);
+ output.writeByte((byte) 0x98);
break;
case BINARY:
- buffer.writeByte(constructorType == SMALL ? (byte) 0xa0 : (byte) 0xb0);
+ output.writeByte(constructorType == SMALL ? (byte) 0xa0 : (byte) 0xb0);
break;
case STRING:
- buffer.writeByte(constructorType == SMALL ? (byte) 0xa1 : (byte) 0xb1);
+ output.writeByte(constructorType == SMALL ? (byte) 0xa1 : (byte) 0xb1);
break;
case SYMBOL:
- buffer.writeByte(constructorType == SMALL ? (byte) 0xa3 : (byte) 0xb3);
+ output.writeByte(constructorType == SMALL ? (byte) 0xa3 : (byte) 0xb3);
break;
case ARRAY:
- buffer.writeByte(constructorType == SMALL ? (byte) 0xe0 : (byte) 0xf0);
+ output.writeByte(constructorType == SMALL ? (byte) 0xe0 : (byte) 0xf0);
break;
case LIST:
- buffer.writeByte(constructorType == TINY ? (byte) 0x45 : constructorType == SMALL ? (byte) 0xc0 : (byte) 0xd0);
+ output.writeByte(constructorType == TINY ? (byte) 0x45 : constructorType == SMALL ? (byte) 0xc0 : (byte) 0xd0);
break;
case MAP:
- buffer.writeByte(constructorType == SMALL ? (byte) 0xc1 : (byte) 0xd1);
+ output.writeByte(constructorType == SMALL ? (byte) 0xc1 : (byte) 0xd1);
break;
case DESCRIBED:
break;
@@ -286,12 +288,12 @@ class ArrayElement extends AbstractElement<Object[]> {
break;
}
while (element != null) {
- element.encode(buffer);
+ element.encode(output);
element = element.next();
}
return size;
- } else {
- return 0;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BinaryElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BinaryElement.java
index 1d883227..aac144c2 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BinaryElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BinaryElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary;
class BinaryElement extends AtomicElement<Binary> {
@@ -68,29 +70,30 @@ class BinaryElement extends AtomicElement<Binary> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
- return 0;
- }
+ public int encode(DataOutput output) {
+ try {
+ int size = size();
- if (isElementOfArray()) {
- final ArrayElement parent = (ArrayElement) parent();
+ if (isElementOfArray()) {
+ final ArrayElement parent = (ArrayElement) parent();
- if (parent.constructorType() == ArrayElement.SMALL) {
- buffer.writeByte((byte) value.getLength());
+ if (parent.constructorType() == ArrayElement.SMALL) {
+ output.writeByte((byte) value.getLength());
+ } else {
+ output.writeInt(value.getLength());
+ }
+ } else if (value.getLength() <= 255) {
+ output.writeByte((byte) 0xa0);
+ output.writeByte((byte) value.getLength());
} else {
- buffer.writeInt(value.getLength());
+ output.writeByte((byte) 0xb0);
+ output.writeInt(value.getLength());
}
- } else if (value.getLength() <= 255) {
- buffer.writeByte((byte) 0xa0);
- buffer.writeByte((byte) value.getLength());
- } else {
- buffer.writeByte((byte) 0xb0);
- buffer.writeInt(value.getLength());
- }
- buffer.writeBytes(value.getArray(), 0, value.getLength());
- return size;
+ output.write(value.getArray(), 0, value.getLength());
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BooleanElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BooleanElement.java
index 93adb3dd..53c0fcde 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BooleanElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/BooleanElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class BooleanElement extends AtomicElement<Boolean> {
@@ -46,15 +48,16 @@ class BooleanElement extends AtomicElement<Boolean> {
}
@Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0) {
+ public int encode(DataOutput output) {
+ try {
if (isElementOfArray()) {
- buffer.writeByte(value ? (byte) 1 : (byte) 0);
+ output.writeByte(value ? (byte) 1 : (byte) 0);
} else {
- buffer.writeByte(value ? (byte) 0x41 : (byte) 0x42);
+ output.writeByte(value ? (byte) 0x41 : (byte) 0x42);
}
return 1;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ByteElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ByteElement.java
index 2cfe9b9d..24f616b5 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ByteElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ByteElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class ByteElement extends AtomicElement<Byte> {
@@ -43,19 +45,18 @@ class ByteElement extends AtomicElement<Byte> {
}
@Override
- public int encode(Buffer buffer) {
- if (isElementOfArray()) {
- if (buffer.writableBytes() > 0) {
- buffer.writeByte(value);
+ public int encode(DataOutput output) {
+ try {
+ if (isElementOfArray()) {
+ output.writeByte(value);
return 1;
- }
- } else {
- if ((buffer.implicitCapacityLimit() - buffer.capacity()) >= 2) {
- buffer.writeByte((byte) 0x51);
- buffer.writeByte(value);
+ } else {
+ output.writeByte((byte) 0x51);
+ output.writeByte(value);
return 2;
}
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CharElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CharElement.java
index 51e0a1c4..7597382d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CharElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CharElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class CharElement extends AtomicElement<Integer> {
@@ -43,14 +45,17 @@ class CharElement extends AtomicElement<Integer> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
final int size = size();
- if (size <= buffer.implicitCapacityLimit() - buffer.capacity()) {
+
+ try {
if (size == 5) {
- buffer.writeByte((byte) 0x73);
+ output.writeByte((byte) 0x73);
}
- buffer.writeInt(value);
+ output.writeInt(value);
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Codec.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Codec.java
index c6055302..b1426bf0 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Codec.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Codec.java
@@ -16,6 +16,8 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -32,8 +34,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
public interface Codec {
public static final class Factory {
@@ -91,9 +91,9 @@ public interface Codec {
long encodedSize();
- long encode(Buffer buffer);
+ long encode(OutputStream output);
- long decode(Buffer buffer);
+ long decode(ByteBuffer input);
void putList();
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CodecImpl.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CodecImpl.java
index 0eabbc03..59f17dbd 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CodecImpl.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/CodecImpl.java
@@ -16,6 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -32,8 +37,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
public class CodecImpl implements Codec {
private Element<?> first;
@@ -124,24 +127,25 @@ public class CodecImpl implements Codec {
}
@Override
- public long encode(Buffer buffer) {
- Element<?> elt = first;
- int size = 0;
- while (elt != null) {
- final int eltSize = elt.size();
- if (eltSize <= buffer.implicitCapacityLimit()) {
- size += elt.encode(buffer);
- } else {
- size += eltSize;
+ public long encode(OutputStream output) {
+ try (DataOutputStream daos = new DataOutputStream(output)) {
+ Element<?> element = first;
+ int size = 0;
+
+ while (element != null) {
+ size += element.encode(daos);
+ element = element.next();
}
- elt = elt.next();
+
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return size;
}
@Override
- public long decode(Buffer buffer) {
- return TypeDecoder.decode(buffer, this);
+ public long decode(ByteBuffer input) {
+ return TypeDecoder.decode(input, this);
}
private void putElement(Element<?> element) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal128Element.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal128Element.java
index 608a0adf..4ff5e71c 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal128Element.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal128Element.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal128;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal128;
class Decimal128Element extends AtomicElement<Decimal128> {
@@ -45,17 +47,18 @@ class Decimal128Element extends AtomicElement<Decimal128> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
+
+ try {
if (size == 17) {
- buffer.writeByte((byte) 0x94);
+ output.writeByte((byte) 0x94);
}
- buffer.writeLong(value.getMostSignificantBits());
- buffer.writeLong(value.getLeastSignificantBits());
+ output.writeLong(value.getMostSignificantBits());
+ output.writeLong(value.getLeastSignificantBits());
return size;
- } else {
- return 0;
+ } catch(IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal32Element.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal32Element.java
index 887d0c6f..a08e6d7a 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal32Element.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal32Element.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal32;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal32;
class Decimal32Element extends AtomicElement<Decimal32> {
@@ -45,16 +47,17 @@ class Decimal32Element extends AtomicElement<Decimal32> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
+
+ try {
if (size == 5) {
- buffer.writeByte((byte) 0x74);
+ output.writeByte((byte) 0x74);
}
- buffer.writeInt(value.getBits());
+ output.writeInt(value.getBits());
return size;
- } else {
- return 0;
+ } catch(IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal64Element.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal64Element.java
index a0eda734..16775a7d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal64Element.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Decimal64Element.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal64;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal64;
class Decimal64Element extends AtomicElement<Decimal64> {
@@ -45,16 +47,17 @@ class Decimal64Element extends AtomicElement<Decimal64> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
+ public int encode(DataOutput output) {
+ final int size = size();
+
+ try {
if (size == 9) {
- buffer.writeByte((byte) 0x84);
+ output.writeByte((byte) 0x84);
}
- buffer.writeLong(value.getBits());
+ output.writeLong(value.getBits());
return size;
- } else {
- return 0;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DescribedTypeElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DescribedTypeElement.java
index a94c4364..be1ac8a9 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DescribedTypeElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DescribedTypeElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
class DescribedTypeElement extends AbstractElement<DescribedType> {
@@ -68,25 +70,26 @@ class DescribedTypeElement extends AbstractElement<DescribedType> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int encodedSize = size();
- if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- } else {
- buffer.writeByte((byte) 0);
+ try {
+ output.writeByte((byte) 0);
if (first == null) {
- buffer.writeByte((byte) 0x40);
- buffer.writeByte((byte) 0x40);
+ output.writeByte((byte) 0x40);
+ output.writeByte((byte) 0x40);
} else {
- first.encode(buffer);
+ first.encode(output);
if (first.next() == null) {
- buffer.writeByte((byte) 0x40);
+ output.writeByte((byte) 0x40);
} else {
- first.next().encode(buffer);
+ first.next().encode(output);
}
}
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
+
return encodedSize;
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DoubleElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DoubleElement.java
index 3ae02139..ea17351c 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DoubleElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/DoubleElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class DoubleElement extends AtomicElement<Double> {
@@ -43,16 +45,17 @@ class DoubleElement extends AtomicElement<Double> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
+
+ try {
if (size == 9) {
- buffer.writeByte((byte) 0x82);
+ output.writeByte((byte) 0x82);
}
- buffer.writeDouble(value);
+ output.writeDouble(value);
return size;
- } else {
- return 0;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Element.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Element.java
index c94c3489..97af43b9 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Element.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/Element.java
@@ -16,7 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
interface Element<T> {
@@ -26,7 +26,7 @@ interface Element<T> {
Codec.DataType getDataType();
- int encode(Buffer buffer);
+ int encode(DataOutput output);
Element<?> next();
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/FloatElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/FloatElement.java
index 2ca919af..0f0af418 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/FloatElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/FloatElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class FloatElement extends AtomicElement<Float> {
@@ -43,16 +45,17 @@ class FloatElement extends AtomicElement<Float> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
- if (buffer.implicitCapacityLimit() >= size) {
+
+ try {
if (size == 5) {
- buffer.writeByte((byte) 0x72);
+ output.writeByte((byte) 0x72);
}
- buffer.writeFloat(value);
+ output.writeFloat(value);
return size;
- } else {
- return 0;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/IntegerElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/IntegerElement.java
index ae657946..815738af 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/IntegerElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/IntegerElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class IntegerElement extends AtomicElement<Integer> {
@@ -57,25 +59,25 @@ class IntegerElement extends AtomicElement<Integer> {
}
@Override
- public int encode(Buffer buffer) {
+ public int encode(DataOutput output) {
int size = size();
- if (size <= buffer.implicitCapacityLimit() - buffer.capacity()) {
+
+ try {
switch (size) {
case 2:
- buffer.writeByte((byte) 0x54);
+ output.writeByte((byte) 0x54);
case 1:
- buffer.writeByte((byte) value);
+ output.writeByte((byte) value);
break;
-
case 5:
- buffer.writeByte((byte) 0x71);
+ output.writeByte((byte) 0x71);
case 4:
- buffer.writeInt(value);
-
+ output.writeInt(value);
}
return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ListElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ListElement.java
index 2e1a4870..d9aae25e 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ListElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ListElement.java
@@ -16,12 +16,13 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import io.netty5.buffer.Buffer;
-
class ListElement extends AbstractElement<List<Object>> {
private Element<?> first;
@@ -99,54 +100,54 @@ class ListElement extends AbstractElement<List<Object>> {
}
@Override
- public int encode(Buffer buffer) {
- int encodedSize = size();
+ public int encode(DataOutput output) {
+ try {
+ int encodedSize = size();
- int count = 0;
- int size = 0;
- Element<?> elt = first;
- while (elt != null) {
- count++;
- size += elt.size();
- elt = elt.next();
- }
+ int count = 0;
+ int size = 0;
+ Element<?> elt = first;
+ while (elt != null) {
+ count++;
+ size += elt.size();
+ elt = elt.next();
+ }
- if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- } else {
if (isElementOfArray()) {
switch (((ArrayElement) parent()).constructorType()) {
case TINY:
break;
case SMALL:
- buffer.writeByte((byte) (size + 1));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) (size + 1));
+ output.writeByte((byte) count);
break;
case LARGE:
- buffer.writeInt((size + 4));
- buffer.writeInt(count);
+ output.writeInt((size + 4));
+ output.writeInt(count);
}
} else {
if (count == 0) {
- buffer.writeByte((byte) 0x45);
+ output.writeByte((byte) 0x45);
} else if (size <= 254 && count <= 255) {
- buffer.writeByte((byte) 0xc0);
- buffer.writeByte((byte) (size + 1));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) 0xc0);
+ output.writeByte((byte) (size + 1));
+ output.writeByte((byte) count);
} else {
- buffer.writeByte((byte) 0xd0);
- buffer.writeInt((size + 4));
- buffer.writeInt(count);
+ output.writeByte((byte) 0xd0);
+ output.writeInt((size + 4));
+ output.writeInt(count);
}
}
elt = first;
while (elt != null) {
- elt.encode(buffer);
+ elt.encode(output);
elt = elt.next();
}
return encodedSize;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/LongElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/LongElement.java
index 6349c820..85bbdf0f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/LongElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/LongElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class LongElement extends AtomicElement<Long> {
@@ -59,23 +61,25 @@ class LongElement extends AtomicElement<Long> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- }
- switch (size) {
- case 2:
- buffer.writeByte((byte) 0x55);
- case 1:
- buffer.writeByte((byte) value);
- break;
- case 9:
- buffer.writeByte((byte) 0x81);
- case 8:
- buffer.writeLong(value);
+ public int encode(DataOutput output) {
+ try {
+ int size = size();
+
+ switch (size) {
+ case 2:
+ output.writeByte((byte) 0x55);
+ case 1:
+ output.writeByte((byte) value);
+ break;
+ case 9:
+ output.writeByte((byte) 0x81);
+ case 8:
+ output.writeLong(value);
+ }
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return size;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/MapElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/MapElement.java
index e3f4fbe8..912145f5 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/MapElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/MapElement.java
@@ -16,12 +16,13 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
-import io.netty5.buffer.Buffer;
-
class MapElement extends AbstractElement<Map<Object, Object>> {
private Element<?> first;
@@ -100,30 +101,28 @@ class MapElement extends AbstractElement<Map<Object, Object>> {
}
@Override
- public int encode(Buffer buffer) {
- int encodedSize = size();
+ public int encode(DataOutput output) {
+ try {
+ int encodedSize = size();
- int count = 0;
- int size = 0;
- Element<?> elt = first;
- while (elt != null) {
- count++;
- size += elt.size();
- elt = elt.next();
- }
+ int count = 0;
+ int size = 0;
+ Element<?> elt = first;
+ while (elt != null) {
+ count++;
+ size += elt.size();
+ elt = elt.next();
+ }
- if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- } else {
if (isElementOfArray()) {
switch (((ArrayElement) parent()).constructorType()) {
case SMALL:
- buffer.writeByte((byte) (size + 1));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) (size + 1));
+ output.writeByte((byte) count);
break;
case LARGE:
- buffer.writeInt((size + 4));
- buffer.writeInt(count);
+ output.writeInt((size + 4));
+ output.writeInt(count);
case TINY:
break;
default:
@@ -131,23 +130,25 @@ class MapElement extends AbstractElement<Map<Object, Object>> {
}
} else {
if (size <= 254 && count <= 255) {
- buffer.writeByte((byte) 0xc1);
- buffer.writeByte((byte) (size + 1));
- buffer.writeByte((byte) count);
+ output.writeByte((byte) 0xc1);
+ output.writeByte((byte) (size + 1));
+ output.writeByte((byte) count);
} else {
- buffer.writeByte((byte) 0xd1);
- buffer.writeInt((size + 4));
- buffer.writeInt(count);
+ output.writeByte((byte) 0xd1);
+ output.writeInt((size + 4));
+ output.writeInt(count);
}
}
elt = first;
while (elt != null) {
- elt.encode(buffer);
+ elt.encode(output);
elt = elt.next();
}
return encodedSize;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
index 675c9da4..e6ce5c48 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class NullElement extends AtomicElement<Void> {
@@ -40,11 +42,12 @@ class NullElement extends AtomicElement<Void> {
}
@Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0 && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
+ public int encode(DataOutput output) {
+ try {
+ output.writeByte((byte) 0x40);
return 1;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ShortElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ShortElement.java
index 58680420..2946f087 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ShortElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/ShortElement.java
@@ -16,7 +16,9 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
class ShortElement extends AtomicElement<Short> {
@@ -43,19 +45,18 @@ class ShortElement extends AtomicElement<Short> {
}
@Override
- public int encode(Buffer buffer) {
- if (isElementOfArray()) {
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
- buffer.writeShort(value);
+ public int encode(DataOutput output) {
+ try {
+ if (isElementOfArray()) {
+ output.writeShort(value);
return 2;
- }
- } else {
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= 3) {
- buffer.writeByte((byte) 0x61);
- buffer.writeShort(value);
+ } else {
+ output.writeByte((byte) 0x61);
+ output.writeShort(value);
return 3;
}
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/StringElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/StringElement.java
index 895b279e..198ba443 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/StringElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/StringElement.java
@@ -16,10 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.charset.Charset;
-import io.netty5.buffer.Buffer;
-
class StringElement extends AtomicElement<String> {
private static final Charset UTF_8 = Charset.forName("UTF-8");
@@ -71,30 +72,32 @@ class StringElement extends AtomicElement<String> {
}
@Override
- public int encode(Buffer buffer) {
- final byte[] bytes = value.getBytes(UTF_8);
- final int length = bytes.length;
+ public int encode(DataOutput output) {
+ try {
+ final byte[] bytes = value.getBytes(UTF_8);
+ final int length = bytes.length;
- int size = size(length);
- if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
- return 0;
- }
- if (isElementOfArray()) {
- final ArrayElement parent = (ArrayElement) parent();
+ int size = size(length);
- if (parent.constructorType() == ArrayElement.SMALL) {
- buffer.writeByte((byte) length);
+ if (isElementOfArray()) {
+ final ArrayElement parent = (ArrayElement) parent();
+
+ if (parent.constructorType() == ArrayElement.SMALL) {
+ output.writeByte((byte) length);
+ } else {
+ output.writeInt(length);
+ }
+ } else if (length <= 255) {
+ output.writeByte((byte) 0xa1);
+ output.writeByte((byte) length);
} else {
- buffer.writeInt(length);
+ output.writeByte((byte) 0xb1);
+ output.writeInt(length);
}
- } else if (length <= 255) {
- buffer.writeByte((byte) 0xa1);
- buffer.writeByte((byte) length);
- } else {
- buffer.writeByte((byte) 0xb1);
- buffer.writeInt(length);
+ output.write(bytes);
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- buffer.writeBytes(bytes);
- return size;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/SymbolElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/SymbolElement.java
index 7fb28766..8f24630a 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/SymbolElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/SymbolElement.java
@@ -16,12 +16,13 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
-import io.netty5.buffer.Buffer;
-
class SymbolElement extends AtomicElement<Symbol> {
private static final Charset ASCII = Charset.forName("US-ASCII");
@@ -69,27 +70,29 @@ class SymbolElement extends AtomicElement<Symbol> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
- return 0;
- }
- if (isElementOfArray()) {
- final ArrayElement parent = (ArrayElement) parent();
+ public int encode(DataOutput output) {
+ try {
+ int size = size();
- if (parent.constructorType() == ArrayElement.SMALL) {
- buffer.writeByte((byte) value.getLength());
+ if (isElementOfArray()) {
+ final ArrayElement parent = (ArrayElement) parent();
+
+ if (parent.constructorType() == ArrayElement.SMALL) {
+ output.writeByte((byte) value.getLength());
+ } else {
+ output.writeInt(value.getLength());
+ }
+ } else if (value.getLength() <= 255) {
+ output.writeByte((byte) 0xa3);
+ output.writeByte((byte) value.getLength());
} else {
- buffer.writeInt(value.getLength());
+ output.writeByte((byte) 0xb3);
+ output.writeByte((byte) value.getLength());
}
- } else if (value.getLength() <= 255) {
- buffer.writeByte((byte) 0xa3);
- buffer.writeByte((byte) value.getLength());
- } else {
- buffer.writeByte((byte) 0xb3);
- buffer.writeByte((byte) value.getLength());
+ output.write(value.toString().getBytes(ASCII));
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- buffer.writeBytes(value.toString().getBytes(ASCII));
- return size;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TimestampElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TimestampElement.java
index abdd51c7..05319d79 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TimestampElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TimestampElement.java
@@ -16,10 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.Date;
-import io.netty5.buffer.Buffer;
-
class TimestampElement extends AtomicElement<Date> {
private final Date value;
@@ -45,16 +46,19 @@ class TimestampElement extends AtomicElement<Date> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- }
- if (size == 9) {
- buffer.writeByte((byte) 0x83);
- }
- buffer.writeLong(value.getTime());
+ public int encode(DataOutput output) {
+ try {
+ final int size = size();
- return size;
+ if (size == 9) {
+ output.writeByte((byte) 0x83);
+ }
+
+ output.writeLong(value.getTime());
+
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TypeDecoder.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TypeDecoder.java
index e532ddc7..8d11011a 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TypeDecoder.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/TypeDecoder.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.UUID;
@@ -29,8 +30,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
class TypeDecoder {
private static final Charset ASCII = Charset.forName("US-ASCII");
@@ -96,30 +95,23 @@ class TypeDecoder {
Codec.DataType getType();
- int size(Buffer buffer);
+ int size(ByteBuffer input);
- void parse(Buffer buffer, Codec data);
+ void parse(ByteBuffer input, Codec data);
}
- static int decode(Buffer buffer, Codec data) {
- if (buffer.readableBytes() > 0) {
- final int position = buffer.readerOffset();
- final TypeConstructor c = readConstructor(buffer);
- final int size = c.size(buffer);
- if (buffer.readableBytes() >= size) {
- c.parse(buffer, data);
- return 1 + size;
- } else {
- buffer.readerOffset(position);
- return -4;
- }
- }
- return 0;
+ static int decode(ByteBuffer input, Codec data) {
+ final TypeConstructor c = readConstructor(input);
+ final int size = c.size(input);
+
+ c.parse(input, data);
+
+ return 1 + size;
}
- private static TypeConstructor readConstructor(Buffer buffer) {
- final int index = buffer.readByte() & 0xff;
+ private static TypeConstructor readConstructor(ByteBuffer input) {
+ final int index = input.get() & 0xff;
final TypeConstructor tc = constructors[index];
if (tc == null) {
throw new IllegalArgumentException("No constructor for type " + index);
@@ -135,12 +127,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putNull();
}
}
@@ -153,12 +145,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putBoolean(true);
}
}
@@ -171,12 +163,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putBoolean(false);
}
}
@@ -189,12 +181,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putUnsignedInteger(UnsignedInteger.ZERO);
}
}
@@ -207,12 +199,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putUnsignedLong(UnsignedLong.ZERO);
}
}
@@ -225,12 +217,12 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 0;
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putList();
}
}
@@ -239,7 +231,7 @@ class TypeDecoder {
private static abstract class Fixed0SizeConstructor implements TypeConstructor {
@Override
- public final int size(Buffer buffer) {
+ public final int size(ByteBuffer input) {
return 0;
}
}
@@ -247,7 +239,7 @@ class TypeDecoder {
private static abstract class Fixed1SizeConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 1;
}
}
@@ -255,7 +247,7 @@ class TypeDecoder {
private static abstract class Fixed2SizeConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 2;
}
}
@@ -263,7 +255,7 @@ class TypeDecoder {
private static abstract class Fixed4SizeConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 4;
}
}
@@ -271,7 +263,7 @@ class TypeDecoder {
private static abstract class Fixed8SizeConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 8;
}
}
@@ -279,7 +271,7 @@ class TypeDecoder {
private static abstract class Fixed16SizeConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
+ public int size(ByteBuffer input) {
return 16;
}
}
@@ -292,8 +284,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedByte(UnsignedByte.valueOf(buffer.readByte()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedByte(UnsignedByte.valueOf(input.get()));
}
}
@@ -305,8 +297,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putByte(buffer.readByte());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putByte(input.get());
}
}
@@ -317,9 +309,10 @@ class TypeDecoder {
return Codec.DataType.UINT;
}
+
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedInteger(UnsignedInteger.valueOf((buffer.readByte()) & 0xff));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedInteger(UnsignedInteger.valueOf((input.get()) & 0xff));
}
}
@@ -331,8 +324,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putInt(buffer.readByte());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putInt(input.get());
}
}
@@ -343,9 +336,10 @@ class TypeDecoder {
return Codec.DataType.ULONG;
}
+
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedLong(UnsignedLong.valueOf((buffer.readByte()) & 0xff));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedLong(UnsignedLong.valueOf((input.get()) & 0xff));
}
}
@@ -357,8 +351,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putLong(buffer.readByte());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putLong(input.get());
}
}
@@ -370,8 +364,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int i = buffer.readByte();
+ public void parse(ByteBuffer input, Codec data) {
+ final int i = input.get();
if (i != 0 && i != 1) {
throw new IllegalArgumentException("Illegal value " + i + " for boolean");
}
@@ -387,8 +381,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedShort(UnsignedShort.valueOf(buffer.readShort()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedShort(UnsignedShort.valueOf(input.getShort()));
}
}
@@ -400,8 +394,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putShort(buffer.readShort());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putShort(input.getShort());
}
}
@@ -413,8 +407,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedInteger(UnsignedInteger.valueOf(buffer.readInt()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedInteger(UnsignedInteger.valueOf(input.getInt()));
}
}
@@ -426,8 +420,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putInt(buffer.readInt());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putInt(input.getInt());
}
}
@@ -439,8 +433,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putFloat(buffer.readFloat());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putFloat(input.getFloat());
}
}
@@ -452,8 +446,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putChar(buffer.readInt());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putChar(input.getInt());
}
}
@@ -465,8 +459,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putDecimal32(new Decimal32(buffer.readInt()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putDecimal32(new Decimal32(input.getInt()));
}
}
@@ -478,8 +472,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUnsignedLong(UnsignedLong.valueOf(buffer.readLong()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUnsignedLong(UnsignedLong.valueOf(input.getLong()));
}
}
@@ -491,8 +485,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putLong(buffer.readLong());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putLong(input.getLong());
}
}
@@ -504,8 +498,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putDouble(buffer.readDouble());
+ public void parse(ByteBuffer input, Codec data) {
+ data.putDouble(input.getDouble());
}
}
@@ -517,8 +511,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putTimestamp(new Date(buffer.readLong()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putTimestamp(new Date(input.getLong()));
}
}
@@ -530,8 +524,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putDecimal64(new Decimal64(buffer.readLong()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putDecimal64(new Decimal64(input.getLong()));
}
}
@@ -543,8 +537,8 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putDecimal128(new Decimal128(buffer.readLong(), buffer.readLong()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putDecimal128(new Decimal128(input.getLong(), input.getLong()));
}
}
@@ -556,43 +550,39 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- data.putUUID(new UUID(buffer.readLong(), buffer.readLong()));
+ public void parse(ByteBuffer input, Codec data) {
+ data.putUUID(new UUID(input.getLong(), input.getLong()));
}
}
private static abstract class SmallVariableConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
- final int position = buffer.readerOffset();
- if (buffer.readableBytes() > 0) {
- final int size = buffer.readByte() & 0xff;
- buffer.readerOffset(position);
-
+ public int size(ByteBuffer input) {
+ final int position = input.position();
+ if (input.remaining() > 0) {
+ final int size = input.get() & 0xff;
+ input.position(position);
return size + 1;
} else {
return 1;
}
}
-
}
private static abstract class VariableConstructor implements TypeConstructor {
@Override
- public int size(Buffer buffer) {
- final int position = buffer.readerOffset();
- if (buffer.readableBytes() >= 4) {
- final int size = buffer.readInt();
- buffer.readerOffset(position);
-
+ public int size(ByteBuffer input) {
+ final int position = input.position();
+ if (input.remaining() >= 4) {
+ final int size = input.getInt();
+ input.position(position);
return size + 4;
} else {
return 4;
}
}
-
}
private static class SmallBinaryConstructor extends SmallVariableConstructor {
@@ -603,10 +593,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readByte() & 0xff;
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putBinary(bytes);
}
}
@@ -619,10 +609,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readByte() & 0xff;
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putSymbol(Symbol.valueOf(new String(bytes, ASCII)));
}
}
@@ -635,10 +625,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readByte() & 0xff;
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putString(new String(bytes, UTF_8));
}
}
@@ -651,10 +641,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readInt();
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putBinary(bytes);
}
}
@@ -667,10 +657,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readInt();
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putSymbol(Symbol.valueOf(new String(bytes, ASCII)));
}
}
@@ -683,10 +673,10 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readInt();
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
final byte[] bytes = new byte[size];
- buffer.readBytes(bytes, 0, bytes.length);
+ input.get(bytes, 0, bytes.length);
data.putString(new String(bytes, UTF_8));
}
}
@@ -699,14 +689,17 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- int size = buffer.readByte() & 0xff;
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readByte() & 0xff;
- data.putList();
- parseChildren(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
+ final ByteBuffer duplicate = input.slice().asReadOnlyBuffer();
+ final int count = duplicate.get() & 0xff;
+
+ // Skip bytes in the source buffer
+ input.position(input.position() + size);
+
+ // Now parse the actual type encoding using the duplicate
+ data.putList();
+ parseChildren(data, duplicate, count);
}
}
@@ -718,14 +711,17 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- int size = buffer.readByte() & 0xff;
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readByte() & 0xff;
- data.putMap();
- parseChildren(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
+ final ByteBuffer duplicate = input.slice().asReadOnlyBuffer();
+ final int count = duplicate.get() & 0xff;
+
+ // Skip bytes in the source buffer
+ input.position(input.position() + size);
+
+ // Now parse the actual type encoding using the duplicate
+ data.putMap();
+ parseChildren(data, duplicate, count);
}
}
@@ -737,14 +733,17 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- int size = buffer.readInt();
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readInt();
- data.putList();
- parseChildren(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
+ final ByteBuffer duplicate = input.slice().asReadOnlyBuffer();
+ final int count = duplicate.getInt();
+
+ // Skip bytes in the source buffer
+ input.position(input.position() + size);
+
+ // Now parse the actual type encoding using the duplicate
+ data.putList();
+ parseChildren(data, duplicate, count);
}
}
@@ -756,25 +755,28 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- int size = buffer.readInt();
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readInt();
- data.putMap();
- parseChildren(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
+ final ByteBuffer duplicate = input.slice().asReadOnlyBuffer();
+ final int count = duplicate.getInt();
+
+ // Skip bytes in the source buffer
+ input.position(input.position() + size);
+
+ // Now parse the actual type encoding using the duplicate
+ data.putMap();
+ parseChildren(data, duplicate, count);
}
}
- private static void parseChildren(Codec data, Buffer buf, int count) {
+ private static void parseChildren(Codec data, ByteBuffer input, int count) {
data.enter();
for (int i = 0; i < count; i++) {
- final TypeConstructor c = readConstructor(buf);
- final int size = c.size(buf);
- final int getReadableBytes = buf.readableBytes();
+ final TypeConstructor c = readConstructor(input);
+ final int size = c.size(input);
+ final int getReadableBytes = input.remaining();
if (size <= getReadableBytes) {
- c.parse(buf, data);
+ c.parse(input, data);
} else {
throw new IllegalArgumentException("Malformed data");
}
@@ -791,32 +793,24 @@ class TypeDecoder {
}
@Override
- public int size(Buffer buffer) {
- try (Buffer buf = buffer.copy(true)) {
- if (buf.readableBytes() > 0) {
- TypeConstructor c = readConstructor(buf);
- final int size = c.size(buf);
- if (buf.readableBytes() > size) {
- buf.readerOffset(size + 1);
- c = readConstructor(buf);
- return size + 2 + c.size(buf);
- } else {
- return size + 2;
- }
- } else {
- return 1;
- }
- }
+ public int size(ByteBuffer input) {
+ final ByteBuffer buf = input.slice().asReadOnlyBuffer();
+ TypeConstructor c = readConstructor(buf);
+ final int size = c.size(buf);
+
+ buf.position(size + 1);
+ c = readConstructor(buf);
+ return size + 2 + c.size(buf);
}
@Override
- public void parse(Buffer buffer, Codec data) {
+ public void parse(ByteBuffer input, Codec data) {
data.putDescribed();
data.enter();
- TypeConstructor c = readConstructor(buffer);
- c.parse(buffer, data);
- c = readConstructor(buffer);
- c.parse(buffer, data);
+ TypeConstructor c = readConstructor(input);
+ c.parse(input, data);
+ c = readConstructor(input);
+ c.parse(input, data);
data.exit();
}
}
@@ -829,13 +823,13 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readByte() & 0xff;
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readByte() & 0xff;
- parseArray(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.get() & 0xff;
+ final ByteBuffer buf = input.slice().asReadOnlyBuffer();
+
+ input.position(input.position() + size);
+ final int count = buf.get() & 0xff;
+ parseArray(data, buf, count);
}
}
@@ -847,42 +841,45 @@ class TypeDecoder {
}
@Override
- public void parse(Buffer buffer, Codec data) {
- final int size = buffer.readInt();
- try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
- buffer.skipReadableBytes(size);
- final int count = buf.readInt();
- parseArray(data, buf, count);
- }
+ public void parse(ByteBuffer input, Codec data) {
+ final int size = input.getInt();
+ final ByteBuffer buf = input.slice().asReadOnlyBuffer();
+
+ input.position(input.position() + size);
+ final int count = buf.getInt();
+ parseArray(data, buf, count);
}
}
- private static void parseArray(Codec data, Buffer buffer, int count) {
- byte type = buffer.readByte();
- boolean isDescribed = type == (byte) 0x00;
- final int descriptorPosition = buffer.readerOffset();
+ private static void parseArray(Codec data, ByteBuffer input, int count) {
+ byte type = input.get();
+
+ final boolean isDescribed = type == (byte) 0x00;
+ final int descriptorPosition = input.position();
+
if (isDescribed) {
- final TypeConstructor descriptorTc = readConstructor(buffer);
- buffer.skipReadableBytes(descriptorTc.size(buffer));
- type = buffer.readByte();
+ final TypeConstructor descriptorTc = readConstructor(input);
+ input.position(input.position() + descriptorTc.size(input));
+ type = input.get();
if (type == (byte) 0x00) {
throw new IllegalArgumentException("Malformed array data");
}
-
}
- TypeConstructor tc = constructors[type & 0xff];
+
+ final TypeConstructor tc = constructors[type & 0xff];
data.putArray(isDescribed, tc.getType());
data.enter();
+
if (isDescribed) {
- final int position = buffer.readerOffset();
- buffer.readerOffset(descriptorPosition);
- final TypeConstructor descriptorTc = readConstructor(buffer);
- descriptorTc.parse(buffer, data);
- buffer.readerOffset(position);
+ final int position = input.position();
+ input.position(descriptorPosition);
+ final TypeConstructor descriptorTc = readConstructor(input);
+ descriptorTc.parse(input, data);
+ input.position(position);
}
for (int i = 0; i < count; i++) {
- tc.parse(buffer, data);
+ tc.parse(input, data);
}
data.exit();
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UUIDElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UUIDElement.java
index 5c86ceac..802e613d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UUIDElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UUIDElement.java
@@ -16,10 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.UUID;
-import io.netty5.buffer.Buffer;
-
class UUIDElement extends AtomicElement<UUID> {
private final UUID value;
@@ -45,17 +46,18 @@ class UUIDElement extends AtomicElement<UUID> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (buffer.implicitCapacityLimit() >= size) {
+ public int encode(DataOutput output) {
+ final int size = size();
+
+ try {
if (size == 17) {
- buffer.writeByte((byte) 0x98);
+ output.writeByte((byte) 0x98);
}
- buffer.writeLong(value.getMostSignificantBits());
- buffer.writeLong(value.getLeastSignificantBits());
+ output.writeLong(value.getMostSignificantBits());
+ output.writeLong(value.getLeastSignificantBits());
return size;
- } else {
- return 0;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedByteElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedByteElement.java
index cad775f3..83945dc1 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedByteElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedByteElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte;
class UnsignedByteElement extends AtomicElement<UnsignedByte> {
@@ -45,19 +47,18 @@ class UnsignedByteElement extends AtomicElement<UnsignedByte> {
}
@Override
- public int encode(Buffer buffer) {
- if (isElementOfArray()) {
- if (buffer.writableBytes() > 0) {
- buffer.writeByte(value.byteValue());
+ public int encode(DataOutput output) {
+ try {
+ if (isElementOfArray()) {
+ output.writeByte(value.byteValue());
return 1;
- }
- } else {
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
- buffer.writeByte((byte) 0x50);
- buffer.writeByte(value.byteValue());
+ } else {
+ output.writeByte((byte) 0x50);
+ output.writeByte(value.byteValue());
return 2;
}
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedIntegerElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedIntegerElement.java
index ff7750c2..b77a8ec6 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedIntegerElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedIntegerElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
class UnsignedIntegerElement extends AtomicElement<UnsignedInteger> {
@@ -68,30 +70,31 @@ class UnsignedIntegerElement extends AtomicElement<UnsignedInteger> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- }
- switch (size) {
- case 1:
- if (isElementOfArray()) {
- buffer.writeByte((byte) value.intValue());
- } else {
- buffer.writeByte((byte) 0x43);
- }
- break;
- case 2:
- buffer.writeByte((byte) 0x52);
- buffer.writeByte((byte) value.intValue());
- break;
- case 5:
- buffer.writeByte((byte) 0x70);
- case 4:
- buffer.writeInt(value.intValue());
+ public int encode(DataOutput output) {
+ try {
+ int size = size();
- }
+ switch (size) {
+ case 1:
+ if (isElementOfArray()) {
+ output.writeByte((byte) value.intValue());
+ } else {
+ output.writeByte((byte) 0x43);
+ }
+ break;
+ case 2:
+ output.writeByte((byte) 0x52);
+ output.writeByte((byte) value.intValue());
+ break;
+ case 5:
+ output.writeByte((byte) 0x70);
+ case 4:
+ output.writeInt(value.intValue());
+ }
- return size;
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedLongElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedLongElement.java
index 89a31790..bc01af78 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedLongElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedLongElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
class UnsignedLongElement extends AtomicElement<UnsignedLong> {
@@ -68,30 +70,31 @@ class UnsignedLongElement extends AtomicElement<UnsignedLong> {
}
@Override
- public int encode(Buffer buffer) {
- int size = size();
- if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
- return 0;
- }
- switch (size) {
- case 1:
- if (isElementOfArray()) {
- buffer.writeByte((byte) value.longValue());
- } else {
- buffer.writeByte((byte) 0x44);
- }
- break;
- case 2:
- buffer.writeByte((byte) 0x53);
- buffer.writeByte((byte) value.longValue());
- break;
- case 9:
- buffer.writeByte((byte) 0x80);
- case 8:
- buffer.writeLong(value.longValue());
+ public int encode(DataOutput output) {
+ try {
+ int size = size();
- }
+ switch (size) {
+ case 1:
+ if (isElementOfArray()) {
+ output.writeByte((byte) value.longValue());
+ } else {
+ output.writeByte((byte) 0x44);
+ }
+ break;
+ case 2:
+ output.writeByte((byte) 0x53);
+ output.writeByte((byte) value.longValue());
+ break;
+ case 9:
+ output.writeByte((byte) 0x80);
+ case 8:
+ output.writeLong(value.longValue());
+ }
- return size;
+ return size;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedShortElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedShortElement.java
index 8fd67eca..7bcc8772 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedShortElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/UnsignedShortElement.java
@@ -16,9 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
-import io.netty5.buffer.Buffer;
+import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
class UnsignedShortElement extends AtomicElement<UnsignedShort> {
@@ -45,19 +47,18 @@ class UnsignedShortElement extends AtomicElement<UnsignedShort> {
}
@Override
- public int encode(Buffer buffer) {
- if (isElementOfArray()) {
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
- buffer.writeShort(value.shortValue());
+ public int encode(DataOutput output) {
+ try {
+ if (isElementOfArray()) {
+ output.writeShort(value.shortValue());
return 2;
- }
- } else {
- if (buffer.implicitCapacityLimit() - buffer.capacity() >= 3) {
- buffer.writeByte((byte) 0x60);
- buffer.writeShort(value.shortValue());
+ } else {
+ output.writeByte((byte) 0x60);
+ output.writeShort(value.shortValue());
return 3;
}
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- return 0;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Attach.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Attach.java
index 112ea4c0..02c61a7f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Attach.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Attach.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -30,8 +31,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.transactions.Coordinator;
-import io.netty5.buffer.Buffer;
-
public class Attach extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:attach:list");
@@ -252,7 +251,7 @@ public class Attach extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleAttach(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Begin.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Begin.java
index 6ed6a274..480f80dc 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Begin.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Begin.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -25,8 +26,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
public class Begin extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:begin:list");
@@ -143,7 +142,7 @@ public class Begin extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleBegin(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Close.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Close.java
index a0085163..cf104c46 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Close.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Close.java
@@ -16,13 +16,12 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class Close extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:close:list");
@@ -68,7 +67,7 @@ public class Close extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleClose(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Detach.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Detach.java
index fb88391e..8749d9d4 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Detach.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Detach.java
@@ -16,14 +16,13 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class Detach extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:detach:list");
@@ -89,7 +88,7 @@ public class Detach extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleDetach(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Disposition.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Disposition.java
index aadfa5be..be91867c 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Disposition.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Disposition.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
@@ -23,8 +24,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class Disposition extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:disposition:list");
@@ -120,7 +119,7 @@ public class Disposition extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleDisposition(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/End.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/End.java
index 82712f56..a5c35c1d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/End.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/End.java
@@ -16,13 +16,12 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class End extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:end:list");
@@ -68,7 +67,7 @@ public class End extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleEnd(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Flow.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Flow.java
index 11f8e71f..adeef7f9 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Flow.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Flow.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
@@ -23,8 +24,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class Flow extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:flow:list");
@@ -171,7 +170,7 @@ public class Flow extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleFlow(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/HeartBeat.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/HeartBeat.java
index 1d024f62..afa4a37f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/HeartBeat.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/HeartBeat.java
@@ -16,7 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
-import io.netty5.buffer.Buffer;
+import java.nio.ByteBuffer;
/**
* Dummy Performative that is fired whenever an Empty frame is received
@@ -40,7 +40,7 @@ public class HeartBeat extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleHeartBeat(frameSize, INSTANCE, payload, channel, context);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Open.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Open.java
index 82c28d57..95d5ba8f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Open.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Open.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -25,8 +26,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty5.buffer.Buffer;
-
public class Open extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:open:list");
@@ -163,7 +162,7 @@ public class Open extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleOpen(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/PerformativeDescribedType.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/PerformativeDescribedType.java
index 48a7cb73..d57bd265 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/PerformativeDescribedType.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/PerformativeDescribedType.java
@@ -16,12 +16,11 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.ListDescribedType;
-import io.netty5.buffer.Buffer;
-
/**
* AMQP Performative marker class for DescribedType elements in this codec.
*/
@@ -52,34 +51,34 @@ public abstract class PerformativeDescribedType extends ListDescribedType {
public interface PerformativeHandler<E> {
- default void handleOpen(int frameSize, Open open, Buffer payload, int channel, E context) {
+ default void handleOpen(int frameSize, Open open, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Open was not handled");
}
- default void handleBegin(int frameSize, Begin begin, Buffer payload, int channel, E context) {
+ default void handleBegin(int frameSize, Begin begin, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Begin was not handled");
}
- default void handleAttach(int frameSize, Attach attach, Buffer payload, int channel, E context) {
+ default void handleAttach(int frameSize, Attach attach, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Attach was not handled");
}
- default void handleFlow(int frameSize, Flow flow, Buffer payload, int channel, E context) {
+ default void handleFlow(int frameSize, Flow flow, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Flow was not handled");
}
- default void handleTransfer(int frameSize, Transfer transfer, Buffer payload, int channel, E context) {
+ default void handleTransfer(int frameSize, Transfer transfer, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Transfer was not handled");
}
- default void handleDisposition(int frameSize, Disposition disposition, Buffer payload, int channel, E context) {
+ default void handleDisposition(int frameSize, Disposition disposition, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Disposition was not handled");
}
- default void handleDetach(int frameSize, Detach detach, Buffer payload, int channel, E context) {
+ default void handleDetach(int frameSize, Detach detach, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Detach was not handled");
}
- default void handleEnd(int frameSize, End end, Buffer payload, int channel, E context) {
+ default void handleEnd(int frameSize, End end, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP End was not handled");
}
- default void handleClose(int frameSize, Close close, Buffer payload, int channel, E context) {
+ default void handleClose(int frameSize, Close close, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Close was not handled");
}
- default void handleHeartBeat(int frameSize, HeartBeat thump, Buffer payload, int channel, E context) {
+ default void handleHeartBeat(int frameSize, HeartBeat thump, ByteBuffer payload, int channel, E context) {
throw new AssertionError("AMQP Heart Beat frame was not handled");
}
}
@@ -88,7 +87,7 @@ public abstract class PerformativeDescribedType extends ListDescribedType {
return getFieldValue(index);
}
- public abstract <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context);
+ public abstract <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context);
@Override
public String toString() {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Transfer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Transfer.java
index e616f729..9fd34c8e 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Transfer.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/transport/Transfer.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec.transport;
+import java.nio.ByteBuffer;
import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary;
@@ -25,8 +26,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty5.buffer.Buffer;
-
public class Transfer extends PerformativeDescribedType {
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:transfer:list");
@@ -172,7 +171,7 @@ public class Transfer extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuffer payload, int channel, E context) {
handler.handleTransfer(frameSize, this, payload, channel, context);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AMQPHeaderExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AMQPHeaderExpectation.java
index 61ee0f7a..8cf464c3 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AMQPHeaderExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AMQPHeaderExpectation.java
@@ -19,15 +19,14 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedExpectation;
import org.apache.qpid.protonj2.test.driver.actions.AMQPHeaderInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.ByteBufferInjectAction;
import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* Expectation entry for AMQP Headers
*/
@@ -54,12 +53,15 @@ public class AMQPHeaderExpectation implements ScriptedExpectation {
}
public ByteBufferInjectAction respondWithBytes(byte[] buffer) {
- ByteBufferInjectAction response = new ByteBufferInjectAction(driver, BufferAllocator.onHeapUnpooled().copyOf(buffer));
+ final ByteBuffer copy = ByteBuffer.allocate(buffer.length);
+ copy.put(buffer).flip().asReadOnlyBuffer();
+
+ final ByteBufferInjectAction response = new ByteBufferInjectAction(driver, copy.asReadOnlyBuffer());
driver.addScriptedElement(response);
return response;
}
- public ByteBufferInjectAction respondWithBytes(Buffer buffer) {
+ public ByteBufferInjectAction respondWithBytes(ByteBuffer buffer) {
ByteBufferInjectAction response = new ByteBufferInjectAction(driver, buffer);
driver.addScriptedElement(response);
return response;
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AbstractExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AbstractExpectation.java
index 498d4da5..38cd7e8b 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AbstractExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AbstractExpectation.java
@@ -18,6 +18,8 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.MatcherAssert.assertThat;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedExpectation;
import org.apache.qpid.protonj2.test.driver.codec.ListDescribedType;
@@ -43,8 +45,6 @@ import org.hamcrest.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-
/**
* Abstract base for expectations that need to handle matchers against fields in the
* value being expected.
@@ -121,7 +121,7 @@ public abstract class AbstractExpectation<T extends ListDescribedType> implement
assertThat("Performative does not match expectation", performative, getExpectationMatcher());
}
- protected final void verifyPayload(Buffer payload) {
+ protected final void verifyPayload(ByteBuffer payload) {
if (getPayloadMatcher() != null) {
assertThat("Payload does not match expectation", payload, getPayloadMatcher());
} else if (payload != null) {
@@ -146,59 +146,59 @@ public abstract class AbstractExpectation<T extends ListDescribedType> implement
protected abstract Class<T> getExpectedTypeClass();
- protected Matcher<Buffer> getPayloadMatcher() {
+ protected Matcher<ByteBuffer> getPayloadMatcher() {
return null;
}
//----- Base implementation of the handle methods to describe when we get wrong type.
@Override
- public void handleOpen(int frameSize, Open open, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleOpen(int frameSize, Open open, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, open, payload, channel, context);
}
@Override
- public void handleBegin(int frameSize, Begin begin, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleBegin(int frameSize, Begin begin, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, begin, payload, channel, context);
}
@Override
- public void handleAttach(int frameSize, Attach attach, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleAttach(int frameSize, Attach attach, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, attach, payload, channel, context);
}
@Override
- public void handleFlow(int frameSize, Flow flow, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleFlow(int frameSize, Flow flow, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, flow, payload, channel, context);
}
@Override
- public void handleTransfer(int frameSize, Transfer transfer, Buffer payload, int channel,AMQPTestDriver context) {
+ public void handleTransfer(int frameSize, Transfer transfer, ByteBuffer payload, int channel,AMQPTestDriver context) {
doVerification(frameSize, transfer, payload, channel, context);
}
@Override
- public void handleDisposition(int frameSize, Disposition disposition, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleDisposition(int frameSize, Disposition disposition, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, disposition, payload, channel, context);
}
@Override
- public void handleDetach(int frameSize, Detach detach, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleDetach(int frameSize, Detach detach, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, detach, payload, channel, context);
}
@Override
- public void handleEnd(int frameSize, End end, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleEnd(int frameSize, End end, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, end, payload, channel, context);
}
@Override
- public void handleClose(int frameSize, Close close, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleClose(int frameSize, Close close, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, close, payload, channel, context);
}
@Override
- public void handleHeartBeat(int frameSize, HeartBeat thump, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleHeartBeat(int frameSize, HeartBeat thump, ByteBuffer payload, int channel, AMQPTestDriver context) {
doVerification(frameSize, thump, payload, channel, context);
}
@@ -239,7 +239,7 @@ public abstract class AbstractExpectation<T extends ListDescribedType> implement
//----- Internal implementation
- private void doVerification(int frameSize, Object performative, Buffer payload, int channel, AMQPTestDriver driver) {
+ private void doVerification(int frameSize, Object performative, ByteBuffer payload, int channel, AMQPTestDriver driver) {
if (getExpectedTypeClass().equals(performative.getClass())) {
verifyFrameSize(frameSize);
verifyPayload(payload);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java
index d54ac73d..3f1be105 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java
@@ -21,6 +21,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
+import java.nio.ByteBuffer;
import java.util.Map;
import java.util.UUID;
@@ -54,8 +55,6 @@ import org.apache.qpid.protonj2.test.driver.matchers.transactions.CoordinatorMat
import org.apache.qpid.protonj2.test.driver.matchers.transport.AttachMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Attach performative
*/
@@ -106,7 +105,7 @@ public class AttachExpectation extends AbstractExpectation<Attach> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleAttach(int frameSize, Attach attach, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleAttach(int frameSize, Attach attach, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleAttach(frameSize, attach, payload, channel, context);
final UnsignedShort remoteChannel = UnsignedShort.valueOf(channel);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java
index 0aba203f..ef7e0c9b 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java
@@ -21,6 +21,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -35,8 +36,6 @@ import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper;
import org.apache.qpid.protonj2.test.driver.matchers.transport.BeginMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Begin performative
*/
@@ -91,7 +90,7 @@ public class BeginExpectation extends AbstractExpectation<Begin> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleBegin(int frameSize, Begin begin, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleBegin(int frameSize, Begin begin, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleBegin(frameSize, begin, payload, channel, context);
context.sessions().handleBegin(begin, UnsignedShort.valueOf(channel));
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/CloseExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/CloseExpectation.java
index 3721ea2b..9014ae59 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/CloseExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/CloseExpectation.java
@@ -18,6 +18,7 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -31,8 +32,6 @@ import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper;
import org.apache.qpid.protonj2.test.driver.matchers.transport.CloseMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Close performative
*/
@@ -55,7 +54,7 @@ public class CloseExpectation extends AbstractExpectation<Close> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleClose(int frameSize, Close close, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleClose(int frameSize, Close close, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleClose(frameSize, close, payload, channel, context);
if (response == null) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DetachExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DetachExpectation.java
index 720381a5..7eac73df 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DetachExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DetachExpectation.java
@@ -19,6 +19,7 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -36,8 +37,6 @@ import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper;
import org.apache.qpid.protonj2.test.driver.matchers.transport.DetachMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Detach performative
*/
@@ -69,7 +68,7 @@ public class DetachExpectation extends AbstractExpectation<Detach> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleDetach(int frameSize, Detach detach, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleDetach(int frameSize, Detach detach, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleDetach(frameSize, detach, payload, channel, context);
final UnsignedShort remoteChannel = UnsignedShort.valueOf(channel);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DispositionExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DispositionExpectation.java
index ba311a69..994de96f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DispositionExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/DispositionExpectation.java
@@ -19,6 +19,7 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
+import java.nio.ByteBuffer;
import java.util.Random;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -41,8 +42,6 @@ import org.apache.qpid.protonj2.test.driver.matchers.transactions.TransactionalS
import org.apache.qpid.protonj2.test.driver.matchers.transport.DispositionMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Disposition performative
*/
@@ -68,7 +67,7 @@ public class DispositionExpectation extends AbstractExpectation<Disposition> {
//----- Handle the incoming Disposition validation and update local side if able
@Override
- public void handleDisposition(int frameSize, Disposition disposition, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleDisposition(int frameSize, Disposition disposition, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleDisposition(frameSize, disposition, payload, channel, context);
final UnsignedShort remoteChannel = UnsignedShort.valueOf(channel);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/EndExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/EndExpectation.java
index 22dee07a..891c5dcc 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/EndExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/EndExpectation.java
@@ -18,6 +18,7 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -33,8 +34,6 @@ import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper;
import org.apache.qpid.protonj2.test.driver.matchers.transport.EndMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP End performative
*/
@@ -63,7 +62,7 @@ public class EndExpectation extends AbstractExpectation<End> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleEnd(int frameSize, End end, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleEnd(int frameSize, End end, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleEnd(frameSize, end, payload, channel, context);
// Ensure that local session tracking knows that remote ended a Session.
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/FlowExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/FlowExpectation.java
index d7b2708a..ecb7266e 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/FlowExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/FlowExpectation.java
@@ -21,6 +21,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -36,8 +37,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.matchers.transport.FlowMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Flow performative
*/
@@ -71,7 +70,7 @@ public class FlowExpectation extends AbstractExpectation<Flow> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleFlow(int frameSize, Flow flow, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleFlow(int frameSize, Flow flow, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleFlow(frameSize, flow, payload, channel, context);
final UnsignedShort remoteChannel = UnsignedShort.valueOf(channel);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java
index 90624ad5..afdda58b 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java
@@ -19,6 +19,7 @@ package org.apache.qpid.protonj2.test.driver.expectations;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
@@ -34,8 +35,6 @@ import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper;
import org.apache.qpid.protonj2.test.driver.matchers.transport.OpenMatcher;
import org.hamcrest.Matcher;
-import io.netty5.buffer.Buffer;
-
/**
* Scripted expectation for the AMQP Open performative
*/
@@ -96,7 +95,7 @@ public class OpenExpectation extends AbstractExpectation<Open> {
//----- Handle the performative and configure response is told to respond
@Override
- public void handleOpen(int frameSize, Open open, Buffer payload, int channel, AMQPTestDriver context) {
+ public void handleOpen(int frameSize, Open open, ByteBuffer payload, int channel, AMQPTestDriver context) {
super.handleOpen(frameSize, open, payload, channel, context);
if (response != null) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/TransferExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/TransferExpectation.java
index 617e7bba..6e8675b0 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/TransferExpectation.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/TransferExpectation.java
@@ -20,6 +20,8 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.LinkTracker;
import org.apache.qpid.protonj2.test.driver.SessionTracker;
@@ -43,9 +45,6 @@ import org.apache.qpid.protonj2.test.driver.matchers.transport.TransferMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* Scripted expectation for the AMQP Transfer performative
*/
@@ -54,7 +53,7 @@ public class TransferExpectation extends AbstractExpectation<Transfer> {
private final TransferMatcher matcher = new TransferMatcher();
private final DeliveryStateBuilder stateBuilder = new DeliveryStateBuilder();
- private Matcher<Buffer> payloadMatcher = Matchers.any(Buffer.class);
+ private Matcher<ByteBuffer> payloadMatcher = Matchers.any(ByteBuffer.class);
protected DispositionInjectAction response;
@@ -130,7 +129,7 @@ public class TransferExpectation extends AbstractExpectation<Transfer> {
}
@Override
- public void handleTransfer(int frameSize, Transfer transfer, Buffer payload, int channel, AMQPTestDriver driver) {
+ public void handleTransfer(int frameSize, Transfer transfer, ByteBuffer payload, int channel, AMQPTestDriver driver) {
super.handleTransfer(frameSize, transfer, payload, channel, driver);
final UnsignedShort remoteChannel = UnsignedShort.valueOf(channel);
@@ -254,18 +253,21 @@ public class TransferExpectation extends AbstractExpectation<Transfer> {
}
public TransferExpectation withNonNullPayload() {
- this.payloadMatcher = notNullValue(Buffer.class);
+ this.payloadMatcher = notNullValue(ByteBuffer.class);
return this;
}
public TransferExpectation withNullPayload() {
- this.payloadMatcher = nullValue(Buffer.class);
+ this.payloadMatcher = nullValue(ByteBuffer.class);
return this;
}
public TransferExpectation withPayload(byte[] buffer) {
+ final ByteBuffer copy = ByteBuffer.allocate(buffer.length);
+ copy.put(buffer).flip();
+
// TODO - Create Matcher which describes the mismatch in detail
- this.payloadMatcher = Matchers.equalTo(BufferAllocator.onHeapUnpooled().copyOf(buffer));
+ this.payloadMatcher = Matchers.equalTo(copy.asReadOnlyBuffer());
return this;
}
@@ -326,7 +328,7 @@ public class TransferExpectation extends AbstractExpectation<Transfer> {
return this;
}
- public TransferExpectation withPayload(Matcher<Buffer> payloadMatcher) {
+ public TransferExpectation withPayload(Matcher<ByteBuffer> payloadMatcher) {
this.payloadMatcher = payloadMatcher;
return this;
}
@@ -337,7 +339,7 @@ public class TransferExpectation extends AbstractExpectation<Transfer> {
}
@Override
- protected Matcher<Buffer> getPayloadMatcher() {
+ protected Matcher<ByteBuffer> getPayloadMatcher() {
return payloadMatcher;
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/messaging/AbstractMessageSectionMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/messaging/AbstractMessageSectionMatcher.java
index a49d1781..5c1e822f 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/messaging/AbstractMessageSectionMatcher.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/messaging/AbstractMessageSectionMatcher.java
@@ -20,6 +20,7 @@ package org.apache.qpid.protonj2.test.driver.matchers.messaging;
import static org.hamcrest.MatcherAssert.assertThat;
+import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.codec.Codec;
@@ -30,8 +31,6 @@ import org.hamcrest.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.buffer.Buffer;
-
public abstract class AbstractMessageSectionMatcher {
private final Logger LOG = LoggerFactory.getLogger(getClass());
@@ -68,8 +67,8 @@ public abstract class AbstractMessageSectionMatcher {
* @throws RuntimeException
* if the provided Binary does not match expectation in some way
*/
- public int verify(Buffer receivedBinary) throws RuntimeException {
- final int length = receivedBinary.readableBytes();
+ public int verify(ByteBuffer receivedBinary) throws RuntimeException {
+ final int length = receivedBinary.remaining();
final Codec data = Codec.Factory.create();
final long decoded = data.decode(receivedBinary);
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/TransferPayloadCompositeMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/TransferPayloadCompositeMatcher.java
index 0abff7a8..95dcd64d 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/TransferPayloadCompositeMatcher.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/TransferPayloadCompositeMatcher.java
@@ -22,6 +22,7 @@ package org.apache.qpid.protonj2.test.driver.matchers.transport;
import static org.hamcrest.MatcherAssert.assertThat;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -36,13 +37,11 @@ import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.hamcrest.TypeSafeMatcher;
-import io.netty5.buffer.Buffer;
-
/**
* Used to verify the Transfer frame payload, i.e the sections of the AMQP
* message such as the header, properties, and body sections.
*/
-public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
+public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<ByteBuffer> {
private HeaderMatcher headersMatcher;
private String headerMatcherFailureDescription;
@@ -54,7 +53,7 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
private String propertiesMatcherFailureDescription;
private ApplicationPropertiesMatcher applicationPropertiesMatcher;
private String applicationPropertiesMatcherFailureDescription;
- private List<Matcher<Buffer>> msgContentMatchers = new ArrayList<>();
+ private List<Matcher<ByteBuffer>> msgContentMatchers = new ArrayList<>();
private String msgContentMatcherFailureDescription;
private FooterMatcher footersMatcher;
private String footerMatcherFailureDescription;
@@ -65,8 +64,10 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
}
@Override
- protected boolean matchesSafely(final Buffer receivedBinary) {
- int origLength = receivedBinary.readableBytes();
+ protected boolean matchesSafely(final ByteBuffer receivedBinary) {
+ final ByteBuffer receivedSlice = receivedBinary.slice().asReadOnlyBuffer();
+ final int origLength = receivedBinary.remaining();
+
int bytesConsumed = 0;
// Length Matcher
@@ -82,110 +83,106 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
// MessageHeader Section
if (headersMatcher != null) {
- try (Buffer msgHeaderEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += headersMatcher.verify(msgHeaderEtcSubBinary);
- } catch (Throwable t) {
- headerMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to MessageHeaderMatcher: " + msgHeaderEtcSubBinary;
- headerMatcherFailureDescription += "\nMessageHeaderMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += headersMatcher.verify(receivedSlice.slice());
+ receivedSlice.position(bytesConsumed);
+ } catch (Throwable t) {
+ headerMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to MessageHeaderMatcher: " + receivedSlice;
+ headerMatcherFailureDescription += "\nMessageHeaderMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
// DeliveryAnnotations Section
if (deliveryAnnotationsMatcher != null) {
- try (Buffer daAnnotationsEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += deliveryAnnotationsMatcher.verify(daAnnotationsEtcSubBinary);
- } catch (Throwable t) {
- deliveryAnnotationsMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to DeliveryAnnotationsMatcher: "
- + daAnnotationsEtcSubBinary;
- deliveryAnnotationsMatcherFailureDescription += "\nDeliveryAnnotationsMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += deliveryAnnotationsMatcher.verify(receivedSlice.slice());
+ receivedSlice.position(bytesConsumed);
+ } catch (Throwable t) {
+ deliveryAnnotationsMatcherFailureDescription = "\nActual encoded form of remaining bytes passed " +
+ "to DeliveryAnnotationsMatcher: " + receivedSlice;
+ deliveryAnnotationsMatcherFailureDescription += "\nDeliveryAnnotationsMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
// MessageAnnotations Section
if (messageAnnotationsMatcher != null) {
- try (Buffer msgAnnotationsEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += messageAnnotationsMatcher.verify(msgAnnotationsEtcSubBinary);
- } catch (Throwable t) {
- messageAnnotationsMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to MessageAnnotationsMatcher: "
- + msgAnnotationsEtcSubBinary;
- messageAnnotationsMatcherFailureDescription += "\nMessageAnnotationsMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += messageAnnotationsMatcher.verify(receivedSlice.slice());
+ receivedSlice.position(bytesConsumed);
+ } catch (Throwable t) {
+ messageAnnotationsMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to " +
+ "MessageAnnotationsMatcher: " + receivedSlice;
+ messageAnnotationsMatcherFailureDescription += "\nMessageAnnotationsMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
// Properties Section
if (propertiesMatcher != null) {
- try (Buffer propsEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += propertiesMatcher.verify(propsEtcSubBinary);
- } catch (Throwable t) {
- propertiesMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to PropertiesMatcher: " + propsEtcSubBinary;
- propertiesMatcherFailureDescription += "\nPropertiesMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += propertiesMatcher.verify(receivedSlice.slice());
+ receivedSlice.position(bytesConsumed);
+ } catch (Throwable t) {
+ propertiesMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to " +
+ "PropertiesMatcher: " + receivedSlice;
+ propertiesMatcherFailureDescription += "\nPropertiesMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
// Application Properties Section
if (applicationPropertiesMatcher != null) {
- try (Buffer appPropsEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += applicationPropertiesMatcher.verify(appPropsEtcSubBinary);
- } catch (Throwable t) {
- applicationPropertiesMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to ApplicationPropertiesMatcher: " + appPropsEtcSubBinary;
- applicationPropertiesMatcherFailureDescription += "\nApplicationPropertiesMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += applicationPropertiesMatcher.verify(receivedSlice.slice());
+ receivedSlice.position(bytesConsumed);
+ } catch (Throwable t) {
+ applicationPropertiesMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to " +
+ "ApplicationPropertiesMatcher: " + receivedSlice;
+ applicationPropertiesMatcherFailureDescription += "\nApplicationPropertiesMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
// Message Content Body Section, already a Matcher<Binary>
if (!msgContentMatchers.isEmpty()) {
- for (Matcher<Buffer> msgContentMatcher : msgContentMatchers) {
- try (Buffer msgContentBodyEtcSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- final int originalReadableBytes = msgContentBodyEtcSubBinary.readableBytes();
- final boolean contentMatches = msgContentMatcher.matches(msgContentBodyEtcSubBinary);
- if (!contentMatches) {
- Description desc = new StringDescription();
- msgContentMatcher.describeTo(desc);
- msgContentMatcher.describeMismatch(msgContentBodyEtcSubBinary, desc);
-
- msgContentMatcherFailureDescription = "\nMessageContentMatcher mismatch Description:";
- msgContentMatcherFailureDescription += desc.toString();
-
- return false;
- }
-
- bytesConsumed += originalReadableBytes - msgContentBodyEtcSubBinary.readableBytes();
+ final ByteBuffer slicedMsgContext = receivedSlice.slice();
+
+ for (Matcher<ByteBuffer> msgContentMatcher : msgContentMatchers) {
+ final int originalReadableBytes = slicedMsgContext.remaining();
+ final boolean contentMatches = msgContentMatcher.matches(slicedMsgContext);
+ if (!contentMatches) {
+ Description desc = new StringDescription();
+ msgContentMatcher.describeTo(desc);
+ msgContentMatcher.describeMismatch(receivedSlice, desc);
+
+ msgContentMatcherFailureDescription = "\nMessageContentMatcher mismatch Description:";
+ msgContentMatcherFailureDescription += desc.toString();
+
+ return false;
}
+
+ bytesConsumed += originalReadableBytes - slicedMsgContext.remaining();
+ receivedSlice.position(bytesConsumed);
}
}
// MessageAnnotations Section
if (footersMatcher != null) {
- try (Buffer footersSubBinary = receivedBinary.copy(bytesConsumed, origLength - bytesConsumed, true)) {
- try {
- bytesConsumed += footersMatcher.verify(footersSubBinary);
- } catch (Throwable t) {
- footerMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to FooterMatcher: "
- + footersSubBinary;
- footerMatcherFailureDescription += "\nFooterMatcher generated throwable: " + t;
+ try {
+ bytesConsumed += footersMatcher.verify(receivedSlice.slice());
+ } catch (Throwable t) {
+ footerMatcherFailureDescription = "\nActual encoded form of remaining bytes passed to " +
+ "FooterMatcher: " + receivedSlice;
+ footerMatcherFailureDescription += "\nFooterMatcher generated throwable: " + t;
- return false;
- }
+ return false;
}
}
@@ -198,7 +195,7 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
}
@Override
- protected void describeMismatchSafely(Buffer item, Description mismatchDescription) {
+ protected void describeMismatchSafely(ByteBuffer item, Description mismatchDescription) {
mismatchDescription.appendText("\nActual encoded form of the full Transfer frame payload: ").appendValue(item);
// Payload Length
@@ -277,7 +274,7 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
this.applicationPropertiesMatcher = appPropsMatcher;
}
- public void setMessageContentMatcher(Matcher<Buffer> msgContentMatcher) {
+ public void setMessageContentMatcher(Matcher<ByteBuffer> msgContentMatcher) {
if (msgContentMatchers.isEmpty()) {
msgContentMatchers.add(msgContentMatcher);
} else {
@@ -285,7 +282,7 @@ public class TransferPayloadCompositeMatcher extends TypeSafeMatcher<Buffer> {
}
}
- public void addMessageContentMatcher(Matcher<Buffer> msgContentMatcher) {
+ public void addMessageContentMatcher(Matcher<ByteBuffer> msgContentMatcher) {
msgContentMatchers.add(msgContentMatcher);
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedAmqpTypeMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedAmqpTypeMatcher.java
index c11a7049..59743d27 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedAmqpTypeMatcher.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedAmqpTypeMatcher.java
@@ -18,6 +18,8 @@
*/
package org.apache.qpid.protonj2.test.driver.matchers.types;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.protonj2.test.driver.codec.Codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
@@ -26,9 +28,7 @@ import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
-import io.netty5.buffer.Buffer;
-
-public abstract class EncodedAmqpTypeMatcher extends TypeSafeMatcher<Buffer> {
+public abstract class EncodedAmqpTypeMatcher extends TypeSafeMatcher<ByteBuffer> {
private final Symbol descriptorSymbol;
private final UnsignedLong descriptorCode;
@@ -53,8 +53,8 @@ public abstract class EncodedAmqpTypeMatcher extends TypeSafeMatcher<Buffer> {
}
@Override
- protected boolean matchesSafely(Buffer receivedBinary) {
- int length = receivedBinary.readableBytes();
+ protected boolean matchesSafely(ByteBuffer receivedBinary) {
+ int length = receivedBinary.remaining();
Codec data = Codec.Factory.create();
long decoded = data.decode(receivedBinary);
decodedDescribedType = data.getDescribedType();
@@ -86,7 +86,7 @@ public abstract class EncodedAmqpTypeMatcher extends TypeSafeMatcher<Buffer> {
}
@Override
- protected void describeMismatchSafely(Buffer item, Description mismatchDescription) {
+ protected void describeMismatchSafely(ByteBuffer item, Description mismatchDescription) {
mismatchDescription.appendText("\nActual encoded form: ").appendValue(item);
if (decodedDescribedType != null) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedCompositingDataSectionMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedCompositingDataSectionMatcher.java
index 4526f630..5ef9dba8 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedCompositingDataSectionMatcher.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedCompositingDataSectionMatcher.java
@@ -19,6 +19,7 @@
package org.apache.qpid.protonj2.test.driver.matchers.types;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.Objects;
import org.apache.qpid.protonj2.test.driver.codec.EncodingCodes;
@@ -29,21 +30,18 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* Data Section matcher that can be used with multiple expectTransfer calls to match a larger
* given payload block to the contents of one or more incoming Data sections split across multiple
* transfer frames and or multiple Data Sections within those transfer frames.
*/
-public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer> {
+public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<ByteBuffer> {
private static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:data:binary");
private static final UnsignedLong DESCRIPTOR_CODE = UnsignedLong.valueOf(0x0000000000000075L);
private final int expectedValueSize;
- private final Buffer expectedValue;
+ private final ByteBuffer expectedValue;
private boolean expectTrailingBytes;
private String decodingErrorDescription;
@@ -59,7 +57,7 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
* the value that is expected to be IN the received {@link Data}
*/
public EncodedCompositingDataSectionMatcher(byte[] expectedValue) {
- this(BufferAllocator.onHeapUnpooled().copyOf(expectedValue).makeReadOnly());
+ this(ByteBuffer.wrap(Arrays.copyOf(expectedValue, expectedValue.length)).asReadOnlyBuffer());
}
/**
@@ -67,18 +65,18 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
* the value that is expected to be IN the received {@link Data}
*/
public EncodedCompositingDataSectionMatcher(Binary expectedValue) {
- this(BufferAllocator.onHeapUnpooled().copyOf(expectedValue.asByteBuffer()).makeReadOnly());
+ this(ByteBuffer.wrap(expectedValue.arrayCopy()).asReadOnlyBuffer());
}
/**
* @param expectedValue
* the value that is expected to be IN the received {@link Data}
*/
- public EncodedCompositingDataSectionMatcher(Buffer expectedValue) {
+ public EncodedCompositingDataSectionMatcher(ByteBuffer expectedValue) {
Objects.requireNonNull(expectedValue, "The expected value cannot be null for this matcher");
- this.expectedValue = expectedValue;
- this.expectedRemainingBytes = this.expectedValue.readableBytes();
+ this.expectedValue = expectedValue.asReadOnlyBuffer();
+ this.expectedRemainingBytes = this.expectedValue.remaining();
this.expectedValueSize = this.expectedRemainingBytes;
}
@@ -96,7 +94,7 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
}
@Override
- protected boolean matchesSafely(Buffer receivedBinary) {
+ protected boolean matchesSafely(ByteBuffer receivedBinary) {
if (expectDataSectionPreamble) {
Object descriptor = readDescribedTypeEncoding(receivedBinary);
@@ -105,12 +103,12 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
}
// Should be a Binary AMQP type with a length value and possibly some bytes
- byte encodingCode = receivedBinary.readByte();
+ byte encodingCode = receivedBinary.get();
if (encodingCode == EncodingCodes.VBIN8) {
- expectedCurrentDataSectionBytes = receivedBinary.readByte() & 0xFF;
+ expectedCurrentDataSectionBytes = receivedBinary.get() & 0xFF;
} else if (encodingCode == EncodingCodes.VBIN32) {
- expectedCurrentDataSectionBytes = receivedBinary.readInt();
+ expectedCurrentDataSectionBytes = receivedBinary.getInt();
} else {
decodingErrorDescription = "Expected to read a Binary Type but read encoding code: " + encodingCode;
return false;
@@ -126,28 +124,28 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
}
if (expectedRemainingBytes != 0) {
- final int currentChunkSize = Math.min(expectedCurrentDataSectionBytes, receivedBinary.readableBytes());
- try (Buffer expectedValueChunk = expectedValue.copy(expectedValue.readerOffset(), currentChunkSize, true);
- Buffer currentChunk = receivedBinary.copy(receivedBinary.readerOffset(), currentChunkSize, true)) {
+ final int currentChunkSize = Math.min(expectedCurrentDataSectionBytes, receivedBinary.remaining());
- receivedBinary.skipReadableBytes(currentChunkSize);
- expectedValue.skipReadableBytes(currentChunkSize);
+ final ByteBuffer expectedValueChunk = expectedValue.slice().limit(currentChunkSize);
+ final ByteBuffer currentChunk = receivedBinary.slice().limit(currentChunkSize);
- if (!expectedValueChunk.equals(currentChunk)) {
- return false;
- }
+ receivedBinary.position(receivedBinary.position() + currentChunkSize);
+ expectedValue.position(expectedValue.position() + currentChunkSize);
- expectedRemainingBytes -= currentChunkSize;
- expectedCurrentDataSectionBytes -= currentChunkSize;
+ if (!expectedValueChunk.equals(currentChunk)) {
+ return false;
}
+ expectedRemainingBytes -= currentChunkSize;
+ expectedCurrentDataSectionBytes -= currentChunkSize;
+
if (expectedRemainingBytes != 0 && expectedCurrentDataSectionBytes == 0) {
expectDataSectionPreamble = true;
expectedCurrentDataSectionBytes = -1;
}
}
- if (expectedRemainingBytes == 0 && receivedBinary.readableBytes() > 0 && !isTrailingBytesExpected()) {
+ if (expectedRemainingBytes == 0 && receivedBinary.remaining() > 0 && !isTrailingBytesExpected()) {
unexpectedTrailingBytes = true;
return false;
} else {
@@ -157,18 +155,18 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
private static final int DESCRIBED_TYPE_INDICATOR = 0;
- private Object readDescribedTypeEncoding(Buffer data) {
- byte encodingCode = data.readByte();
+ private Object readDescribedTypeEncoding(ByteBuffer data) {
+ byte encodingCode = data.get();
if (encodingCode == DESCRIBED_TYPE_INDICATOR) {
- encodingCode = data.readByte();
+ encodingCode = data.get();
switch (encodingCode) {
case EncodingCodes.ULONG0:
return UnsignedLong.ZERO;
case EncodingCodes.SMALLULONG:
- return UnsignedLong.valueOf(data.readByte() & 0xff);
+ return UnsignedLong.valueOf(data.get() & 0xff);
case EncodingCodes.ULONG:
- return UnsignedLong.valueOf(data.readLong());
+ return UnsignedLong.valueOf(data.getLong());
case EncodingCodes.SYM8:
return readSymbol8(data);
case EncodingCodes.SYM32:
@@ -183,34 +181,30 @@ public class EncodedCompositingDataSectionMatcher extends TypeSafeMatcher<Buffer
return null;
}
- private Symbol readSymbol32(Buffer buffer) {
- int length = buffer.readInt();
-
- if (length == 0) {
- return Symbol.valueOf("");
- } else {
- final ByteBuffer symbolBuffer = ByteBuffer.allocate(length);
- buffer.readBytes(symbolBuffer);
-
- return Symbol.getSymbol(symbolBuffer, false);
- }
+ private static Symbol readSymbol32(ByteBuffer buffer) {
+ return readSymbol(buffer.getInt(), buffer);
}
- private Symbol readSymbol8(Buffer buffer) {
- int length = buffer.readByte() & 0xFF;
+ private static Symbol readSymbol8(ByteBuffer buffer) {
+ return readSymbol(buffer.get() & 0xFF, buffer);
+ }
+ private static Symbol readSymbol(int length, ByteBuffer buffer) {
if (length == 0) {
return Symbol.valueOf("");
} else {
- final ByteBuffer symbolBuffer = ByteBuffer.allocate(length);
- buffer.readBytes(symbolBuffer);
+ final byte[] symbolBytes = new byte[length];
+
+ buffer.get(symbolBytes);
+
+ final ByteBuffer symbolBuffer = ByteBuffer.wrap(symbolBytes).asReadOnlyBuffer();
return Symbol.getSymbol(symbolBuffer, false);
}
}
@Override
- protected void describeMismatchSafely(Buffer item, Description mismatchDescription) {
+ protected void describeMismatchSafely(ByteBuffer item, Description mismatchDescription) {
mismatchDescription.appendText("\nActual encoded form: ").appendValue(item);
if (decodingErrorDescription != null) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedPartialDataSectionMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedPartialDataSectionMatcher.java
index 5e396473..80855da6 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedPartialDataSectionMatcher.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/types/EncodedPartialDataSectionMatcher.java
@@ -19,6 +19,7 @@
package org.apache.qpid.protonj2.test.driver.matchers.types;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import org.apache.qpid.protonj2.test.driver.codec.EncodingCodes;
import org.apache.qpid.protonj2.test.driver.codec.messaging.Data;
@@ -28,16 +29,13 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
-public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
+public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<ByteBuffer> {
private static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:data:binary");
private static final UnsignedLong DESCRIPTOR_CODE = UnsignedLong.valueOf(0x0000000000000075L);
private final boolean expectDataSectionPreamble;
- private final Buffer expectedValue;
+ private final ByteBuffer expectedValue;
private final int expectedEncodedSize;
private boolean expectTrailingBytes;
private String decodingErrorDescription;
@@ -51,7 +49,7 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* the value that is expected to be IN the received {@link Data}
*/
public EncodedPartialDataSectionMatcher(int expectedEncodedSize, byte[] expectedValue) {
- this(expectedEncodedSize, BufferAllocator.onHeapUnpooled().copyOf(expectedValue), true);
+ this(expectedEncodedSize, ByteBuffer.wrap(Arrays.copyOf(expectedValue, expectedValue.length)).asReadOnlyBuffer(), true);
}
/**
@@ -62,7 +60,7 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* the value that is expected to be IN the received {@link Data}
*/
public EncodedPartialDataSectionMatcher(int expectedEncodedSize, Binary expectedValue) {
- this(expectedEncodedSize, BufferAllocator.onHeapUnpooled().copyOf(expectedValue.asByteBuffer()), true);
+ this(expectedEncodedSize, ByteBuffer.wrap(expectedValue.arrayCopy()).asReadOnlyBuffer(), true);
}
/**
@@ -72,7 +70,7 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* @param expectedValue
* the value that is expected to be IN the received {@link Data}
*/
- public EncodedPartialDataSectionMatcher(int expectedEncodedSize, Buffer expectedValue) {
+ public EncodedPartialDataSectionMatcher(int expectedEncodedSize, ByteBuffer expectedValue) {
this(expectedEncodedSize, expectedValue, true);
}
@@ -81,7 +79,7 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* the value that is expected to be IN the received {@link Data}
*/
public EncodedPartialDataSectionMatcher(byte[] expectedValue) {
- this(-1, BufferAllocator.onHeapUnpooled().copyOf(expectedValue), false);
+ this(-1, ByteBuffer.wrap(Arrays.copyOf(expectedValue, expectedValue.length)).asReadOnlyBuffer(), false);
}
/**
@@ -89,14 +87,14 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* the value that is expected to be IN the received {@link Data}
*/
public EncodedPartialDataSectionMatcher(Binary expectedValue) {
- this(-1, BufferAllocator.onHeapUnpooled().copyOf(expectedValue.asByteBuffer()), false);
+ this(-1, ByteBuffer.wrap(expectedValue.arrayCopy()).asReadOnlyBuffer(), false);
}
/**
* @param expectedValue
* the value that is expected to be IN the received {@link Data}
*/
- public EncodedPartialDataSectionMatcher(Buffer expectedValue) {
+ public EncodedPartialDataSectionMatcher(ByteBuffer expectedValue) {
this(-1, expectedValue, false);
}
@@ -110,8 +108,8 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
* should the matcher check for the Data and Binary section encoding
* meta-data or only match the payload to the given expected value.
*/
- protected EncodedPartialDataSectionMatcher(int expectedEncodedSize, Buffer expectedValue, boolean expectDataSectionPreamble) {
- this.expectedValue = expectedValue;
+ protected EncodedPartialDataSectionMatcher(int expectedEncodedSize, ByteBuffer expectedValue, boolean expectDataSectionPreamble) {
+ this.expectedValue = expectedValue.asReadOnlyBuffer();
this.expectedEncodedSize = expectedEncodedSize;
this.expectDataSectionPreamble = expectDataSectionPreamble;
}
@@ -130,7 +128,7 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
}
@Override
- protected boolean matchesSafely(Buffer receivedBinary) {
+ protected boolean matchesSafely(ByteBuffer receivedBinary) {
if (expectDataSectionPreamble) {
Object descriptor = readDescribedTypeEncoding(receivedBinary);
@@ -139,13 +137,13 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
}
// Should be a Binary AMQP type with a length value and possibly some bytes
- byte encodingCode = receivedBinary.readByte();
+ byte encodingCode = receivedBinary.get();
int binaryEncodedSize = -1;
if (encodingCode == EncodingCodes.VBIN8) {
- binaryEncodedSize = receivedBinary.readByte() & 0xFF;
+ binaryEncodedSize = receivedBinary.get() & 0xFF;
} else if (encodingCode == EncodingCodes.VBIN32) {
- binaryEncodedSize = receivedBinary.readInt();
+ binaryEncodedSize = receivedBinary.getInt();
} else {
decodingErrorDescription = "Expected to read a Binary Type but read encoding code: " + encodingCode;
return false;
@@ -159,14 +157,14 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
}
if (expectedValue != null) {
- Buffer payload = receivedBinary.copy(true);
- receivedBinary.skipReadableBytes(payload.readableBytes());
+ final ByteBuffer payload = receivedBinary.slice().asReadOnlyBuffer();
+ receivedBinary.position(receivedBinary.position() + payload.remaining());
if (!expectedValue.equals(payload)) {
return false;
}
}
- if (receivedBinary.readableBytes() > 0 && !isTrailingBytesExpected()) {
+ if (receivedBinary.remaining() > 0 && !isTrailingBytesExpected()) {
unexpectedTrailingBytes = true;
return false;
} else {
@@ -176,18 +174,18 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
private static final int DESCRIBED_TYPE_INDICATOR = 0;
- private Object readDescribedTypeEncoding(Buffer data) {
- byte encodingCode = data.readByte();
+ private Object readDescribedTypeEncoding(ByteBuffer data) {
+ byte encodingCode = data.get();
if (encodingCode == DESCRIBED_TYPE_INDICATOR) {
- encodingCode = data.readByte();
+ encodingCode = data.get();
switch (encodingCode) {
case EncodingCodes.ULONG0:
return UnsignedLong.ZERO;
case EncodingCodes.SMALLULONG:
- return UnsignedLong.valueOf(data.readByte() & 0xff);
+ return UnsignedLong.valueOf(data.get() & 0xff);
case EncodingCodes.ULONG:
- return UnsignedLong.valueOf(data.readLong());
+ return UnsignedLong.valueOf(data.getLong());
case EncodingCodes.SYM8:
return readSymbol8(data);
case EncodingCodes.SYM32:
@@ -202,34 +200,30 @@ public class EncodedPartialDataSectionMatcher extends TypeSafeMatcher<Buffer> {
return null;
}
- private Symbol readSymbol32(Buffer buffer) {
- int length = buffer.readInt();
-
- if (length == 0) {
- return Symbol.valueOf("");
- } else {
- final ByteBuffer symbolBuffer = ByteBuffer.allocate(length);
- buffer.readBytes(symbolBuffer);
-
- return Symbol.getSymbol(symbolBuffer, false);
- }
+ private static Symbol readSymbol32(ByteBuffer buffer) {
+ return readSymbol(buffer.getInt(), buffer);
}
- private Symbol readSymbol8(Buffer buffer) {
- int length = buffer.readByte() & 0xFF;
+ private static Symbol readSymbol8(ByteBuffer buffer) {
+ return readSymbol(buffer.get() & 0xFF, buffer);
+ }
+ private static Symbol readSymbol(int length, ByteBuffer buffer) {
if (length == 0) {
return Symbol.valueOf("");
} else {
- final ByteBuffer symbolBuffer = ByteBuffer.allocate(length);
- buffer.readBytes(symbolBuffer);
+ final byte[] symbolBytes = new byte[length];
+
+ buffer.get(symbolBytes);
+
+ final ByteBuffer symbolBuffer = ByteBuffer.wrap(symbolBytes).asReadOnlyBuffer();
return Symbol.getSymbol(symbolBuffer, false);
}
}
@Override
- protected void describeMismatchSafely(Buffer item, Description mismatchDescription) {
+ protected void describeMismatchSafely(ByteBuffer item, Description mismatchDescription) {
mismatchDescription.appendText("\nActual encoded form: ").appendValue(item);
if (decodingErrorDescription != null) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
index ae2fbdcf..b90af803 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
@@ -14,438 +14,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.qpid.protonj2.test.driver.netty;
import java.io.IOException;
import java.net.URI;
-import java.net.URISyntaxException;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.bootstrap.Bootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioSocketChannel;
-import io.netty5.handler.codec.http.DefaultHttpContent;
-import io.netty5.handler.codec.http.FullHttpResponse;
-import io.netty5.handler.codec.http.HttpClientCodec;
-import io.netty5.handler.codec.http.HttpObjectAggregator;
-import io.netty5.handler.codec.http.headers.HttpHeaders;
-import io.netty5.handler.codec.http.websocketx.BinaryWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.ContinuationWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PingWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PongWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.TextWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshaker;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
-import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketVersion;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
/**
- * Self contained Netty client implementation that provides a base for more
- * complex client implementations to use as the IO layer.
+ * Base API for Netty Client implementations
*/
-public abstract class NettyClient implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NettyClient.class);
-
- private static final String AMQP_SUB_PROTOCOL = "amqp";
-
- private Bootstrap bootstrap;
- private EventLoopGroup group;
- private Channel channel;
- private String host;
- private int port;
- protected volatile IOException failureCause;
- private final ProtonTestClientOptions options;
- private volatile SslHandler sslHandler;
- protected final AtomicBoolean connected = new AtomicBoolean();
- protected final AtomicBoolean closed = new AtomicBoolean();
- protected final CountDownLatch connectedLatch = new CountDownLatch(1);
-
- public NettyClient(ProtonTestClientOptions options) {
- this.options = options;
- }
-
- @Override
- public void close() throws Exception {
- if (closed.compareAndSet(false, true)) {
- connected.set(false);
- connectedLatch.countDown();
- if (channel != null) {
- try {
- if (!channel.close().asStage().await(10, TimeUnit.SECONDS)) {
- LOG.info("Channel close timed out waiting for result");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Close of channel interrupted while awaiting result");
- }
- }
- }
- }
-
- public void connect(String host, int port) throws IOException {
- if (closed.get()) {
- throw new IllegalStateException("Netty client has already been closed");
- }
-
- if (host == null || host.isEmpty()) {
- throw new IllegalArgumentException("Transport host value cannot be null");
- }
-
- this.host = host;
-
- if (port > 0) {
- this.port = port;
- } else {
- if (options.isSecure()) {
- this.port = ProtonTestClientOptions.DEFAULT_SSL_PORT;
- } else {
- this.port = ProtonTestClientOptions.DEFAULT_TCP_PORT;
- }
- }
-
- group = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
- bootstrap = new Bootstrap().channel(NioSocketChannel.class).group(group);
- bootstrap.handler(new ChannelInitializer<Channel>() {
- @Override
- public void initChannel(Channel transportChannel) throws Exception {
- channel = transportChannel;
- configureChannel(transportChannel);
- }
- });
-
- configureNetty(bootstrap, options);
-
- bootstrap.connect(host, port).addListener(channel, ChannelFutureListeners.FIRE_EXCEPTION_ON_FAILURE);
- try {
- connectedLatch.await();
- } catch (InterruptedException e) {
- Thread.interrupted();
- }
-
- if (!connected.get()) {
- if (failureCause != null) {
- throw failureCause;
- } else {
- throw new IOException("Netty client was closed before a connection was established.");
- }
- }
- }
-
- public EventLoop eventLoop() {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return channel.executor();
- }
-
- public void write(ByteBuffer buffer) {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- channel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(buffer).makeReadOnly());
- }
-
- public boolean isConnected() {
- return connected.get();
- }
-
- public boolean isSecure() {
- return options.isSecure();
- }
-
- public URI getRemoteURI() {
- if (host != null) {
- try {
- if (options.isUseWebSockets()) {
- return new URI(options.isSecure() ? "wss" : "ws", null, host, port, options.getWebSocketPath(), null, null);
- } else {
- return new URI(options.isSecure() ? "ssl" : "tcp", null, host, port, null, null, null);
- }
- } catch (URISyntaxException e) {
- }
- }
-
- return null;
- }
-
- //----- Default implementation of Netty handler
-
- protected class NettyClientInboundHandler implements ChannelHandler {
-
- private final WebSocketClientHandshaker handshaker;
- private Future<Void> handshakeTimeoutFuture;
-
- public NettyClientInboundHandler() {
- if (options.isUseWebSockets()) {
- HttpHeaders headers = HttpHeaders.newHeaders();
-
- options.getHttpHeaders().forEach((key, value) -> {
- headers.set(key, value);
- });
-
- handshaker = WebSocketClientHandshakerFactory.newHandshaker(
- getRemoteURI(), WebSocketVersion.V13, AMQP_SUB_PROTOCOL,
- true, headers, options.getWebSocketMaxFrameSize());
- } else {
- handshaker = null;
- }
- }
-
- @Override
- public final void channelRegistered(ChannelHandlerContext context) throws Exception {
- channel = context.channel();
- }
-
- @Override
- public void channelActive(ChannelHandlerContext context) throws Exception {
- if (options.isUseWebSockets()) {
- handshaker.handshake(context.channel());
-
- handshakeTimeoutFuture = context.executor().schedule(()-> {
- LOG.trace("WebSocket handshake timed out! Channel is {}", context.channel());
- if (!handshaker.isHandshakeComplete()) {
- NettyClient.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
- }
- }, options.getConnectTimeout(), TimeUnit.MILLISECONDS);
- }
-
- // In the Secure case we need to let the handshake complete before we
- // trigger the connected event.
- if (!isSecure()) {
- if (!options.isUseWebSockets()) {
- handleConnected(context.channel());
- }
- } else {
- SslHandler sslHandler = context.pipeline().get(SslHandler.class);
- sslHandler.handshakeFuture().addListener(new FutureListener<Channel>() {
- @Override
- public void operationComplete(Future<? extends Channel> future) throws Exception {
- if (future.isSuccess()) {
- LOG.trace("SSL Handshake has completed: {}", channel);
- if (!options.isUseWebSockets()) {
- handleConnected(channel);
- }
- } else {
- LOG.trace("SSL Handshake has failed: {}", channel);
- handleTransportFailure(channel, future.cause());
- }
- }
- });
- }
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext context) throws Exception {
- if (handshakeTimeoutFuture != null) {
- handshakeTimeoutFuture.cancel();
- }
-
- handleTransportFailure(context.channel(), new IOException("Remote closed connection unexpectedly"));
- }
-
- @Override
- public void channelExceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
- handleTransportFailure(context.channel(), cause);
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object message) {
- if (options.isUseWebSockets()) {
- LOG.trace("New data read: incoming: {}", message);
-
- Channel ch = ctx.channel();
- if (!handshaker.isHandshakeComplete()) {
- handshaker.finishHandshake(ch, (FullHttpResponse) message);
- LOG.trace("WebSocket Client connected! {}", ctx.channel());
- // Now trigger super processing as we are really connected.
- if (handshakeTimeoutFuture.cancel()) {
- handleConnected(ch);
- }
-
- return;
- }
-
- // We shouldn't get this since we handle the handshake previously.
- if (message instanceof FullHttpResponse) {
- FullHttpResponse response = (FullHttpResponse) message;
- throw new IllegalStateException(
- "Unexpected FullHttpResponse (getStatus=" + response.status() +
- ", content=" + response.payload().toString(StandardCharsets.UTF_8) + ')');
- }
-
- WebSocketFrame frame = (WebSocketFrame) message;
- if (frame instanceof TextWebSocketFrame) {
- TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
- LOG.warn("WebSocket Client received message: " + textFrame.text());
- ctx.fireChannelExceptionCaught(new IOException("Received invalid frame over WebSocket."));
- } else if (frame instanceof BinaryWebSocketFrame) {
- BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.binaryData().readableBytes());
- ctx.fireChannelRead(binaryFrame.binaryData());
- } else if (frame instanceof ContinuationWebSocketFrame) {
- ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.binaryData().readableBytes());
- ctx.fireChannelRead(continuationFrame.binaryData());
- } else if (frame instanceof PingWebSocketFrame) {
- LOG.trace("WebSocket Client received ping, response with pong");
- ch.write(new PongWebSocketFrame(frame.binaryData()));
- } else if (frame instanceof CloseWebSocketFrame) {
- LOG.trace("WebSocket Client received closing");
- ch.close();
- }
- } else {
- ctx.fireChannelRead(message);
- }
- }
- }
-
- private class NettyClientOutboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (options.isUseWebSockets() && msg instanceof Buffer) {
- if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
- int split = orig.readableBytes()/2;
-
- Buffer part1 = orig.copy(origIndex, split);
- LOG.trace("NettyClientOutboundHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
- LOG.trace("NettyClientOutboundHandler: Part2: {}", orig);
-
- BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
- ctx.writeAndFlush(frame1);
- ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
- } else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
- }
- } else {
- return ctx.write(msg);
- }
- }
- }
-
- //----- Internal Client implementation API
-
- protected abstract ChannelHandler getClientHandler();
-
- protected EventLoop getEventLoop() {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return channel.executor();
- }
-
- protected SslHandler getSslHandler() {
- return sslHandler;
- }
-
- private void configureChannel(final Channel channel) throws Exception {
- if (isSecure()) {
- final SslHandler sslHandler;
- try {
- sslHandler = SslSupport.createClientSslHandler(getRemoteURI(), options);
- } catch (Exception ex) {
- LOG.warn("Error during initialization of channel from SSL Handler creation:");
- handleTransportFailure(channel, ex);
- throw new IOException(ex);
- }
-
- channel.pipeline().addLast("ssl", sslHandler);
- }
-
- if (options.isTraceBytes()) {
- channel.pipeline().addLast("logger", new LoggingHandler(getClass()));
- }
-
- if (options.isUseWebSockets()) {
- channel.pipeline().addLast(new HttpClientCodec());
- channel.pipeline().addLast(new HttpObjectAggregator<DefaultHttpContent>(8192));
- }
-
- channel.pipeline().addLast(new NettyClientOutboundHandler());
- channel.pipeline().addLast(new NettyClientInboundHandler());
- channel.pipeline().addLast(getClientHandler());
- }
-
- private void configureNetty(Bootstrap bootstrap, ProtonTestClientOptions options) {
- bootstrap.option(ChannelOption.TCP_NODELAY, options.isTcpNoDelay());
- bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeout());
- bootstrap.option(ChannelOption.SO_KEEPALIVE, options.isTcpKeepAlive());
- bootstrap.option(ChannelOption.SO_LINGER, options.getSoLinger());
-
- if (options.getSendBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_SNDBUF, options.getSendBufferSize());
- }
-
- if (options.getReceiveBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_RCVBUF, options.getReceiveBufferSize());
- }
-
- if (options.getTrafficClass() != -1) {
- bootstrap.option(ChannelOption.IP_TOS, options.getTrafficClass());
- }
-
- if (options.getLocalAddress() != null || options.getLocalPort() != 0) {
- if (options.getLocalAddress() != null) {
- bootstrap.localAddress(options.getLocalAddress(), options.getLocalPort());
- } else {
- bootstrap.localAddress(options.getLocalPort());
- }
- }
- }
-
- //----- Event Handlers which can be overridden in subclasses -------------//
-
- protected void handleConnected(Channel connectedChannel) {
- LOG.trace("Channel has become active! Channel is {}", connectedChannel);
- channel = connectedChannel;
- connected.set(true);
- connectedLatch.countDown();
- }
+public interface NettyClient extends AutoCloseable {
+
+ /**
+ * Connect to the specified host on the given port.
+ *
+ * @param host
+ * The host to connect to
+ * @param port
+ * The port on the host to connect to.
+ *
+ * @throws IOException if the connect fails immediately.
+ */
+ void connect(String host, int port) throws IOException;
+
+ /**
+ * @return a wrapped event loop that exposes common netty event loop APIs
+ */
+ NettyEventLoop eventLoop();
+
+ /**
+ * Writes the given {@link ByteBuffer} to the client IO layer.
+ *
+ * @param buffer
+ * The buffer of bytes to write.
+ */
+ void write(ByteBuffer buffer);
+
+ /**
+ * @return is the client currently connected.
+ */
+ boolean isConnected();
+
+ /**
+ * @return is the connection secure.
+ */
+ boolean isSecure();
+
+ /**
+ * @return a URI that represents the client connection.
+ */
+ URI getRemoteURI();
- protected void handleTransportFailure(Channel failedChannel, Throwable cause) {
- if (!closed.get()) {
- LOG.trace("Channel indicates connection failure! Channel is {}", failedChannel);
- failureCause = new IOException(cause);
- channel = failedChannel;
- connected.set(false);
- connectedLatch.countDown();
- } else {
- LOG.trace("Closed Channel signalled that the channel ended: {}", channel);
- }
- }
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyEventLoop.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyEventLoop.java
new file mode 100644
index 00000000..59fb4745
--- /dev/null
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyEventLoop.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.qpid.protonj2.test.driver.netty;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Abstraction around Netty event loops to allow change of Netty version
+ */
+public interface NettyEventLoop {
+
+ /**
+ * @return true if the current thread is the event loop thread.
+ */
+ boolean inEventLoop();
+
+ /**
+ * Run the given {@link Runnable} on the Netty event loop.
+ *
+ * @param runnable
+ * The {@link Runnable} to schedule to run on the event loop.
+ */
+ void execute(Runnable runnable);
+
+ /**
+ * Schedule the given {@link Runnable} to run on the event loop after the given delay
+ *
+ * @param runnable
+ * The {@link Runnable} to schedule to run on the event loop.
+ * @param delay
+ * The time delay before the {@link Runnable} should be executed.
+ * @param unit
+ * The units that the time delay is given in.
+ */
+ void schedule(Runnable runnable, int delay, TimeUnit unit);
+
+}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java
new file mode 100644
index 00000000..cfa728d9
--- /dev/null
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.qpid.protonj2.test.driver.netty;
+
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
+
+import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
+import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
+import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Client;
+import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Server;
+import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Support;
+import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Client;
+import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Server;
+import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Support;
+
+/**
+ * An I/O context used to abstract the implementation of the IO layer in use.
+ */
+public interface NettyIOBuilder {
+
+ /**
+ * Create an NettyClient from the available options.
+ *
+ * @param options
+ * The {@link ProtonTestClientOptions} that configure the IO Transport the context creates.
+ * @param connectedHandler
+ * A handler that should be invoked when a connection attempt succeeds.
+ * @param inputHandler
+ * A {@link Consumer} that accept incoming {@link ByteBuffer} data from the remote.
+ *
+ * @return a new {@link NettyClient} from available options.
+ */
+ public static NettyClient createClient(ProtonTestClientOptions options, Runnable connectedHandler, Consumer<ByteBuffer> inputHandler) {
+ if (Netty4Support.isAvailable()) {
+ return new Netty4Client(options, connectedHandler, inputHandler);
+ } else if (Netty5Support.isAvailable()) {
+ return new Netty5Client(options, connectedHandler, inputHandler);
+ }
+
+ throw new UnsupportedOperationException("Netty not available on the class path");
+ }
+
+ /**
+ * Create an NettyServer from the available options.
+ *
+ * @param options
+ * The {@link ProtonTestServerOptions} that configure the IO Transport the context creates.
+ * @param connectedHandler
+ * A handler that should be invoked when a connection attempt succeeds.
+ * @param inputHandler
+ * A {@link Consumer} that accept incoming {@link ByteBuffer} data from the remote.
+ *
+ * @return a new {@link NettyServer} from available options.
+ */
+ public static NettyServer createServer(ProtonTestServerOptions options, Runnable connectedHandler, Consumer<ByteBuffer> inputHandler) {
+ if (Netty4Support.isAvailable()) {
+ return new Netty4Server(options, connectedHandler, inputHandler);
+ } else if (Netty5Support.isAvailable()) {
+ return new Netty5Server(options, connectedHandler, inputHandler);
+ }
+
+ throw new UnsupportedOperationException("Netty not available on the class path");
+ }
+}
\ No newline at end of file
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
index 26f16892..4291bee1 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
@@ -14,431 +14,58 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.qpid.protonj2.test.driver.netty;
-import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLPeerUnverifiedException;
-
-import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.bootstrap.ServerBootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.DefaultBufferAllocators;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioServerSocketChannel;
-import io.netty5.handler.codec.http.DefaultFullHttpResponse;
-import io.netty5.handler.codec.http.DefaultHttpContent;
-import io.netty5.handler.codec.http.FullHttpRequest;
-import io.netty5.handler.codec.http.FullHttpResponse;
-import io.netty5.handler.codec.http.HttpObjectAggregator;
-import io.netty5.handler.codec.http.HttpResponseStatus;
-import io.netty5.handler.codec.http.HttpServerCodec;
-import io.netty5.handler.codec.http.HttpUtil;
-import io.netty5.handler.codec.http.HttpVersion;
-import io.netty5.handler.codec.http.websocketx.BinaryWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.ContinuationWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketServerHandshakeCompletionEvent;
-import io.netty5.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
-import io.netty5.handler.logging.LogLevel;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
/**
- * Base Server implementation used to create Netty based server implementations for
- * unit testing aspects of the client code.
+ *
*/
-public abstract class NettyServer implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class);
-
- static final int PORT = Integer.parseInt(System.getProperty("port", "5672"));
- static final String WEBSOCKET_PATH = "/";
- static final int DEFAULT_MAX_FRAME_SIZE = 65535;
-
- private EventLoopGroup bossGroup;
- private EventLoopGroup workerGroup;
- private Channel serverChannel;
- private Channel clientChannel;
- private final ProtonTestServerOptions options;
- private int maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
- private String webSocketPath = WEBSOCKET_PATH;
- private volatile SslHandler sslHandler;
- private volatile WebSocketServerHandshakeCompletionEvent handshakeComplete;
- private final CountDownLatch handshakeCompletion = new CountDownLatch(1);
-
- private final AtomicBoolean started = new AtomicBoolean();
-
- public NettyServer(ProtonTestServerOptions options) {
- this.options = options;
- }
-
- public boolean isSecureServer() {
- return options.isSecure();
- }
-
- public boolean isAcceptingConnections() {
- return serverChannel != null && serverChannel.isOpen();
- }
-
- public boolean hasSecureConnection() {
- return sslHandler != null;
- }
-
- public boolean hasClientConnection() {
- return clientChannel != null && clientChannel.isOpen();
- }
-
- public int getClientPort() {
- Objects.requireNonNull(clientChannel);
- return (((InetSocketAddress) clientChannel.remoteAddress()).getPort());
- }
-
- public boolean isPeerVerified() {
- try {
- if (hasSecureConnection()) {
- return sslHandler.engine().getSession().getPeerPrincipal() != null;
- } else {
- return false;
- }
- } catch (SSLPeerUnverifiedException unverified) {
- return false;
- }
- }
-
- public SSLEngine getConnectionSSLEngine() {
- if (hasSecureConnection()) {
- return sslHandler.engine();
- } else {
- return null;
- }
- }
-
- public boolean isWebSocketServer() {
- return options.isUseWebSockets();
- }
-
- public String getWebSocketPath() {
- return webSocketPath;
- }
-
- public void setWebSocketPath(String webSocketPath) {
- this.webSocketPath = webSocketPath;
- }
-
- public int getMaxFrameSize() {
- return maxFrameSize;
- }
-
- public void setMaxFrameSize(int maxFrameSize) {
- this.maxFrameSize = maxFrameSize;
- }
-
- public boolean awaitHandshakeCompletion(long delayMs) throws InterruptedException {
- return handshakeCompletion.await(delayMs, TimeUnit.MILLISECONDS);
- }
-
- public WebSocketServerHandshakeCompletionEvent getHandshakeComplete() {
- return handshakeComplete;
- }
-
- public URI getConnectionURI(String queryString) throws Exception {
- if (!started.get()) {
- throw new IllegalStateException("Cannot get URI of non-started server");
- }
+public interface NettyServer extends AutoCloseable {
- int port = getServerPort();
+ boolean isSecureServer();
- String scheme;
- String path;
+ boolean isAcceptingConnections();
- if (isWebSocketServer()) {
- if (isSecureServer()) {
- scheme = "amqpwss";
- } else {
- scheme = "amqpws";
- }
- } else {
- if (isSecureServer()) {
- scheme = "amqps";
- } else {
- scheme = "amqp";
- }
- }
+ boolean hasSecureConnection();
- if (isWebSocketServer()) {
- path = getWebSocketPath();
- } else {
- path = null;
- }
+ boolean hasClientConnection();
- if (queryString != null && queryString.startsWith("?")) {
- queryString = queryString.substring(1);
- }
+ int getClientPort();
- return new URI(scheme, null, "localhost", port, path, queryString, null);
- }
+ boolean isPeerVerified();
- public void start() throws Exception {
- if (started.compareAndSet(false, true)) {
- // Configure the server to basic NIO type channels
- bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
- workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
+ SSLEngine getConnectionSSLEngine();
- ServerBootstrap server = new ServerBootstrap();
- server.group(bossGroup, workerGroup);
- server.channel(NioServerSocketChannel.class);
- server.option(ChannelOption.SO_BACKLOG, 100);
- server.handler(new LoggingHandler(LogLevel.INFO));
- server.childHandler(new ChannelInitializer<Channel>() {
+ boolean isWebSocketServer();
- @Override
- public void initChannel(Channel ch) throws Exception {
- // Don't accept any new connections.
- serverChannel.close();
- // Now we know who the client is
- clientChannel = ch;
+ String getWebSocketPath();
- if (isSecureServer()) {
- ch.pipeline().addLast(sslHandler = SslSupport.createServerSslHandler(null, options));
- }
+ void setWebSocketPath(String webSocketPath);
- if (options.isUseWebSockets()) {
- ch.pipeline().addLast(new HttpServerCodec());
- ch.pipeline().addLast(new HttpObjectAggregator<DefaultHttpContent>(65536));
- ch.pipeline().addLast(new WebSocketServerProtocolHandler(getWebSocketPath(), "amqp", true, maxFrameSize));
- }
+ int getMaxFrameSize();
- ch.pipeline().addLast(new NettyServerOutboundHandler());
- ch.pipeline().addLast(new NettyServerInboundHandler());
- ch.pipeline().addLast(getServerHandler());
- }
- });
+ void setMaxFrameSize(int maxFrameSize);
- // Start the server and then update the server port in case the configuration
- // was such that the server chose a free port.
- serverChannel = server.bind(options.getServerPort()).asStage().get();
- options.setServerPort(((InetSocketAddress) serverChannel.localAddress()).getPort());
- }
- }
+ URI getConnectionURI(String queryString) throws Exception;
- protected abstract ChannelHandler getServerHandler();
+ void start() throws Exception;
- public void write(ByteBuffer frame) {
- if (clientChannel == null || !clientChannel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
+ void write(ByteBuffer frame);
- clientChannel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(frame).makeReadOnly());
- }
+ NettyEventLoop eventLoop();
- public EventLoop eventLoop() {
- if (clientChannel == null || !clientChannel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
+ void stop() throws InterruptedException;
- return clientChannel.executor();
- }
-
- public void stop() throws InterruptedException {
- if (started.compareAndSet(true, false)) {
- LOG.info("Syncing channel close");
- serverChannel.close().asStage().sync();
-
- if (clientChannel != null) {
- try {
- if (!clientChannel.close().asStage().await(10, TimeUnit.SECONDS)) {
- LOG.info("Connected Client channel close timed out waiting for result");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Close of connected client channel interrupted while awaiting result");
- }
- }
-
- // Shut down all event loops to terminate all threads.
- int timeout = 100;
- LOG.trace("Shutting down boss group");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
- LOG.trace("Boss group shut down");
-
- LOG.trace("Shutting down worker group");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
- LOG.trace("Worker group shut down");
- }
- }
-
- public void stopAsync() throws InterruptedException {
- if (started.compareAndSet(true, false)) {
- LOG.info("Closing channel asynchronously");
- serverChannel.close().asStage().sync();
-
- if (clientChannel != null) {
- clientChannel.close();
- }
-
- // Shut down all event loops to terminate all threads.
- int timeout = 100;
- LOG.trace("Shutting down boss group asynchronously");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
-
- LOG.trace("Shutting down worker group asynchronously");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
- }
- }
+ void stopAsync() throws InterruptedException;
@Override
- public void close() throws InterruptedException {
- stop();
- }
-
- public int getServerPort() {
- if (!started.get()) {
- throw new IllegalStateException("Cannot get server port of non-started server");
- }
-
- return options.getServerPort();
- }
-
- private class NettyServerOutboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (isWebSocketServer() && msg instanceof Buffer) {
- if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
- int split = orig.readableBytes()/2;
-
- Buffer part1 = orig.copy(origIndex, split);
- LOG.trace("NettyServerHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
- LOG.trace("NettyServerHandler: Part2: {}", orig);
-
- BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
- ctx.writeAndFlush(frame1);
- ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
- } else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
- }
- } else {
- return ctx.write(msg);
- }
- }
- }
-
- private class NettyServerInboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public void channelInboundEvent(ChannelHandlerContext context, Object payload) {
- if (payload instanceof WebSocketServerHandshakeCompletionEvent) {
- handshakeComplete = (WebSocketServerHandshakeCompletionEvent) payload;
- handshakeCompletion.countDown();
- }
- }
-
- @Override
- public void channelActive(final ChannelHandlerContext ctx) {
- LOG.info("NettyServerHandler -> New active channel: {}", ctx.channel());
- SslHandler handler = ctx.pipeline().get(SslHandler.class);
- if (handler != null) {
- handler.handshakeFuture().addListener(new FutureListener<Channel>() {
- @Override
- public void operationComplete(Future<? extends Channel> future) throws Exception {
- LOG.info("Server -> SSL handshake completed. Succeeded: {}", future.isSuccess());
- if (!future.isSuccess()) {
- ctx.close();
- }
- }
- });
- }
-
- ctx.fireChannelActive();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- LOG.info("NettyServerHandler: channel has gone inactive: {}", ctx.channel());
- ctx.close();
- ctx.fireChannelInactive();
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel read: {}", msg);
- if (msg instanceof WebSocketFrame) {
- WebSocketFrame frame = (WebSocketFrame) msg;
- ctx.fireChannelRead(frame.binaryData());
- } else if (msg instanceof FullHttpRequest) {
- // Reject anything not on the WebSocket path
- FullHttpRequest request = (FullHttpRequest) msg;
-
- sendHttpResponse(ctx, request,
- new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST, DefaultBufferAllocators.onHeapAllocator().allocate(0)));
- } else {
- // Forward anything else along to the next handler.
- ctx.fireChannelRead(msg);
- }
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- ctx.flush();
- }
-
- @Override
- public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- LOG.info("NettyServerHandler: NettyServerHandlerException caught on channel: {}", ctx.channel());
- // Close the connection when an exception is raised.
- cause.printStackTrace();
- ctx.close();
- }
- }
-
- private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {
- // Generate an error page if response getStatus code is not OK (200).
- if (response.status().code() != 200) {
- byte[] status = response.status().toString().getBytes(StandardCharsets.UTF_8);
- response.payload().writeBytes(status);
- HttpUtil.setContentLength(response, response.payload().readableBytes());
- }
+ void close() throws InterruptedException;
- // Send the response and close the connection if necessary.
- Future<Void> f = ctx.channel().writeAndFlush(response);
- if (!HttpUtil.isKeepAlive(request) || response.status().code() != 200) {
- f.addListener(ctx.channel(), ChannelFutureListeners.CLOSE);
- }
- }
+ int getServerPort();
- protected SslHandler getSslHandler() {
- return sslHandler;
- }
-}
+}
\ No newline at end of file
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Client.java
similarity index 68%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Client.java
index ae2fbdcf..30a0207e 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Client.java
@@ -14,66 +14,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty4;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
+import org.apache.qpid.protonj2.test.driver.netty.NettyClient;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.bootstrap.Bootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioSocketChannel;
-import io.netty5.handler.codec.http.DefaultHttpContent;
-import io.netty5.handler.codec.http.FullHttpResponse;
-import io.netty5.handler.codec.http.HttpClientCodec;
-import io.netty5.handler.codec.http.HttpObjectAggregator;
-import io.netty5.handler.codec.http.headers.HttpHeaders;
-import io.netty5.handler.codec.http.websocketx.BinaryWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.ContinuationWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PingWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PongWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.TextWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshaker;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
-import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketVersion;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.EventLoop;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.http.DefaultHttpHeaders;
+import io.netty.handler.codec.http.FullHttpResponse;
+import io.netty.handler.codec.http.HttpClientCodec;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
+import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
+import io.netty.handler.codec.http.websocketx.WebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketVersion;
+import io.netty.handler.logging.LoggingHandler;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.ScheduledFuture;
/**
* Self contained Netty client implementation that provides a base for more
* complex client implementations to use as the IO layer.
*/
-public abstract class NettyClient implements AutoCloseable {
+public final class Netty4Client implements NettyClient {
- private static final Logger LOG = LoggerFactory.getLogger(NettyClient.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String AMQP_SUB_PROTOCOL = "amqp";
+ private Netty4EventLoop eventLoop;
private Bootstrap bootstrap;
private EventLoopGroup group;
private Channel channel;
@@ -86,8 +94,17 @@ public abstract class NettyClient implements AutoCloseable {
protected final AtomicBoolean closed = new AtomicBoolean();
protected final CountDownLatch connectedLatch = new CountDownLatch(1);
- public NettyClient(ProtonTestClientOptions options) {
+ private final Consumer<ByteBuffer> inputConsumer;
+ private final Runnable connectedRunnable;
+
+ public Netty4Client(ProtonTestClientOptions options, Runnable connectedRunnable, Consumer<ByteBuffer> inputConsumer) {
+ Objects.requireNonNull(options);
+ Objects.requireNonNull(inputConsumer);
+ Objects.requireNonNull(connectedRunnable);
+
this.options = options;
+ this.connectedRunnable = connectedRunnable;
+ this.inputConsumer = inputConsumer;
}
@Override
@@ -97,7 +114,7 @@ public abstract class NettyClient implements AutoCloseable {
connectedLatch.countDown();
if (channel != null) {
try {
- if (!channel.close().asStage().await(10, TimeUnit.SECONDS)) {
+ if (!channel.close().await(10, TimeUnit.SECONDS)) {
LOG.info("Channel close timed out waiting for result");
}
} catch (InterruptedException e) {
@@ -108,6 +125,7 @@ public abstract class NettyClient implements AutoCloseable {
}
}
+ @Override
public void connect(String host, int port) throws IOException {
if (closed.get()) {
throw new IllegalStateException("Netty client has already been closed");
@@ -129,19 +147,20 @@ public abstract class NettyClient implements AutoCloseable {
}
}
- group = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
+ group = new NioEventLoopGroup(1);
bootstrap = new Bootstrap().channel(NioSocketChannel.class).group(group);
bootstrap.handler(new ChannelInitializer<Channel>() {
@Override
public void initChannel(Channel transportChannel) throws Exception {
channel = transportChannel;
+ eventLoop = new Netty4EventLoop(channel.eventLoop());
configureChannel(transportChannel);
}
});
configureNetty(bootstrap, options);
- bootstrap.connect(host, port).addListener(channel, ChannelFutureListeners.FIRE_EXCEPTION_ON_FAILURE);
+ bootstrap.connect(host, port).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
try {
connectedLatch.await();
} catch (InterruptedException e) {
@@ -157,30 +176,35 @@ public abstract class NettyClient implements AutoCloseable {
}
}
- public EventLoop eventLoop() {
+ @Override
+ public NettyEventLoop eventLoop() {
if (channel == null || !channel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- return channel.executor();
+ return eventLoop;
}
+ @Override
public void write(ByteBuffer buffer) {
if (channel == null || !channel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- channel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(buffer).makeReadOnly());
+ channel.writeAndFlush(Unpooled.wrappedBuffer(buffer).asReadOnly());
}
+ @Override
public boolean isConnected() {
return connected.get();
}
+ @Override
public boolean isSecure() {
return options.isSecure();
}
+ @Override
public URI getRemoteURI() {
if (host != null) {
try {
@@ -198,14 +222,14 @@ public abstract class NettyClient implements AutoCloseable {
//----- Default implementation of Netty handler
- protected class NettyClientInboundHandler implements ChannelHandler {
+ protected class NettyClientInboundHandler extends ChannelInboundHandlerAdapter {
private final WebSocketClientHandshaker handshaker;
- private Future<Void> handshakeTimeoutFuture;
+ private ScheduledFuture<?> handshakeTimeoutFuture;
public NettyClientInboundHandler() {
if (options.isUseWebSockets()) {
- HttpHeaders headers = HttpHeaders.newHeaders();
+ DefaultHttpHeaders headers = new DefaultHttpHeaders();
options.getHttpHeaders().forEach((key, value) -> {
headers.set(key, value);
@@ -232,7 +256,7 @@ public abstract class NettyClient implements AutoCloseable {
handshakeTimeoutFuture = context.executor().schedule(()-> {
LOG.trace("WebSocket handshake timed out! Channel is {}", context.channel());
if (!handshaker.isHandshakeComplete()) {
- NettyClient.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
+ Netty4Client.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
}
}, options.getConnectTimeout(), TimeUnit.MILLISECONDS);
}
@@ -245,9 +269,9 @@ public abstract class NettyClient implements AutoCloseable {
}
} else {
SslHandler sslHandler = context.pipeline().get(SslHandler.class);
- sslHandler.handshakeFuture().addListener(new FutureListener<Channel>() {
+ sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {
@Override
- public void operationComplete(Future<? extends Channel> future) throws Exception {
+ public void operationComplete(Future<Channel> future) throws Exception {
if (future.isSuccess()) {
LOG.trace("SSL Handshake has completed: {}", channel);
if (!options.isUseWebSockets()) {
@@ -261,18 +285,17 @@ public abstract class NettyClient implements AutoCloseable {
});
}
}
-
@Override
public void channelInactive(ChannelHandlerContext context) throws Exception {
if (handshakeTimeoutFuture != null) {
- handshakeTimeoutFuture.cancel();
+ handshakeTimeoutFuture.cancel(false);
}
handleTransportFailure(context.channel(), new IOException("Remote closed connection unexpectedly"));
}
@Override
- public void channelExceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
handleTransportFailure(context.channel(), cause);
}
@@ -286,7 +309,7 @@ public abstract class NettyClient implements AutoCloseable {
handshaker.finishHandshake(ch, (FullHttpResponse) message);
LOG.trace("WebSocket Client connected! {}", ctx.channel());
// Now trigger super processing as we are really connected.
- if (handshakeTimeoutFuture.cancel()) {
+ if (handshakeTimeoutFuture.cancel(false)) {
handleConnected(ch);
}
@@ -298,25 +321,25 @@ public abstract class NettyClient implements AutoCloseable {
FullHttpResponse response = (FullHttpResponse) message;
throw new IllegalStateException(
"Unexpected FullHttpResponse (getStatus=" + response.status() +
- ", content=" + response.payload().toString(StandardCharsets.UTF_8) + ')');
+ ", content=" + response.content().toString(StandardCharsets.UTF_8) + ')');
}
WebSocketFrame frame = (WebSocketFrame) message;
if (frame instanceof TextWebSocketFrame) {
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
LOG.warn("WebSocket Client received message: " + textFrame.text());
- ctx.fireChannelExceptionCaught(new IOException("Received invalid frame over WebSocket."));
+ ctx.fireExceptionCaught(new IOException("Received invalid frame over WebSocket."));
} else if (frame instanceof BinaryWebSocketFrame) {
BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.binaryData().readableBytes());
- ctx.fireChannelRead(binaryFrame.binaryData());
+ LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.content().readableBytes());
+ ctx.fireChannelRead(binaryFrame.content());
} else if (frame instanceof ContinuationWebSocketFrame) {
ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.binaryData().readableBytes());
- ctx.fireChannelRead(continuationFrame.binaryData());
+ LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.content().readableBytes());
+ ctx.fireChannelRead(continuationFrame.content());
} else if (frame instanceof PingWebSocketFrame) {
LOG.trace("WebSocket Client received ping, response with pong");
- ch.write(new PongWebSocketFrame(frame.binaryData()));
+ ch.write(new PongWebSocketFrame(frame.content()));
} else if (frame instanceof CloseWebSocketFrame) {
LOG.trace("WebSocket Client received closing");
ch.close();
@@ -327,46 +350,70 @@ public abstract class NettyClient implements AutoCloseable {
}
}
- private class NettyClientOutboundHandler extends ChannelHandlerAdapter {
+ private class NettyClientOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override
- public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (options.isUseWebSockets() && msg instanceof Buffer) {
+ if (options.isUseWebSockets() && msg instanceof ByteBuf) {
if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
+ ByteBuf orig = (ByteBuf) msg;
+ int origIndex = orig.readerIndex();
int split = orig.readableBytes()/2;
- Buffer part1 = orig.copy(origIndex, split);
+ ByteBuf part1 = orig.copy(origIndex, split);
LOG.trace("NettyClientOutboundHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
+ orig.readerIndex(origIndex + split);
LOG.trace("NettyClientOutboundHandler: Part2: {}", orig);
BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
ctx.writeAndFlush(frame1);
ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
+ ctx.write(frame2, promise);
} else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
+ BinaryWebSocketFrame frame = new BinaryWebSocketFrame((ByteBuf) msg);
+ ctx.write(frame, promise);
}
} else {
- return ctx.write(msg);
+ ctx.write(msg, promise);
}
}
}
//----- Internal Client implementation API
- protected abstract ChannelHandler getClientHandler();
+ protected ChannelHandler getClientHandler() {
+ return new SimpleChannelInboundHandler<ByteBuf>() {
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectedRunnable.run();
+ ctx.fireChannelActive();
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf input) throws Exception {
+ LOG.trace("AMQP Test Client Channel read: {}", input);
+
+ // Driver processes new data and may produce output based on this.
+ try {
+ final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
+ input.readBytes(copy);
+ inputConsumer.accept(copy.flip().asReadOnlyBuffer());
+ } catch (Throwable e) {
+ LOG.error("Closed AMQP Test client channel due to error: ", e);
+ ctx.channel().close();
+ }
+ }
+ };
+ }
protected EventLoop getEventLoop() {
if (channel == null || !channel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- return channel.executor();
+ return channel.eventLoop();
}
protected SslHandler getSslHandler() {
@@ -393,7 +440,7 @@ public abstract class NettyClient implements AutoCloseable {
if (options.isUseWebSockets()) {
channel.pipeline().addLast(new HttpClientCodec());
- channel.pipeline().addLast(new HttpObjectAggregator<DefaultHttpContent>(8192));
+ channel.pipeline().addLast(new HttpObjectAggregator(8192));
}
channel.pipeline().addLast(new NettyClientOutboundHandler());
@@ -445,7 +492,7 @@ public abstract class NettyClient implements AutoCloseable {
connected.set(false);
connectedLatch.countDown();
} else {
- LOG.trace("Closed Channel signalled that the channel ended: {}", channel);
+ LOG.trace("Closed Channel signaled that the channel ended: {}", channel);
}
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4EventLoop.java
similarity index 58%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4EventLoop.java
index 675c9da4..79015e4c 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4EventLoop.java
@@ -14,37 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+package org.apache.qpid.protonj2.test.driver.netty.netty4;
-class NullElement extends AtomicElement<Void> {
+import java.util.concurrent.TimeUnit;
- NullElement(Element<?> parent, Element<?> prev) {
- super(parent, prev);
- }
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
- @Override
- public int size() {
- return isElementOfArray() ? 0 : 1;
+import io.netty.channel.EventLoop;
+
+public final class Netty4EventLoop implements NettyEventLoop {
+
+ private final EventLoop loop;
+
+ public Netty4EventLoop(EventLoop loop) {
+ this.loop = loop;
}
@Override
- public Void getValue() {
- return null;
+ public boolean inEventLoop() {
+ return loop.inEventLoop();
}
@Override
- public Codec.DataType getDataType() {
- return Codec.DataType.NULL;
+ public void execute(Runnable runnable) {
+ loop.execute(runnable);
}
@Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0 && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public void schedule(Runnable runnable, int delay, TimeUnit unit) {
+ loop.schedule(runnable, delay, unit);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Server.java
similarity index 65%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Server.java
index 26f16892..cf7ba820 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Server.java
@@ -14,8 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty4;
+import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
+import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+
+import java.lang.invoke.MethodHandles;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
@@ -24,62 +28,64 @@ import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLPeerUnverifiedException;
import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
+import org.apache.qpid.protonj2.test.driver.netty.NettyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.bootstrap.ServerBootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.DefaultBufferAllocators;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioServerSocketChannel;
-import io.netty5.handler.codec.http.DefaultFullHttpResponse;
-import io.netty5.handler.codec.http.DefaultHttpContent;
-import io.netty5.handler.codec.http.FullHttpRequest;
-import io.netty5.handler.codec.http.FullHttpResponse;
-import io.netty5.handler.codec.http.HttpObjectAggregator;
-import io.netty5.handler.codec.http.HttpResponseStatus;
-import io.netty5.handler.codec.http.HttpServerCodec;
-import io.netty5.handler.codec.http.HttpUtil;
-import io.netty5.handler.codec.http.HttpVersion;
-import io.netty5.handler.codec.http.websocketx.BinaryWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.ContinuationWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketServerHandshakeCompletionEvent;
-import io.netty5.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
-import io.netty5.handler.logging.LogLevel;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.FullHttpResponse;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpServerCodec;
+import io.netty.handler.codec.http.HttpUtil;
+import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
/**
* Base Server implementation used to create Netty based server implementations for
* unit testing aspects of the client code.
*/
-public abstract class NettyServer implements AutoCloseable {
+public final class Netty4Server implements NettyServer {
- private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
static final int PORT = Integer.parseInt(System.getProperty("port", "5672"));
static final String WEBSOCKET_PATH = "/";
static final int DEFAULT_MAX_FRAME_SIZE = 65535;
+ private Netty4EventLoop eventLoop;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel serverChannel;
@@ -88,36 +94,51 @@ public abstract class NettyServer implements AutoCloseable {
private int maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
private String webSocketPath = WEBSOCKET_PATH;
private volatile SslHandler sslHandler;
- private volatile WebSocketServerHandshakeCompletionEvent handshakeComplete;
+ private volatile HandshakeComplete handshakeComplete;
private final CountDownLatch handshakeCompletion = new CountDownLatch(1);
private final AtomicBoolean started = new AtomicBoolean();
- public NettyServer(ProtonTestServerOptions options) {
+ private final Consumer<ByteBuffer> inputConsumer;
+ private final Runnable connectedRunnable;
+
+ public Netty4Server(ProtonTestServerOptions options, Runnable connectedRunnable, Consumer<ByteBuffer> inputConsumer) {
+ Objects.requireNonNull(options);
+ Objects.requireNonNull(inputConsumer);
+ Objects.requireNonNull(connectedRunnable);
+
this.options = options;
+ this.connectedRunnable = connectedRunnable;
+ this.inputConsumer = inputConsumer;
}
+ @Override
public boolean isSecureServer() {
return options.isSecure();
}
+ @Override
public boolean isAcceptingConnections() {
return serverChannel != null && serverChannel.isOpen();
}
+ @Override
public boolean hasSecureConnection() {
return sslHandler != null;
}
+ @Override
public boolean hasClientConnection() {
return clientChannel != null && clientChannel.isOpen();
}
+ @Override
public int getClientPort() {
Objects.requireNonNull(clientChannel);
return (((InetSocketAddress) clientChannel.remoteAddress()).getPort());
}
+ @Override
public boolean isPeerVerified() {
try {
if (hasSecureConnection()) {
@@ -130,6 +151,7 @@ public abstract class NettyServer implements AutoCloseable {
}
}
+ @Override
public SSLEngine getConnectionSSLEngine() {
if (hasSecureConnection()) {
return sslHandler.engine();
@@ -138,22 +160,27 @@ public abstract class NettyServer implements AutoCloseable {
}
}
+ @Override
public boolean isWebSocketServer() {
return options.isUseWebSockets();
}
+ @Override
public String getWebSocketPath() {
return webSocketPath;
}
+ @Override
public void setWebSocketPath(String webSocketPath) {
this.webSocketPath = webSocketPath;
}
+ @Override
public int getMaxFrameSize() {
return maxFrameSize;
}
+ @Override
public void setMaxFrameSize(int maxFrameSize) {
this.maxFrameSize = maxFrameSize;
}
@@ -162,10 +189,11 @@ public abstract class NettyServer implements AutoCloseable {
return handshakeCompletion.await(delayMs, TimeUnit.MILLISECONDS);
}
- public WebSocketServerHandshakeCompletionEvent getHandshakeComplete() {
+ public HandshakeComplete getHandshakeComplete() {
return handshakeComplete;
}
+ @Override
public URI getConnectionURI(String queryString) throws Exception {
if (!started.get()) {
throw new IllegalStateException("Cannot get URI of non-started server");
@@ -203,11 +231,12 @@ public abstract class NettyServer implements AutoCloseable {
return new URI(scheme, null, "localhost", port, path, queryString, null);
}
+ @Override
public void start() throws Exception {
if (started.compareAndSet(false, true)) {
// Configure the server to basic NIO type channels
- bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
- workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
+ bossGroup = new NioEventLoopGroup(1);
+ workerGroup = new NioEventLoopGroup();
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup);
@@ -223,13 +252,15 @@ public abstract class NettyServer implements AutoCloseable {
// Now we know who the client is
clientChannel = ch;
+ eventLoop = new Netty4EventLoop(ch.eventLoop());
+
if (isSecureServer()) {
ch.pipeline().addLast(sslHandler = SslSupport.createServerSslHandler(null, options));
}
if (options.isUseWebSockets()) {
ch.pipeline().addLast(new HttpServerCodec());
- ch.pipeline().addLast(new HttpObjectAggregator<DefaultHttpContent>(65536));
+ ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new WebSocketServerProtocolHandler(getWebSocketPath(), "amqp", true, maxFrameSize));
}
@@ -241,37 +272,84 @@ public abstract class NettyServer implements AutoCloseable {
// Start the server and then update the server port in case the configuration
// was such that the server chose a free port.
- serverChannel = server.bind(options.getServerPort()).asStage().get();
+ serverChannel = server.bind(options.getServerPort()).sync().channel();
options.setServerPort(((InetSocketAddress) serverChannel.localAddress()).getPort());
}
}
- protected abstract ChannelHandler getServerHandler();
+ protected ChannelHandler getServerHandler() {
+ return new SimpleChannelInboundHandler<ByteBuf>() {
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectedRunnable.run();
+ ctx.fireChannelActive();
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf input) throws Exception {
+ LOG.trace("AMQP Test Server Channel read: {}", input);
+
+ // Driver processes new data and may produce output based on this.
+ try {
+ final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
+ input.readBytes(copy);
+ inputConsumer.accept(copy.flip().asReadOnlyBuffer());
+ } catch (Throwable e) {
+ LOG.error("Closed AMQP Test server channel due to error: ", e);
+ ctx.channel().close();
+ }
+ }
+ };
+ }
+ @Override
public void write(ByteBuffer frame) {
if (clientChannel == null || !clientChannel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- clientChannel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(frame).makeReadOnly());
+ clientChannel.writeAndFlush(Unpooled.wrappedBuffer(frame), clientChannel.voidPromise());
}
- public EventLoop eventLoop() {
+ @Override
+ public NettyEventLoop eventLoop() {
if (clientChannel == null || !clientChannel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- return clientChannel.executor();
+ return eventLoop;
+ }
+
+ @Override
+ public void stopAsync() throws InterruptedException {
+ if (started.compareAndSet(true, false)) {
+ LOG.info("Closing channel asynchronously");
+ serverChannel.close().sync();
+
+ if (clientChannel != null) {
+ clientChannel.close();
+ }
+
+ // Shut down all event loops to terminate all threads.
+ int timeout = 100;
+ LOG.trace("Shutting down boss group asynchronously");
+ bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
+
+ LOG.trace("Shutting down worker group asynchronously");
+ workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
+ }
}
+ @Override
public void stop() throws InterruptedException {
if (started.compareAndSet(true, false)) {
LOG.info("Syncing channel close");
- serverChannel.close().asStage().sync();
+ serverChannel.close().syncUninterruptibly();
if (clientChannel != null) {
try {
- if (!clientChannel.close().asStage().await(10, TimeUnit.SECONDS)) {
+ if (!clientChannel.close().await(10, TimeUnit.SECONDS)) {
LOG.info("Connected Client channel close timed out waiting for result");
}
} catch (InterruptedException e) {
@@ -283,39 +361,21 @@ public abstract class NettyServer implements AutoCloseable {
// Shut down all event loops to terminate all threads.
int timeout = 100;
LOG.trace("Shutting down boss group");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
+ bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).awaitUninterruptibly(timeout);
LOG.trace("Boss group shut down");
LOG.trace("Shutting down worker group");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
+ workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).awaitUninterruptibly(timeout);
LOG.trace("Worker group shut down");
}
}
- public void stopAsync() throws InterruptedException {
- if (started.compareAndSet(true, false)) {
- LOG.info("Closing channel asynchronously");
- serverChannel.close().asStage().sync();
-
- if (clientChannel != null) {
- clientChannel.close();
- }
-
- // Shut down all event loops to terminate all threads.
- int timeout = 100;
- LOG.trace("Shutting down boss group asynchronously");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
-
- LOG.trace("Shutting down worker group asynchronously");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
- }
- }
-
@Override
public void close() throws InterruptedException {
stop();
}
+ @Override
public int getServerPort() {
if (!started.get()) {
throw new IllegalStateException("Cannot get server port of non-started server");
@@ -324,42 +384,42 @@ public abstract class NettyServer implements AutoCloseable {
return options.getServerPort();
}
- private class NettyServerOutboundHandler extends ChannelHandlerAdapter {
+ private class NettyServerOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override
- public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (isWebSocketServer() && msg instanceof Buffer) {
+ if (isWebSocketServer() && msg instanceof ByteBuf) {
if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
+ ByteBuf orig = (ByteBuf) msg;
+ int origIndex = orig.readerIndex();
int split = orig.readableBytes()/2;
- Buffer part1 = orig.copy(origIndex, split);
+ ByteBuf part1 = orig.copy(origIndex, split);
LOG.trace("NettyServerHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
+ orig.readerIndex(origIndex + split);
LOG.trace("NettyServerHandler: Part2: {}", orig);
BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
ctx.writeAndFlush(frame1);
ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
+ ctx.write(frame2, promise);
} else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
+ BinaryWebSocketFrame frame = new BinaryWebSocketFrame((ByteBuf) msg);
+ ctx.write(frame, promise);
}
} else {
- return ctx.write(msg);
+ ctx.write(msg, promise);
}
}
}
- private class NettyServerInboundHandler extends ChannelHandlerAdapter {
+ private class NettyServerInboundHandler extends ChannelInboundHandlerAdapter {
@Override
- public void channelInboundEvent(ChannelHandlerContext context, Object payload) {
- if (payload instanceof WebSocketServerHandshakeCompletionEvent) {
- handshakeComplete = (WebSocketServerHandshakeCompletionEvent) payload;
+ public void userEventTriggered(ChannelHandlerContext context, Object payload) {
+ if (payload instanceof HandshakeComplete) {
+ handshakeComplete = (HandshakeComplete) payload;
handshakeCompletion.countDown();
}
}
@@ -369,9 +429,9 @@ public abstract class NettyServer implements AutoCloseable {
LOG.info("NettyServerHandler -> New active channel: {}", ctx.channel());
SslHandler handler = ctx.pipeline().get(SslHandler.class);
if (handler != null) {
- handler.handshakeFuture().addListener(new FutureListener<Channel>() {
+ handler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {
@Override
- public void operationComplete(Future<? extends Channel> future) throws Exception {
+ public void operationComplete(Future<Channel> future) throws Exception {
LOG.info("Server -> SSL handshake completed. Succeeded: {}", future.isSuccess());
if (!future.isSuccess()) {
ctx.close();
@@ -395,14 +455,11 @@ public abstract class NettyServer implements AutoCloseable {
LOG.trace("NettyServerHandler: Channel read: {}", msg);
if (msg instanceof WebSocketFrame) {
WebSocketFrame frame = (WebSocketFrame) msg;
- ctx.fireChannelRead(frame.binaryData());
+ ctx.fireChannelRead(frame.content());
} else if (msg instanceof FullHttpRequest) {
// Reject anything not on the WebSocket path
FullHttpRequest request = (FullHttpRequest) msg;
-
- sendHttpResponse(ctx, request,
- new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST, DefaultBufferAllocators.onHeapAllocator().allocate(0)));
+ sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
} else {
// Forward anything else along to the next handler.
ctx.fireChannelRead(msg);
@@ -415,7 +472,7 @@ public abstract class NettyServer implements AutoCloseable {
}
@Override
- public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
LOG.info("NettyServerHandler: NettyServerHandlerException caught on channel: {}", ctx.channel());
// Close the connection when an exception is raised.
cause.printStackTrace();
@@ -426,15 +483,16 @@ public abstract class NettyServer implements AutoCloseable {
private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {
// Generate an error page if response getStatus code is not OK (200).
if (response.status().code() != 200) {
- byte[] status = response.status().toString().getBytes(StandardCharsets.UTF_8);
- response.payload().writeBytes(status);
- HttpUtil.setContentLength(response, response.payload().readableBytes());
+ ByteBuf buf = Unpooled.copiedBuffer(response.status().toString(), StandardCharsets.UTF_8);
+ response.content().writeBytes(buf);
+ buf.release();
+ HttpUtil.setContentLength(response, response.content().readableBytes());
}
// Send the response and close the connection if necessary.
- Future<Void> f = ctx.channel().writeAndFlush(response);
+ ChannelFuture f = ctx.channel().writeAndFlush(response);
if (!HttpUtil.isKeepAlive(request) || response.status().code() != 200) {
- f.addListener(ctx.channel(), ChannelFutureListeners.CLOSE);
+ f.addListener(ChannelFutureListener.CLOSE);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Support.java
similarity index 52%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Support.java
index 675c9da4..2b82e725 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/Netty4Support.java
@@ -14,37 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+package org.apache.qpid.protonj2.test.driver.netty.netty4;
-class NullElement extends AtomicElement<Void> {
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
- NullElement(Element<?> parent, Element<?> prev) {
- super(parent, prev);
- }
+import io.netty.buffer.Unpooled;
- @Override
- public int size() {
- return isElementOfArray() ? 0 : 1;
- }
+/**
+ * Support class used to detect if Netty 4 is available on the class path.
+ */
+public final class Netty4Support {
- @Override
- public Void getValue() {
- return null;
- }
+ private static final Logger LOG = LoggerFactory.getLogger(Netty4Support.class);
- @Override
- public Codec.DataType getDataType() {
- return Codec.DataType.NULL;
+ private static final Throwable UNAVAILABILITY_CAUSE;
+ static {
+ Throwable cause = null;
+ try {
+ Unpooled.wrappedBuffer(new byte[0]);
+ } catch (Throwable ex) {
+ LOG.debug("Netty 4 not available for use.");
+ cause = ex;
+ }
+
+ UNAVAILABILITY_CAUSE = cause;
}
- @Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0 && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public static final boolean isAvailable() {
+ return UNAVAILABILITY_CAUSE == null;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/SslSupport.java
similarity index 98%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/SslSupport.java
index 256122ee..d88b0f51 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty4/SslSupport.java
@@ -14,11 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty4;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -38,18 +39,19 @@ import javax.net.ssl.X509ExtendedKeyManager;
import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
+import org.apache.qpid.protonj2.test.driver.netty.X509AliasKeyManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
/**
* Static class that provides various utility methods used by Transport implementations.
*/
public class SslSupport {
- private static final Logger LOG = LoggerFactory.getLogger(SslSupport.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
/**
* Creates a Netty SslHandler instance for use in client instances that require
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java
similarity index 88%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java
index ae2fbdcf..61134119 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyClient.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java
@@ -14,18 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty5;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
+import org.apache.qpid.protonj2.test.driver.netty.NettyClient;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,6 +47,7 @@ import io.netty5.channel.ChannelOption;
import io.netty5.channel.EventLoop;
import io.netty5.channel.EventLoopGroup;
import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.SimpleChannelInboundHandler;
import io.netty5.channel.nio.NioHandler;
import io.netty5.channel.socket.nio.NioSocketChannel;
import io.netty5.handler.codec.http.DefaultHttpContent;
@@ -68,12 +74,13 @@ import io.netty5.util.concurrent.FutureListener;
* Self contained Netty client implementation that provides a base for more
* complex client implementations to use as the IO layer.
*/
-public abstract class NettyClient implements AutoCloseable {
+public final class Netty5Client implements NettyClient {
- private static final Logger LOG = LoggerFactory.getLogger(NettyClient.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String AMQP_SUB_PROTOCOL = "amqp";
+ private Netty5EventLoop eventLoop;
private Bootstrap bootstrap;
private EventLoopGroup group;
private Channel channel;
@@ -86,8 +93,17 @@ public abstract class NettyClient implements AutoCloseable {
protected final AtomicBoolean closed = new AtomicBoolean();
protected final CountDownLatch connectedLatch = new CountDownLatch(1);
- public NettyClient(ProtonTestClientOptions options) {
+ private final Consumer<ByteBuffer> inputConsumer;
+ private final Runnable connectedRunnable;
+
+ public Netty5Client(ProtonTestClientOptions options, Runnable connectedRunnable, Consumer<ByteBuffer> inputConsumer) {
+ Objects.requireNonNull(options);
+ Objects.requireNonNull(inputConsumer);
+ Objects.requireNonNull(connectedRunnable);
+
this.options = options;
+ this.connectedRunnable = connectedRunnable;
+ this.inputConsumer = inputConsumer;
}
@Override
@@ -108,6 +124,7 @@ public abstract class NettyClient implements AutoCloseable {
}
}
+ @Override
public void connect(String host, int port) throws IOException {
if (closed.get()) {
throw new IllegalStateException("Netty client has already been closed");
@@ -135,6 +152,7 @@ public abstract class NettyClient implements AutoCloseable {
@Override
public void initChannel(Channel transportChannel) throws Exception {
channel = transportChannel;
+ eventLoop = new Netty5EventLoop(channel.executor());
configureChannel(transportChannel);
}
});
@@ -157,14 +175,16 @@ public abstract class NettyClient implements AutoCloseable {
}
}
- public EventLoop eventLoop() {
+ @Override
+ public NettyEventLoop eventLoop() {
if (channel == null || !channel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- return channel.executor();
+ return eventLoop;
}
+ @Override
public void write(ByteBuffer buffer) {
if (channel == null || !channel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
@@ -173,14 +193,17 @@ public abstract class NettyClient implements AutoCloseable {
channel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(buffer).makeReadOnly());
}
+ @Override
public boolean isConnected() {
return connected.get();
}
+ @Override
public boolean isSecure() {
return options.isSecure();
}
+ @Override
public URI getRemoteURI() {
if (host != null) {
try {
@@ -232,7 +255,7 @@ public abstract class NettyClient implements AutoCloseable {
handshakeTimeoutFuture = context.executor().schedule(()-> {
LOG.trace("WebSocket handshake timed out! Channel is {}", context.channel());
if (!handshaker.isHandshakeComplete()) {
- NettyClient.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
+ Netty5Client.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
}
}, options.getConnectTimeout(), TimeUnit.MILLISECONDS);
}
@@ -359,7 +382,31 @@ public abstract class NettyClient implements AutoCloseable {
//----- Internal Client implementation API
- protected abstract ChannelHandler getClientHandler();
+ protected ChannelHandler getClientHandler() {
+ return new SimpleChannelInboundHandler<Buffer>() {
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectedRunnable.run();
+ ctx.fireChannelActive();
+ }
+
+ @Override
+ protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
+ LOG.trace("AMQP Test Client Channel read: {}", input);
+
+ // Driver processes new data and may produce output based on this.
+ try {
+ final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
+ input.readBytes(copy);
+ inputConsumer.accept(copy.flip().asReadOnlyBuffer());
+ } catch (Throwable e) {
+ LOG.error("Closed AMQP Test client channel due to error: ", e);
+ ctx.channel().close();
+ }
+ }
+ };
+ }
protected EventLoop getEventLoop() {
if (channel == null || !channel.isActive()) {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java
similarity index 58%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java
index 675c9da4..16056003 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java
@@ -14,37 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+package org.apache.qpid.protonj2.test.driver.netty.netty5;
-class NullElement extends AtomicElement<Void> {
+import java.util.concurrent.TimeUnit;
- NullElement(Element<?> parent, Element<?> prev) {
- super(parent, prev);
- }
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
- @Override
- public int size() {
- return isElementOfArray() ? 0 : 1;
+import io.netty5.channel.EventLoop;
+
+public final class Netty5EventLoop implements NettyEventLoop {
+
+ private final EventLoop loop;
+
+ public Netty5EventLoop(EventLoop loop) {
+ this.loop = loop;
}
@Override
- public Void getValue() {
- return null;
+ public boolean inEventLoop() {
+ return loop.inEventLoop();
}
@Override
- public Codec.DataType getDataType() {
- return Codec.DataType.NULL;
+ public void execute(Runnable runnable) {
+ loop.execute(runnable);
}
@Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0 && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public void schedule(Runnable runnable, int delay, TimeUnit unit) {
+ loop.schedule(runnable, delay, unit);
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java
similarity index 87%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java
index 26f16892..11cf9652 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyServer.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java
@@ -14,8 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty5;
+import java.lang.invoke.MethodHandles;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
@@ -24,11 +25,14 @@ import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLPeerUnverifiedException;
import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
+import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
+import org.apache.qpid.protonj2.test.driver.netty.NettyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,9 +47,9 @@ import io.netty5.channel.ChannelHandlerAdapter;
import io.netty5.channel.ChannelHandlerContext;
import io.netty5.channel.ChannelInitializer;
import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
import io.netty5.channel.EventLoopGroup;
import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.SimpleChannelInboundHandler;
import io.netty5.channel.nio.NioHandler;
import io.netty5.channel.socket.nio.NioServerSocketChannel;
import io.netty5.handler.codec.http.DefaultFullHttpResponse;
@@ -72,14 +76,15 @@ import io.netty5.util.concurrent.FutureListener;
* Base Server implementation used to create Netty based server implementations for
* unit testing aspects of the client code.
*/
-public abstract class NettyServer implements AutoCloseable {
+public final class Netty5Server implements NettyServer {
- private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
static final int PORT = Integer.parseInt(System.getProperty("port", "5672"));
static final String WEBSOCKET_PATH = "/";
static final int DEFAULT_MAX_FRAME_SIZE = 65535;
+ private Netty5EventLoop eventLoop;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel serverChannel;
@@ -93,31 +98,46 @@ public abstract class NettyServer implements AutoCloseable {
private final AtomicBoolean started = new AtomicBoolean();
- public NettyServer(ProtonTestServerOptions options) {
+ private final Consumer<ByteBuffer> inputConsumer;
+ private final Runnable connectedRunnable;
+
+ public Netty5Server(ProtonTestServerOptions options, Runnable connectedRunnable, Consumer<ByteBuffer> inputConsumer) {
+ Objects.requireNonNull(options);
+ Objects.requireNonNull(inputConsumer);
+ Objects.requireNonNull(connectedRunnable);
+
this.options = options;
+ this.connectedRunnable = connectedRunnable;
+ this.inputConsumer = inputConsumer;
}
+ @Override
public boolean isSecureServer() {
return options.isSecure();
}
+ @Override
public boolean isAcceptingConnections() {
return serverChannel != null && serverChannel.isOpen();
}
+ @Override
public boolean hasSecureConnection() {
return sslHandler != null;
}
+ @Override
public boolean hasClientConnection() {
return clientChannel != null && clientChannel.isOpen();
}
+ @Override
public int getClientPort() {
Objects.requireNonNull(clientChannel);
return (((InetSocketAddress) clientChannel.remoteAddress()).getPort());
}
+ @Override
public boolean isPeerVerified() {
try {
if (hasSecureConnection()) {
@@ -130,6 +150,7 @@ public abstract class NettyServer implements AutoCloseable {
}
}
+ @Override
public SSLEngine getConnectionSSLEngine() {
if (hasSecureConnection()) {
return sslHandler.engine();
@@ -138,22 +159,27 @@ public abstract class NettyServer implements AutoCloseable {
}
}
+ @Override
public boolean isWebSocketServer() {
return options.isUseWebSockets();
}
+ @Override
public String getWebSocketPath() {
return webSocketPath;
}
+ @Override
public void setWebSocketPath(String webSocketPath) {
this.webSocketPath = webSocketPath;
}
+ @Override
public int getMaxFrameSize() {
return maxFrameSize;
}
+ @Override
public void setMaxFrameSize(int maxFrameSize) {
this.maxFrameSize = maxFrameSize;
}
@@ -166,6 +192,7 @@ public abstract class NettyServer implements AutoCloseable {
return handshakeComplete;
}
+ @Override
public URI getConnectionURI(String queryString) throws Exception {
if (!started.get()) {
throw new IllegalStateException("Cannot get URI of non-started server");
@@ -203,6 +230,7 @@ public abstract class NettyServer implements AutoCloseable {
return new URI(scheme, null, "localhost", port, path, queryString, null);
}
+ @Override
public void start() throws Exception {
if (started.compareAndSet(false, true)) {
// Configure the server to basic NIO type channels
@@ -222,6 +250,7 @@ public abstract class NettyServer implements AutoCloseable {
serverChannel.close();
// Now we know who the client is
clientChannel = ch;
+ eventLoop = new Netty5EventLoop(ch.executor());
if (isSecureServer()) {
ch.pipeline().addLast(sslHandler = SslSupport.createServerSslHandler(null, options));
@@ -246,8 +275,33 @@ public abstract class NettyServer implements AutoCloseable {
}
}
- protected abstract ChannelHandler getServerHandler();
+ protected ChannelHandler getServerHandler() {
+ return new SimpleChannelInboundHandler<Buffer>() {
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectedRunnable.run();
+ ctx.fireChannelActive();
+ }
+
+ @Override
+ protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
+ LOG.trace("AMQP Test Server Channel read: {}", input);
+
+ // Driver processes new data and may produce output based on this.
+ try {
+ final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
+ input.readBytes(copy);
+ inputConsumer.accept(copy.flip().asReadOnlyBuffer());
+ } catch (Throwable e) {
+ LOG.error("Closed AMQP Test server channel due to error: ", e);
+ ctx.channel().close();
+ }
+ }
+ };
+ }
+ @Override
public void write(ByteBuffer frame) {
if (clientChannel == null || !clientChannel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
@@ -256,14 +310,16 @@ public abstract class NettyServer implements AutoCloseable {
clientChannel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(frame).makeReadOnly());
}
- public EventLoop eventLoop() {
+ @Override
+ public NettyEventLoop eventLoop() {
if (clientChannel == null || !clientChannel.isActive()) {
throw new IllegalStateException("Channel is not connected or has closed");
}
- return clientChannel.executor();
+ return eventLoop;
}
+ @Override
public void stop() throws InterruptedException {
if (started.compareAndSet(true, false)) {
LOG.info("Syncing channel close");
@@ -292,6 +348,7 @@ public abstract class NettyServer implements AutoCloseable {
}
}
+ @Override
public void stopAsync() throws InterruptedException {
if (started.compareAndSet(true, false)) {
LOG.info("Closing channel asynchronously");
@@ -316,6 +373,7 @@ public abstract class NettyServer implements AutoCloseable {
stop();
}
+ @Override
public int getServerPort() {
if (!started.get()) {
throw new IllegalStateException("Cannot get server port of non-started server");
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java
similarity index 52%
copy from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
copy to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java
index 675c9da4..776744fd 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java
@@ -14,37 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty5.buffer.Buffer;
+package org.apache.qpid.protonj2.test.driver.netty.netty5;
-class NullElement extends AtomicElement<Void> {
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
- NullElement(Element<?> parent, Element<?> prev) {
- super(parent, prev);
- }
+import io.netty5.buffer.BufferAllocator;
- @Override
- public int size() {
- return isElementOfArray() ? 0 : 1;
- }
+/**
+ * Support class used to detect if Netty 5 is available on the class path.
+ */
+public final class Netty5Support {
- @Override
- public Void getValue() {
- return null;
- }
+ private static final Logger LOG = LoggerFactory.getLogger(Netty5Support.class);
- @Override
- public Codec.DataType getDataType() {
- return Codec.DataType.NULL;
+ private static final Throwable UNAVAILABILITY_CAUSE;
+ static {
+ Throwable cause = null;
+ try {
+ BufferAllocator.onHeapUnpooled();
+ } catch (Throwable ex) {
+ LOG.debug("Netty 5 not available for use.");
+ cause = ex;
+ }
+
+ UNAVAILABILITY_CAUSE = cause;
}
- @Override
- public int encode(Buffer buffer) {
- if (buffer.writableBytes() > 0 && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public static final boolean isAvailable() {
+ return UNAVAILABILITY_CAUSE == null;
}
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java
similarity index 98%
rename from protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java
rename to protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java
index 256122ee..5fbdcae2 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/SslSupport.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java
@@ -14,11 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.test.driver.netty;
+package org.apache.qpid.protonj2.test.driver.netty.netty5;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -38,6 +39,7 @@ import javax.net.ssl.X509ExtendedKeyManager;
import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
+import org.apache.qpid.protonj2.test.driver.netty.X509AliasKeyManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,7 +51,7 @@ import io.netty5.handler.ssl.util.InsecureTrustManagerFactory;
*/
public class SslSupport {
- private static final Logger LOG = LoggerFactory.getLogger(SslSupport.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
/**
* Creates a Netty SslHandler instance for use in client instances that require
diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/codec/benchmark/Benchmark.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/codec/benchmark/Benchmark.java
index 3747fc1d..868c3556 100644
--- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/codec/benchmark/Benchmark.java
+++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/codec/benchmark/Benchmark.java
@@ -20,8 +20,10 @@
*/
package org.apache.qpid.protonj2.codec.benchmark;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;
@@ -44,14 +46,11 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Role;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
public class Benchmark implements Runnable {
private static final int ITERATIONS = 10 * 1024 * 1024;
- private Buffer buffer = BufferAllocator.onHeapUnpooled().allocate(8192);
+ private ByteArrayOutputStream output = new ByteArrayOutputStream(8192);
private BenchmarkResult resultSet = new BenchmarkResult();
private boolean warming = true;
@@ -105,16 +104,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putJavaList(list);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -128,16 +129,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putUUID(uuid);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -154,16 +157,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(transfer);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -184,16 +189,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(flow);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -209,16 +216,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(header);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -236,16 +245,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(properties);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -262,16 +273,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(annotations);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -288,16 +301,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(properties);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -313,18 +328,20 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putSymbol(symbol1);
codec.putSymbol(symbol2);
codec.putSymbol(symbol3);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -340,18 +357,20 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putString(string1);
codec.putString(string2);
codec.putString(string3);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.decode(buffer);
codec.decode(buffer);
@@ -372,16 +391,18 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(disposition);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
@@ -397,18 +418,20 @@ public class Benchmark implements Runnable {
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.resetOffsets();
+ output.reset();
codec.putDescribedType(data1);
codec.putDescribedType(data2);
codec.putDescribedType(data3);
- codec.encode(buffer);
+ codec.encode(output);
codec.clear();
}
resultSet.encodesComplete();
+ final ByteBuffer buffer = ByteBuffer.wrap(output.toByteArray()).asReadOnlyBuffer();
+
resultSet.start();
for (int i = 0; i < ITERATIONS; i++) {
- buffer.readerOffset(0);
+ buffer.position(0);
codec.decode(buffer);
codec.clear();
}
diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/codec/DataImplTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/codec/DataImplTest.java
index e3f3bf8f..c20d2a0f 100644
--- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/codec/DataImplTest.java
+++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/codec/DataImplTest.java
@@ -21,7 +21,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -39,9 +43,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.Role;
import org.apache.qpid.protonj2.test.driver.codec.transport.SenderSettleMode;
import org.junit.jupiter.api.Test;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
/**
* Test some basic operations of the Data type codec
*/
@@ -55,8 +56,8 @@ public class DataImplTest {
open.setContainerId("test");
open.setHostname("localhost");
- Buffer encoded = encodeProtonPerformative(open);
- int expectedRead = encoded.readableBytes();
+ ByteBuffer encoded = encodeProtonPerformative(open);
+ int expectedRead = encoded.remaining();
Codec codec = Codec.Factory.create();
@@ -79,8 +80,16 @@ public class DataImplTest {
Codec codec = Codec.Factory.create();
codec.putDescribedType(open);
- Buffer encoded = BufferAllocator.onHeapUnpooled().allocate((int) codec.encodedSize());
- codec.encode(encoded);
+ final long encodedSizeEstimate = codec.encodedSize();
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
+ final DataOutputStream output = new DataOutputStream(baos);
+
+ codec.encode(output);
+
+ final ByteBuffer encoded = ByteBuffer.wrap(baos.toByteArray());
+
+ assertEquals(encodedSizeEstimate, encoded.remaining());
DescribedType decoded = decodeProtonPerformative(encoded);
assertNotNull(decoded);
@@ -97,8 +106,8 @@ public class DataImplTest {
begin.setHandleMax(UnsignedInteger.valueOf(512));
begin.setRemoteChannel(UnsignedShort.valueOf(1));
- Buffer encoded = encodeProtonPerformative(begin);
- int expectedRead = encoded.readableBytes();
+ ByteBuffer encoded = encodeProtonPerformative(begin);
+ int expectedRead = encoded.remaining();
Codec codec = Codec.Factory.create();
@@ -124,8 +133,13 @@ public class DataImplTest {
Codec codec = Codec.Factory.create();
codec.putDescribedType(begin);
- try (Buffer encoded = BufferAllocator.onHeapUnpooled().allocate((int) codec.encodedSize())) {
- codec.encode(encoded);
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream((int) codec.encodedSize());
+ DataOutputStream output = new DataOutputStream(baos)) {
+
+ codec.encode(output);
+
+ final ByteBuffer encoded = ByteBuffer.wrap(baos.toByteArray());
DescribedType decoded = decodeProtonPerformative(encoded);
assertNotNull(decoded);
@@ -148,20 +162,19 @@ public class DataImplTest {
attach.setSource(new Source());
attach.setTarget(new Target());
- try (Buffer encoded = encodeProtonPerformative(attach)) {
- final int expectedRead = encoded.readableBytes();
+ final ByteBuffer encoded = encodeProtonPerformative(attach);
+ final int expectedRead = encoded.remaining();
- Codec codec = Codec.Factory.create();
+ Codec codec = Codec.Factory.create();
- assertEquals(expectedRead, codec.decode(encoded));
+ assertEquals(expectedRead, codec.decode(encoded));
- Attach described = (Attach) codec.getDescribedType();
- assertNotNull(described);
- assertEquals(Attach.DESCRIPTOR_SYMBOL, described.getDescriptor());
+ Attach described = (Attach) codec.getDescribedType();
+ assertNotNull(described);
+ assertEquals(Attach.DESCRIPTOR_SYMBOL, described.getDescriptor());
- assertEquals(described.getHandle(), UnsignedInteger.valueOf(1));
- assertEquals(described.getName(), "test");
- }
+ assertEquals(described.getHandle(), UnsignedInteger.valueOf(1));
+ assertEquals(described.getName(), "test");
}
@Test
@@ -178,8 +191,13 @@ public class DataImplTest {
Codec codec = Codec.Factory.create();
codec.putDescribedType(attach);
- try (Buffer encoded = BufferAllocator.onHeapUnpooled().allocate((int) codec.encodedSize())) {
- codec.encode(encoded);
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream((int) codec.encodedSize());
+ DataOutputStream output = new DataOutputStream(baos)) {
+
+ codec.encode(output);
+
+ final ByteBuffer encoded = ByteBuffer.wrap(baos.toByteArray());
DescribedType decoded = decodeProtonPerformative(encoded);
assertNotNull(decoded);
@@ -206,13 +224,13 @@ public class DataImplTest {
2, -95, 12, 113, 117, 101, 117, 101, 45, 112, 114, 101, 102, 105,
120, -95, 8, 113, 117, 101, 117, 101, 58, 47, 47};
- Buffer encoded = BufferAllocator.onHeapUnpooled().copyOf(completeOpen);
+ final ByteBuffer encoded = ByteBuffer.wrap(completeOpen);
DescribedType decoded = decodeProtonPerformative(encoded);
assertNotNull(decoded);
assertTrue(decoded instanceof Open);
- Open performative = (Open) decoded;
+ final Open performative = (Open) decoded;
assertEquals("container", performative.getContainerId());
assertEquals("localhost", performative.getHostname());
@@ -232,7 +250,7 @@ public class DataImplTest {
assertEquals(expected, performative.getProperties());
}
- private DescribedType decodeProtonPerformative(Buffer buffer) throws IOException {
+ private DescribedType decodeProtonPerformative(ByteBuffer buffer) throws IOException {
DescribedType performative = null;
try {
@@ -256,18 +274,20 @@ public class DataImplTest {
return performative;
}
- private Buffer encodeProtonPerformative(DescribedType performative) {
- Buffer buffer = BufferAllocator.onHeapPooled().allocate(256);
+ private ByteBuffer encodeProtonPerformative(DescribedType performative) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
if (performative != null) {
- try {
+ try (DataOutputStream output = new DataOutputStream(baos)) {
codec.putDescribedType(performative);
- codec.encode(buffer);
+ codec.encode(output);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
} finally {
codec.clear();
}
}
- return buffer;
+ return ByteBuffer.wrap(baos.toByteArray());
}
}
diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/legacy/LegacyCodecTransferFramesTestDataGenerator.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/legacy/LegacyCodecTransferFramesTestDataGenerator.java
index 67e0dc03..83759208 100644
--- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/legacy/LegacyCodecTransferFramesTestDataGenerator.java
+++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/legacy/LegacyCodecTransferFramesTestDataGenerator.java
@@ -21,9 +21,11 @@ import java.util.HashMap;
import java.util.UUID;
import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.UnsignedByte;
import org.apache.qpid.proton.amqp.UnsignedInteger;
import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.amqp.messaging.Header;
import org.apache.qpid.proton.amqp.transport.Transfer;
import org.apache.qpid.proton.codec.ReadableBuffer;
import org.apache.qpid.proton.codec.WritableBuffer;
@@ -46,11 +48,14 @@ public class LegacyCodecTransferFramesTestDataGenerator {
completedTransfer.setMessageFormat(null);
completedTransfer.setSettled(true);
- String emptyOpenFrameString = LegacyFrameDataGenerator.generateUnitTestVariable("completedTransfer", completedTransfer, encodeMessage());
- System.out.println(emptyOpenFrameString);
+ String encodedMessageOne = LegacyFrameDataGenerator.generateUnitTestVariable("completedTransfer1", completedTransfer, encodeMessage1());
+ System.out.println(encodedMessageOne);
+
+ String encodedMessageTwo = LegacyFrameDataGenerator.generateUnitTestVariable("completedTransfer2", completedTransfer, encodeMessage2());
+ System.out.println(encodedMessageTwo);
}
- private static ReadableBuffer encodeMessage() {
+ private static ReadableBuffer encodeMessage1() {
final WritableBuffer.ByteBufferWrapper buffer = WritableBuffer.ByteBufferWrapper.allocate(1024);
final byte[] body = new byte[100];
Arrays.fill(body, (byte) 'A');
@@ -69,4 +74,25 @@ public class LegacyCodecTransferFramesTestDataGenerator {
return buffer.toReadableBuffer();
}
+
+ private static ReadableBuffer encodeMessage2() {
+ final WritableBuffer.ByteBufferWrapper buffer = WritableBuffer.ByteBufferWrapper.allocate(1024);
+ final byte[] body = new byte[] { 0, 1, 2, 3 };
+
+ Header header = new Header();
+ header.setDurable(true);
+ header.setPriority(UnsignedByte.valueOf((byte) 2));
+ header.setTtl(UnsignedInteger.valueOf(65535));
+ header.setFirstAcquirer(true);
+ header.setDeliveryCount(UnsignedInteger.valueOf(2));
+
+ Message message = Message.Factory.create();
+
+ message.setHeader(header);
+ message.setBody(new Data(new Binary(body)));
+
+ message.encode(buffer);
+
+ return buffer.toReadableBuffer();
+ }
}
diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedCompositingDataSectionMatcherTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedCompositingDataSectionMatcherTest.java
index 5c481542..70771f71 100644
--- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedCompositingDataSectionMatcherTest.java
+++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedCompositingDataSectionMatcherTest.java
@@ -19,6 +19,7 @@ package org.apache.qpid.protonj2.test.driver.matches.types;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import java.nio.ByteBuffer;
import java.util.Random;
import org.apache.qpid.proton.codec.EncodingCodes;
@@ -26,9 +27,6 @@ import org.apache.qpid.protonj2.test.driver.codec.messaging.Data;
import org.apache.qpid.protonj2.test.driver.matchers.types.EncodedCompositingDataSectionMatcher;
import org.junit.jupiter.api.Test;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
class EncodedCompositingDataSectionMatcherTest {
@Test
@@ -39,9 +37,9 @@ class EncodedCompositingDataSectionMatcherTest {
Random bytesGenerator = new Random(SEED);
bytesGenerator.nextBytes(PAYLOAD);
- Buffer incomingBytes = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
+ ByteBuffer incomingBytes = ByteBuffer.allocate(EXPECTED_SIZE);
- incomingBytes.writeBytes(PAYLOAD);
+ incomingBytes.put(PAYLOAD).flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -61,14 +59,15 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.setSeed(SEED);
bytesGenerator.nextBytes(CHUNK);
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
+ ByteBuffer partial1 = ByteBuffer.allocate(EXPECTED_SIZE);
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(EXPECTED_SIZE);
- partial1.writeBytes(CHUNK);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(EXPECTED_SIZE);
+ partial1.put(CHUNK);
+ partial1.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -88,14 +87,15 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.setSeed(SEED + 1);
bytesGenerator.nextBytes(CHUNK);
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
+ ByteBuffer partial1 = ByteBuffer.allocate(EXPECTED_SIZE);
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(EXPECTED_SIZE);
- partial1.writeBytes(CHUNK);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(EXPECTED_SIZE);
+ partial1.put(CHUNK);
+ partial1.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -117,19 +117,21 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.nextBytes(CHUNK1);
bytesGenerator.nextBytes(CHUNK2);
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
+ final ByteBuffer partial1 = ByteBuffer.allocate(EXPECTED_SIZE);
+ final ByteBuffer partial2 = ByteBuffer.allocate(EXPECTED_SIZE);
// First half arrives with preamble
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(EXPECTED_SIZE);
- partial1.writeBytes(CHUNK1);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(EXPECTED_SIZE);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second half arrives without preamble as expected
- partial2.writeBytes(CHUNK2);
+ partial2.put(CHUNK2);
+ partial2.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -156,25 +158,29 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.nextBytes(CHUNK3);
bytesGenerator.nextBytes(CHUNK4);
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
- Buffer partial3 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
- Buffer partial4 = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE);
+ final ByteBuffer partial1 = ByteBuffer.allocate(EXPECTED_SIZE);
+ final ByteBuffer partial2 = ByteBuffer.allocate(EXPECTED_SIZE);
+ final ByteBuffer partial3 = ByteBuffer.allocate(EXPECTED_SIZE);
+ final ByteBuffer partial4 = ByteBuffer.allocate(EXPECTED_SIZE);
// First chunk arrives with preamble
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(EXPECTED_SIZE);
- partial1.writeBytes(CHUNK1);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(EXPECTED_SIZE);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second chunk arrives without preamble as expected
- partial2.writeBytes(CHUNK2);
+ partial2.put(CHUNK2);
+ partial2.flip();
// Third chunk arrives without preamble as expected
- partial3.writeBytes(CHUNK3);
+ partial3.put(CHUNK3);
+ partial3.flip();
// Fourth chunk arrives without preamble as expected
- partial4.writeBytes(CHUNK4);
+ partial4.put(CHUNK4);
+ partial4.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -184,10 +190,13 @@ class EncodedCompositingDataSectionMatcherTest {
assertThat(partial3, matcher);
assertThat(partial4, matcher);
+ final ByteBuffer partial5 = ByteBuffer.allocate(4);
+
+ partial5.put(new byte[] { 3, 3, 3, 3});
+ partial5.flip();
+
// Anything else that arrives that is handed to this matcher should fail
- try (Buffer buffer = BufferAllocator.onHeapUnpooled().allocate(4).writeBytes(new byte[] { 3, 3, 3, 3})) {
- assertFalse(matcher.matches(buffer));
- }
+ assertFalse(matcher.matches(partial5));
}
@Test
@@ -196,19 +205,21 @@ class EncodedCompositingDataSectionMatcherTest {
final byte[] CHUNK1 = new byte[] { 0, 1, 2 };
final byte[] CHUNK2 = new byte[] { 3, 4, 5, 6, 7, 8, 9 };
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(16);
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(16);
+ final ByteBuffer partial1 = ByteBuffer.allocate(16);
+ final ByteBuffer partial2 = ByteBuffer.allocate(16);
// First half arrives with preamble
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(PAYLOAD.length);
- partial1.writeBytes(CHUNK1);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(PAYLOAD.length);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second half arrives without preamble as expected
- partial2.writeBytes(CHUNK2);
+ partial2.put(CHUNK2);
+ partial2.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -232,19 +243,21 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.setSeed(SEED);
bytesGenerator.nextBytes(CHUNK2);
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(16);
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(16);
+ final ByteBuffer partial1 = ByteBuffer.allocate(256);
+ final ByteBuffer partial2 = ByteBuffer.allocate(128);
// First half arrives with preamble
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(EXPECTED_SIZE);
- partial1.writeBytes(CHUNK1);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(EXPECTED_SIZE);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second half arrives without preamble as expected
- partial2.writeBytes(CHUNK2);
+ partial2.put(CHUNK2);
+ partial2.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -266,15 +279,16 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.setSeed(SEED);
bytesGenerator.nextBytes(CHUNK);
- Buffer inboundBytes = BufferAllocator.onHeapUnpooled().allocate(16);
+ final ByteBuffer inboundBytes = ByteBuffer.allocate(512);
- inboundBytes.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- inboundBytes.writeByte(EncodingCodes.SMALLULONG);
- inboundBytes.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- inboundBytes.writeByte(EncodingCodes.VBIN32);
- inboundBytes.writeInt(EXPECTED_SIZE);
- inboundBytes.writeBytes(CHUNK);
- inboundBytes.writeBytes(EXTRA);
+ inboundBytes.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ inboundBytes.put(EncodingCodes.SMALLULONG);
+ inboundBytes.put(Data.DESCRIPTOR_CODE.byteValue());
+ inboundBytes.put(EncodingCodes.VBIN32);
+ inboundBytes.putInt(EXPECTED_SIZE);
+ inboundBytes.put(CHUNK);
+ inboundBytes.put(EXTRA);
+ inboundBytes.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -297,22 +311,24 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.nextBytes(CHUNK2);
// First half arrives with preamble
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(16);
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(CHUNK1.length);
- partial1.writeBytes(CHUNK1);
+ final ByteBuffer partial1 = ByteBuffer.allocate(256);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(CHUNK1.length);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second half arrives without preamble as expected
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(16);
- partial2.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial2.writeByte(EncodingCodes.SMALLULONG);
- partial2.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial2.writeByte(EncodingCodes.VBIN32);
- partial2.writeInt(CHUNK2.length);
- partial2.writeBytes(CHUNK2);
+ final ByteBuffer partial2 = ByteBuffer.allocate(256);
+ partial2.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial2.put(EncodingCodes.SMALLULONG);
+ partial2.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial2.put(EncodingCodes.VBIN32);
+ partial2.putInt(CHUNK2.length);
+ partial2.put(CHUNK2);
+ partial2.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
@@ -336,23 +352,25 @@ class EncodedCompositingDataSectionMatcherTest {
bytesGenerator.nextBytes(CHUNK2);
// First half arrives with preamble
- Buffer partial1 = BufferAllocator.onHeapUnpooled().allocate(16);
- partial1.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial1.writeByte(EncodingCodes.SMALLULONG);
- partial1.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial1.writeByte(EncodingCodes.VBIN32);
- partial1.writeInt(CHUNK1.length);
- partial1.writeBytes(CHUNK1);
+ final ByteBuffer partial1 = ByteBuffer.allocate(256);
+ partial1.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial1.put(EncodingCodes.SMALLULONG);
+ partial1.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial1.put(EncodingCodes.VBIN32);
+ partial1.putInt(CHUNK1.length);
+ partial1.put(CHUNK1);
+ partial1.flip();
// Second half arrives without preamble as expected
- Buffer partial2 = BufferAllocator.onHeapUnpooled().allocate(16);
- partial2.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- partial2.writeByte(EncodingCodes.SMALLULONG);
- partial2.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- partial2.writeByte(EncodingCodes.VBIN32);
- partial2.writeInt(CHUNK2.length + 1);
- partial2.writeBytes(CHUNK2);
- partial2.writeByte((byte) 64);
+ final ByteBuffer partial2 = ByteBuffer.allocate(128 + 9);
+ partial2.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ partial2.put(EncodingCodes.SMALLULONG);
+ partial2.put(Data.DESCRIPTOR_CODE.byteValue());
+ partial2.put(EncodingCodes.VBIN32);
+ partial2.putInt(CHUNK2.length + 1);
+ partial2.put(CHUNK2);
+ partial2.put((byte) 64);
+ partial2.flip();
EncodedCompositingDataSectionMatcher matcher =
new EncodedCompositingDataSectionMatcher(PAYLOAD);
diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedPartialDataSectionMatcherTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedPartialDataSectionMatcherTest.java
index b3bc1713..edb163d1 100644
--- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedPartialDataSectionMatcherTest.java
+++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matches/types/EncodedPartialDataSectionMatcherTest.java
@@ -19,15 +19,14 @@ package org.apache.qpid.protonj2.test.driver.matches.types;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.proton.codec.EncodingCodes;
import org.apache.qpid.protonj2.test.driver.codec.messaging.AmqpValue;
import org.apache.qpid.protonj2.test.driver.codec.messaging.Data;
import org.apache.qpid.protonj2.test.driver.matchers.types.EncodedPartialDataSectionMatcher;
import org.junit.jupiter.api.Test;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
public class EncodedPartialDataSectionMatcherTest {
@Test
@@ -35,19 +34,20 @@ public class EncodedPartialDataSectionMatcherTest {
final byte[] PAYLOAD = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
final int EXPECTED_SIZE = 256;
- try (Buffer body = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE)) {
- body.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- body.writeByte(EncodingCodes.SMALLULONG);
- body.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- body.writeByte(EncodingCodes.VBIN32);
- body.writeInt(EXPECTED_SIZE);
- body.writeBytes(PAYLOAD);
+ final ByteBuffer body = ByteBuffer.allocate(EXPECTED_SIZE);
- EncodedPartialDataSectionMatcher matcher =
- new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+ body.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ body.put(EncodingCodes.SMALLULONG);
+ body.put(Data.DESCRIPTOR_CODE.byteValue());
+ body.put(EncodingCodes.VBIN32);
+ body.putInt(EXPECTED_SIZE);
+ body.put(PAYLOAD);
+ body.flip();
- assertThat(body, matcher);
- }
+ EncodedPartialDataSectionMatcher matcher =
+ new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+
+ assertThat(body, matcher);
}
@Test
@@ -55,19 +55,20 @@ public class EncodedPartialDataSectionMatcherTest {
final byte[] PAYLOAD = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
final int EXPECTED_SIZE = 256;
- try (Buffer body = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE)) {
- body.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- body.writeByte(EncodingCodes.SMALLULONG);
- body.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- body.writeByte(EncodingCodes.VBIN32);
- body.writeInt(EXPECTED_SIZE + 1);
- body.writeBytes(PAYLOAD);
+ final ByteBuffer body = ByteBuffer.allocate(EXPECTED_SIZE);
+
+ body.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ body.put(EncodingCodes.SMALLULONG);
+ body.put(Data.DESCRIPTOR_CODE.byteValue());
+ body.put(EncodingCodes.VBIN32);
+ body.putInt(EXPECTED_SIZE + 1);
+ body.put(PAYLOAD);
+ body.flip();
- EncodedPartialDataSectionMatcher matcher =
- new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+ EncodedPartialDataSectionMatcher matcher =
+ new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
- assertFalse(matcher.matches(body));
- }
+ assertFalse(matcher.matches(body));
}
@Test
@@ -75,19 +76,20 @@ public class EncodedPartialDataSectionMatcherTest {
final byte[] PAYLOAD = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
final int EXPECTED_SIZE = 256;
- try (Buffer body = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE)) {
- body.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- body.writeByte(EncodingCodes.SMALLULONG);
- body.writeByte(AmqpValue.DESCRIPTOR_CODE.byteValue());
- body.writeByte(EncodingCodes.VBIN32);
- body.writeInt(EXPECTED_SIZE + 1);
- body.writeBytes(PAYLOAD);
+ final ByteBuffer body = ByteBuffer.allocate(EXPECTED_SIZE);
- EncodedPartialDataSectionMatcher matcher =
- new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+ body.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ body.put(EncodingCodes.SMALLULONG);
+ body.put(AmqpValue.DESCRIPTOR_CODE.byteValue());
+ body.put(EncodingCodes.VBIN32);
+ body.putInt(EXPECTED_SIZE + 1);
+ body.put(PAYLOAD);
+ body.flip();
- assertFalse(matcher.matches(body));
- }
+ EncodedPartialDataSectionMatcher matcher =
+ new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+
+ assertFalse(matcher.matches(body));
}
@Test
@@ -95,19 +97,20 @@ public class EncodedPartialDataSectionMatcherTest {
final byte[] PAYLOAD = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
final int EXPECTED_SIZE = 256;
- try (Buffer body = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE)) {
- body.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- body.writeByte(EncodingCodes.SMALLULONG);
- body.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- body.writeByte(EncodingCodes.SYM8);
- body.writeInt(EXPECTED_SIZE + 1);
- body.writeBytes(PAYLOAD);
+ final ByteBuffer body = ByteBuffer.allocate(EXPECTED_SIZE);
+
+ body.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ body.put(EncodingCodes.SMALLULONG);
+ body.put(Data.DESCRIPTOR_CODE.byteValue());
+ body.put(EncodingCodes.SYM8);
+ body.putInt(EXPECTED_SIZE + 1);
+ body.put(PAYLOAD);
+ body.flip();
- EncodedPartialDataSectionMatcher matcher =
- new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+ EncodedPartialDataSectionMatcher matcher =
+ new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
- assertFalse(matcher.matches(body));
- }
+ assertFalse(matcher.matches(body));
}
@Test
@@ -116,18 +119,19 @@ public class EncodedPartialDataSectionMatcherTest {
final byte[] ACTUAL_PAYLOAD = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
final int EXPECTED_SIZE = 256;
- try (Buffer body = BufferAllocator.onHeapUnpooled().allocate(EXPECTED_SIZE)) {
- body.writeByte(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
- body.writeByte(EncodingCodes.SMALLULONG);
- body.writeByte(Data.DESCRIPTOR_CODE.byteValue());
- body.writeByte(EncodingCodes.VBIN32);
- body.writeInt(EXPECTED_SIZE + 1);
- body.writeBytes(ACTUAL_PAYLOAD);
+ final ByteBuffer body = ByteBuffer.allocate(EXPECTED_SIZE);
+
+ body.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
+ body.put(EncodingCodes.SMALLULONG);
+ body.put(Data.DESCRIPTOR_CODE.byteValue());
+ body.put(EncodingCodes.VBIN32);
+ body.putInt(EXPECTED_SIZE + 1);
+ body.put(ACTUAL_PAYLOAD);
+ body.flip();
- EncodedPartialDataSectionMatcher matcher =
- new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
+ EncodedPartialDataSectionMatcher matcher =
+ new EncodedPartialDataSectionMatcher(EXPECTED_SIZE, PAYLOAD);
- assertFalse(matcher.matches(body));
- }
+ assertFalse(matcher.matches(body));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org