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 2022/12/16 22:15:03 UTC
[qpid-protonj2] branch main updated: PROTON-2661 Refactoring buffers and transports for netty 5 support
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 b90448af PROTON-2661 Refactoring buffers and transports for netty 5 support
b90448af is described below
commit b90448af196e5c9242473c754a502fb6fbe5af86
Author: Timothy Bish <ta...@gmail.com>
AuthorDate: Fri Dec 16 17:11:22 2022 -0500
PROTON-2661 Refactoring buffers and transports for netty 5 support
Changes the ProtonBuffer API to allow for compatability with both netty4
and netty5 and adds a transport in the proton client that will work with
the netty5 snapshot currently available. Other refactorings and updates
internally to support the netty5 ownershup model for buffers and the
various differences between the two.
---
pom.xml | 45 +
protonj2-client/pom.xml | 49 +-
.../qpid/protonj2/client/AdvancedMessage.java | 22 +-
.../client/futures/ProgressiveClientFuture.java | 6 +-
.../protonj2/client/impl/ClientConnection.java | 17 +-
.../qpid/protonj2/client/impl/ClientDelivery.java | 8 +-
.../qpid/protonj2/client/impl/ClientLinkType.java | 4 +-
.../qpid/protonj2/client/impl/ClientMessage.java | 7 +-
.../protonj2/client/impl/ClientMessageSupport.java | 13 +-
.../client/impl/ClientReceiverLinkType.java | 4 +-
.../qpid/protonj2/client/impl/ClientSender.java | 37 +-
.../qpid/protonj2/client/impl/ClientSession.java | 9 +-
.../protonj2/client/impl/ClientStreamDelivery.java | 48 +-
.../protonj2/client/impl/ClientStreamReceiver.java | 11 +-
.../client/impl/ClientStreamReceiverMessage.java | 11 +-
.../protonj2/client/impl/ClientStreamSender.java | 26 +-
.../client/impl/ClientStreamSenderMessage.java | 137 +-
.../qpid/protonj2/client/transport/IOContext.java | 78 +
.../transport/{ => netty4}/EpollSupport.java | 4 +-
.../transport/{ => netty4}/IOUringSupport.java | 4 +-
.../transport/{ => netty4}/KQueueSupport.java | 4 +-
.../Netty4IOContext.java} | 70 +-
.../client/transport/netty4/Netty4Support.java | 46 +-
.../client/transport/{ => netty4}/SslSupport.java | 5 +-
.../transport/{ => netty4}/TcpTransport.java | 129 +-
.../transport/{ => netty4}/WebSocketTransport.java | 7 +-
.../transport/{ => netty5}/EpollSupport.java | 17 +-
.../transport/{ => netty5}/IOUringSupport.java | 17 +-
.../transport/{ => netty5}/KQueueSupport.java | 17 +-
.../Netty5IOContext.java} | 79 +-
.../client/transport/netty5/Netty5Support.java | 46 +-
.../client/transport/{ => netty5}/SslSupport.java | 27 +-
.../transport/{ => netty5}/TcpTransport.java | 219 +-
.../transport/{ => netty5}/WebSocketTransport.java | 156 +-
.../protonj2/client/impl/ClientMessageTest.java | 11 +-
.../protonj2/client/impl/SslConnectionTest.java | 4 +-
.../client/test/ImperativeClientTestCase.java | 14 +-
.../{ => netty4}/NettyBlackHoleServer.java | 2 +-
.../transport/{ => netty4}/NettyEchoServer.java | 2 +-
.../transport/{ => netty4}/NettyIOContextTest.java | 13 +-
.../client/transport/{ => netty4}/NettyServer.java | 2 +-
.../{ => netty4}/OpenSslTransportTest.java | 3 +-
.../{ => netty4}/SecureWebSocketTransportTest.java | 3 +-
.../transport/{ => netty4}/SslSupportTest.java | 2 +-
.../transport/{ => netty4}/SslTransportTest.java | 7 +-
.../transport/{ => netty4}/TcpTransportTest.java | 143 +-
.../{ => netty4}/WebSocketTransportTest.java | 34 +-
.../{ => netty4}/X509AliasKeyManagerTest.java | 3 +-
.../{ => netty5}/NettyBlackHoleServer.java | 10 +-
.../transport/{ => netty5}/NettyEchoServer.java | 14 +-
.../transport/{ => netty5}/NettyIOContextTest.java | 12 +-
.../client/transport/{ => netty5}/NettyServer.java | 166 +-
.../{ => netty5}/OpenSslTransportTest.java | 13 +-
.../{ => netty5}/SecureWebSocketTransportTest.java | 3 +-
.../transport/{ => netty5}/SslSupportTest.java | 44 +-
.../transport/{ => netty5}/SslTransportTest.java | 15 +-
.../transport/{ => netty5}/TcpTransportTest.java | 317 +-
.../{ => netty5}/WebSocketTransportTest.java | 46 +-
.../{ => netty5}/X509AliasKeyManagerTest.java | 3 +-
.../qpid/protonj2/client/util/ExternalMessage.java | 10 +-
.../buffer/api/CompositeBufferAppendBenchmark.java | 75 +
.../buffer/api/CompositeBufferImpBenchmark.java | 194 +
.../qpid/protonj2/codec/CodecBenchmarkBase.java | 4 +-
.../messaging/ApplicationPropertiesBenchmark.java | 2 +-
.../protonj2/codec/messaging/DataBenchmark.java | 2 +-
.../codec/messaging/DispositionBenchmark.java | 2 +-
.../protonj2/codec/messaging/FlowBenchmark.java | 2 +-
.../protonj2/codec/messaging/HeaderBenchmark.java | 2 +-
.../messaging/MessageAnnotationsBenchmark.java | 2 +-
.../codec/messaging/PropertiesBenchmark.java | 2 +-
.../codec/messaging/TransferBenchmark.java | 2 +-
.../codec/primitives/ListOfIntBenchmark.java | 2 +-
.../protonj2/codec/primitives/StringBenchmark.java | 2 +-
.../protonj2/codec/primitives/SymbolBenchmark.java | 2 +-
.../protonj2/codec/primitives/UUIDBenchmark.java | 2 +-
protonj2-test-driver/pom.xml | 10 +-
.../qpid/protonj2/test/driver/AMQPTestDriver.java | 77 +-
.../qpid/protonj2/test/driver/FrameDecoder.java | 50 +-
.../qpid/protonj2/test/driver/FrameEncoder.java | 31 +-
.../qpid/protonj2/test/driver/LinkTracker.java | 4 +-
.../protonj2/test/driver/ProtonTestClient.java | 33 +-
.../protonj2/test/driver/ProtonTestServer.java | 35 +-
.../qpid/protonj2/test/driver/ReceiverTracker.java | 4 +-
.../qpid/protonj2/test/driver/ScriptedAction.java | 20 +-
.../qpid/protonj2/test/driver/SenderTracker.java | 4 +-
.../qpid/protonj2/test/driver/SessionTracker.java | 6 +-
.../actions/AbstractPerformativeInjectAction.java | 4 +-
.../driver/actions/ByteBufferInjectAction.java | 6 +-
.../test/driver/actions/RawBytesInjectAction.java | 8 +-
.../test/driver/actions/TransferInjectAction.java | 18 +-
.../test/driver/buffer/NettyReadableBuffer.java | 216 -
.../test/driver/buffer/NettyWritableBuffer.java | 129 -
.../test/driver/buffer/ReadableBuffer.java | 549 --
.../test/driver/buffer/WritableBuffer.java | 263 -
.../protonj2/test/driver/codec/ArrayElement.java | 6 +-
.../protonj2/test/driver/codec/BinaryElement.java | 6 +-
.../protonj2/test/driver/codec/BooleanElement.java | 6 +-
.../protonj2/test/driver/codec/ByteElement.java | 8 +-
.../protonj2/test/driver/codec/CharElement.java | 6 +-
.../qpid/protonj2/test/driver/codec/Codec.java | 6 +-
.../qpid/protonj2/test/driver/codec/CodecImpl.java | 8 +-
.../test/driver/codec/Decimal128Element.java | 6 +-
.../test/driver/codec/Decimal32Element.java | 6 +-
.../test/driver/codec/Decimal64Element.java | 6 +-
.../test/driver/codec/DescribedTypeElement.java | 6 +-
.../protonj2/test/driver/codec/DoubleElement.java | 6 +-
.../qpid/protonj2/test/driver/codec/Element.java | 4 +-
.../protonj2/test/driver/codec/FloatElement.java | 6 +-
.../protonj2/test/driver/codec/IntegerElement.java | 6 +-
.../protonj2/test/driver/codec/ListElement.java | 7 +-
.../protonj2/test/driver/codec/LongElement.java | 6 +-
.../protonj2/test/driver/codec/MapElement.java | 7 +-
.../protonj2/test/driver/codec/NullElement.java | 6 +-
.../protonj2/test/driver/codec/ShortElement.java | 8 +-
.../protonj2/test/driver/codec/StringElement.java | 6 +-
.../protonj2/test/driver/codec/SymbolElement.java | 6 +-
.../test/driver/codec/TimestampElement.java | 6 +-
.../protonj2/test/driver/codec/TypeDecoder.java | 295 +-
.../protonj2/test/driver/codec/UUIDElement.java | 6 +-
.../test/driver/codec/UnsignedByteElement.java | 8 +-
.../test/driver/codec/UnsignedIntegerElement.java | 6 +-
.../test/driver/codec/UnsignedLongElement.java | 6 +-
.../test/driver/codec/UnsignedShortElement.java | 8 +-
.../test/driver/codec/transport/Attach.java | 4 +-
.../test/driver/codec/transport/Begin.java | 4 +-
.../test/driver/codec/transport/Close.java | 4 +-
.../test/driver/codec/transport/Detach.java | 4 +-
.../test/driver/codec/transport/Disposition.java | 4 +-
.../protonj2/test/driver/codec/transport/End.java | 4 +-
.../protonj2/test/driver/codec/transport/Flow.java | 4 +-
.../test/driver/codec/transport/HeartBeat.java | 4 +-
.../protonj2/test/driver/codec/transport/Open.java | 4 +-
.../codec/transport/PerformativeDescribedType.java | 24 +-
.../test/driver/codec/transport/Transfer.java | 4 +-
.../driver/expectations/AMQPHeaderExpectation.java | 8 +-
.../driver/expectations/AbstractExpectation.java | 28 +-
.../driver/expectations/AttachExpectation.java | 4 +-
.../test/driver/expectations/BeginExpectation.java | 4 +-
.../test/driver/expectations/CloseExpectation.java | 4 +-
.../driver/expectations/DetachExpectation.java | 4 +-
.../expectations/DispositionExpectation.java | 4 +-
.../test/driver/expectations/EndExpectation.java | 4 +-
.../test/driver/expectations/FlowExpectation.java | 4 +-
.../test/driver/expectations/OpenExpectation.java | 4 +-
.../driver/expectations/TransferExpectation.java | 18 +-
.../messaging/AbstractMessageSectionMatcher.java | 11 +-
.../transport/TransferPayloadCompositeMatcher.java | 141 +-
.../matchers/types/EncodedAmqpTypeMatcher.java | 8 +-
.../EncodedCompositingDataSectionMatcher.java | 58 +-
.../types/EncodedPartialDataSectionMatcher.java | 52 +-
.../protonj2/test/driver/netty/NettyClient.java | 140 +-
.../protonj2/test/driver/netty/NettyServer.java | 168 +-
.../protonj2/test/driver/netty/SslSupport.java | 4 +-
.../qpid/protonj2/codec/benchmark/Benchmark.java | 54 +-
.../driver/buffer/NettyReadableBufferTest.java | 458 --
.../driver/buffer/NettyWritableBufferTest.java | 164 -
.../test/driver/buffer/WritableBufferTest.java | 273 -
.../protonj2/test/driver/codec/DataImplTest.java | 71 +-
.../EncodedCompositingDataSectionMatcherTest.java | 46 +-
.../EncodedPartialDataSectionMatcherTest.java | 114 +-
protonj2/pom.xml | 5 +
.../qpid/protonj2/buffer/ProtonAbstractBuffer.java | 736 --
.../apache/qpid/protonj2/buffer/ProtonBuffer.java | 1585 ++---
.../protonj2/buffer/ProtonBufferAccessors.java | 604 ++
.../protonj2/buffer/ProtonBufferAllocator.java | 170 +-
.../buffer/ProtonBufferClosedException.java | 51 +-
.../protonj2/buffer/ProtonBufferComponent.java | 168 +
.../buffer/ProtonBufferComponentAccessor.java | 224 +
.../protonj2/buffer/ProtonBufferInputStream.java | 43 +-
.../qpid/protonj2/buffer/ProtonBufferIterator.java | 96 +
.../protonj2/buffer/ProtonBufferOutputStream.java | 57 +-
.../buffer/ProtonBufferReadOnlyException.java | 51 +-
.../qpid/protonj2/buffer/ProtonBufferUtils.java | 938 +++
.../qpid/protonj2/buffer/ProtonByteBuffer.java | 275 -
.../protonj2/buffer/ProtonByteBufferAllocator.java | 79 -
.../qpid/protonj2/buffer/ProtonByteUtils.java | 229 -
.../protonj2/buffer/ProtonCompositeBuffer.java | 740 +-
.../protonj2/buffer/ProtonDuplicatedBuffer.java | 185 -
.../protonj2/buffer/ProtonNettyByteBuffer.java | 714 --
.../buffer/ProtonNettyByteBufferAllocator.java | 77 -
.../qpid/protonj2/buffer/ProtonNioByteBuffer.java | 262 -
.../qpid/protonj2/buffer/ProtonSlicedBuffer.java | 328 -
.../buffer/impl/ProtonByteArrayBuffer.java | 1105 +++
.../impl/ProtonByteArrayBufferAllocator.java | 123 +
.../buffer/impl/ProtonCompositeBufferImpl.java | 2224 ++++++
.../buffer/netty/Netty4ProtonBufferAllocator.java | 134 +
.../buffer/netty/Netty4ToProtonBufferAdapter.java | 1091 +++
.../buffer/netty/Netty5ProtonBufferAllocator.java | 139 +
.../buffer/netty/Netty5ToProtonBufferAdapter.java | 955 +++
.../buffer/netty/ProtonBufferToNetty5Adapter.java | 1107 +++
.../protonj2/codec/decoders/ProtonDecoder.java | 14 +-
.../codec/decoders/ProtonDecoderState.java | 15 +-
.../decoders/UnknownDescribedTypeDecoder.java | 6 +-
.../codec/decoders/messaging/DataTypeDecoder.java | 12 +-
.../decoders/messaging/HeaderTypeDecoder.java | 2 +-
.../decoders/messaging/PropertiesTypeDecoder.java | 2 +-
.../primitives/AbstractArrayTypeDecoder.java | 2 +-
.../primitives/AbstractBinaryTypeDecoder.java | 12 +-
.../primitives/AbstractListTypeDecoder.java | 2 +-
.../primitives/AbstractMapTypeDecoder.java | 2 +-
.../primitives/AbstractStringTypeDecoder.java | 2 +-
.../primitives/AbstractSymbolTypeDecoder.java | 14 +-
.../codec/decoders/primitives/ByteTypeDecoder.java | 2 +-
.../decoders/primitives/CharacterTypeDecoder.java | 2 +-
.../decoders/primitives/Decimal128TypeDecoder.java | 2 +-
.../decoders/primitives/Decimal32TypeDecoder.java | 2 +-
.../decoders/primitives/Decimal64TypeDecoder.java | 2 +-
.../decoders/primitives/DoubleTypeDecoder.java | 2 +-
.../decoders/primitives/FloatTypeDecoder.java | 2 +-
.../decoders/primitives/Integer32TypeDecoder.java | 2 +-
.../decoders/primitives/Integer8TypeDecoder.java | 2 +-
.../decoders/primitives/Long8TypeDecoder.java | 2 +-
.../codec/decoders/primitives/LongTypeDecoder.java | 2 +-
.../decoders/primitives/ShortTypeDecoder.java | 2 +-
.../decoders/primitives/TimestampTypeDecoder.java | 2 +-
.../codec/decoders/primitives/UUIDTypeDecoder.java | 2 +-
.../primitives/UnsignedByteTypeDecoder.java | 2 +-
.../primitives/UnsignedInteger32TypeDecoder.java | 2 +-
.../primitives/UnsignedInteger8TypeDecoder.java | 2 +-
.../primitives/UnsignedLong64TypeDecoder.java | 2 +-
.../primitives/UnsignedLong8TypeDecoder.java | 2 +-
.../primitives/UnsignedShortTypeDecoder.java | 2 +-
.../decoders/transport/AttachTypeDecoder.java | 4 +-
.../codec/decoders/transport/BeginTypeDecoder.java | 4 +-
.../decoders/transport/DetachTypeDecoder.java | 4 +-
.../decoders/transport/DispositionTypeDecoder.java | 4 +-
.../codec/decoders/transport/FlowTypeDecoder.java | 4 +-
.../codec/decoders/transport/OpenTypeDecoder.java | 4 +-
.../decoders/transport/TransferTypeDecoder.java | 4 +-
.../encoders/AbstractDescribedListTypeEncoder.java | 18 +-
.../encoders/AbstractDescribedMapTypeEncoder.java | 18 +-
.../encoders/AbstractPrimitiveTypeEncoder.java | 4 +-
.../codec/encoders/DeliveryTagEncoder.java | 2 +-
.../codec/encoders/ProtonEncoderState.java | 4 +-
.../messaging/AmqpSequenceTypeEncoder.java | 4 +-
.../encoders/messaging/AmqpValueTypeEncoder.java | 4 +-
.../codec/encoders/messaging/DataTypeEncoder.java | 6 +-
.../encoders/primitives/ArrayTypeEncoder.java | 8 +-
.../encoders/primitives/BinaryTypeEncoder.java | 16 +-
.../encoders/primitives/BooleanTypeEncoder.java | 18 +-
.../codec/encoders/primitives/ByteTypeEncoder.java | 12 +-
.../encoders/primitives/CharacterTypeEncoder.java | 12 +-
.../encoders/primitives/DoubleTypeEncoder.java | 12 +-
.../encoders/primitives/FloatTypeEncoder.java | 12 +-
.../encoders/primitives/IntegerTypeEncoder.java | 12 +-
.../codec/encoders/primitives/ListTypeEncoder.java | 4 +-
.../codec/encoders/primitives/LongTypeEncoder.java | 12 +-
.../codec/encoders/primitives/MapTypeEncoder.java | 4 +-
.../encoders/primitives/ShortTypeEncoder.java | 12 +-
.../encoders/primitives/StringTypeEncoder.java | 14 +-
.../encoders/primitives/SymbolTypeEncoder.java | 4 +-
.../primitives/UnsignedIntegerTypeEncoder.java | 6 +-
.../primitives/UnsignedLongTypeEncoder.java | 2 +-
.../apache/qpid/protonj2/engine/Connection.java | 15 +
.../org/apache/qpid/protonj2/engine/Engine.java | 15 +
.../org/apache/qpid/protonj2/engine/Scheduler.java | 123 +
.../protonj2/engine/impl/ProtonConnection.java | 8 +
.../qpid/protonj2/engine/impl/ProtonEngine.java | 57 +-
.../engine/impl/ProtonEngineConfiguration.java | 4 +-
.../engine/impl/ProtonFrameDecodingHandler.java | 72 +-
.../engine/impl/ProtonFrameEncodingHandler.java | 98 +-
.../engine/impl/ProtonIncomingDelivery.java | 43 +-
.../engine/impl/ProtonSequentialTagGenerator.java | 18 +-
.../engine/impl/ProtonTransactionController.java | 13 +-
.../engine/impl/ProtonTransactionManager.java | 2 +-
.../engine/impl/ProtonUuidTagGenerator.java | 10 +-
.../engine/impl/sasl/ProtonSaslClientContext.java | 7 +-
.../engine/sasl/client/AbstractMechanism.java | 4 +-
.../sasl/client/AbstractScramSHAMechanism.java | 6 +-
.../engine/sasl/client/CramMD5Mechanism.java | 12 +-
.../engine/sasl/client/PlainMechanism.java | 4 +-
.../engine/sasl/client/XOauth2Mechanism.java | 4 +-
.../apache/qpid/protonj2/engine/util/SplayMap.java | 2 +-
.../apache/qpid/protonj2/resource/Resource.java | 55 +
.../qpid/protonj2/resource/SharedResource.java | 89 +
.../org/apache/qpid/protonj2/types/Binary.java | 84 +-
.../apache/qpid/protonj2/types/DeliveryTag.java | 12 +-
.../org/apache/qpid/protonj2/types/Symbol.java | 15 +-
.../apache/qpid/protonj2/types/messaging/Data.java | 41 +-
.../qpid/protonj2/types/transport/AMQPHeader.java | 39 +-
.../qpid/protonj2/types/transport/Transfer.java | 4 +-
.../protonj2/buffer/ProtonAbstractBufferTest.java | 7184 +++++++++++++-------
.../buffer/ProtonBufferInputStreamTest.java | 40 +-
.../buffer/ProtonBufferOutputStreamTest.java | 24 +-
.../buffer/ProtonByteBufferAllocatorTest.java | 181 -
.../protonj2/buffer/ProtonByteBufferSliceTest.java | 322 -
.../qpid/protonj2/buffer/ProtonByteBufferTest.java | 399 --
.../protonj2/buffer/ProtonCompositeBufferTest.java | 2134 ------
.../buffer/ProtonDuplicatedBufferTest.java | 57 -
.../protonj2/buffer/ProtonNettyByteBufferTest.java | 645 --
.../protonj2/buffer/ProtonNioByteBufferTest.java | 139 -
.../protonj2/buffer/ProtonSlicedBufferTest.java | 62 -
.../buffer/impl/ProtonByteArrayBufferTest.java | 47 +-
.../impl/ProtonCompositeBufferAlloactor.java | 98 +
.../buffer/impl/ProtonCompositeBufferImplTest.java | 1919 ++++++
.../netty/Netty4ProtonBufferAdapterTest.java | 57 +
.../netty/Netty5ProtonBufferAdapterTest.java | 40 +-
.../buffer/netty/NettyBufferAdapterTestBase.java | 129 +
.../netty/ProtonBufferToNetty5AdapterTest.java | 1591 +++++
.../protonj2/buffer/util/ProtonTestByteBuffer.java | 89 -
.../qpid/protonj2/codec/DeliveryTagCodecTest.java | 43 +-
.../protonj2/codec/RegisteredTypeCodecTest.java | 6 +-
.../codec/UnknownDescribedTypeCodecTest.java | 28 +-
.../qpid/protonj2/codec/benchmark/Benchmark.java | 30 +-
.../protonj2/codec/decoders/ProtonDecoderTest.java | 44 +-
.../codec/decoders/ProtonStreamDecoderTest.java | 140 +-
.../protonj2/codec/encoders/ProtonEncoderTest.java | 42 +-
.../protonj2/codec/legacy/CodecToLegacyType.java | 4 +-
.../protonj2/codec/legacy/LegacyCodecAdapter.java | 9 +-
.../codec/messaging/AcceptedTypeCodecTest.java | 46 +-
.../codec/messaging/AmqpSequenceTypeCodecTest.java | 33 +-
.../codec/messaging/AmqpValueTypeCodecTest.java | 36 +-
.../ApplicationPropertiesTypeCodecTest.java | 54 +-
.../codec/messaging/DataTypeCodecTest.java | 78 +-
.../messaging/DeleteOnCloseTypeCodecTest.java | 37 +-
.../DeleteOnNoLinksOrMessagesCodecTest.java | 37 +-
.../messaging/DeleteOnNoLinksTypeCodecTest.java | 37 +-
.../messaging/DeleteOnNoMessagesTypeCodecTest.java | 37 +-
.../DeliveryAnnotationsTypeCodecTest.java | 54 +-
.../codec/messaging/FlowTypeCodecTest.java | 14 +-
.../codec/messaging/FooterTypeCodecTest.java | 58 +-
.../codec/messaging/HeaderTypeCodecTest.java | 54 +-
.../messaging/MessageAnnotationsTypeCodecTest.java | 54 +-
.../codec/messaging/ModifiedTypeCodecTest.java | 57 +-
.../codec/messaging/PropertiesTypeCodecTest.java | 47 +-
.../codec/messaging/ReceivedTypeCodecTest.java | 55 +-
.../codec/messaging/RejectedTypeCodecTest.java | 49 +-
.../codec/messaging/ReleasedTypeCodecTest.java | 37 +-
.../codec/messaging/SourceTypeCodecTest.java | 43 +-
.../codec/messaging/TargetTypeCodeTest.java | 41 +-
.../codec/primitives/ArrayTypeCodecTest.java | 191 +-
.../codec/primitives/BinaryTypeCodecTest.java | 117 +-
.../codec/primitives/BooleanTypeCodecTest.java | 178 +-
.../codec/primitives/ByteTypeCodecTest.java | 34 +-
.../codec/primitives/CharacterTypeCodecTest.java | 37 +-
.../codec/primitives/Decimal128TypeCodecTest.java | 39 +-
.../codec/primitives/Decimal32TypeCodecTest.java | 32 +-
.../codec/primitives/Decimal64TypeCodecTest.java | 33 +-
.../codec/primitives/DoubleTypeCodecTest.java | 34 +-
.../codec/primitives/FloatTypeCodecTest.java | 34 +-
.../codec/primitives/IntegerTypeCodecTest.java | 62 +-
.../codec/primitives/ListTypeCodecTest.java | 100 +-
.../codec/primitives/LongTypeCodecTest.java | 50 +-
.../codec/primitives/MapTypeCodecTest.java | 72 +-
.../codec/primitives/NullTypeCodecTest.java | 22 +-
.../codec/primitives/ShortTypeCodecTest.java | 34 +-
.../codec/primitives/StringTypeCodecTest.java | 86 +-
.../codec/primitives/SymbolTypeCodecTest.java | 82 +-
.../codec/primitives/TimestampTypeCodecTest.java | 34 +-
.../codec/primitives/UUIDTypeCodecTest.java | 56 +-
.../primitives/UnsignedByteTypeCodecTest.java | 79 +-
.../primitives/UnsignedIntegerTypeCodecTest.java | 57 +-
.../primitives/UnsignedLongTypeCodecTest.java | 95 +-
.../primitives/UnsignedShortTypeCodecTest.java | 56 +-
.../codec/security/SaslChallengeTypeCodecTest.java | 38 +-
.../codec/security/SaslInitTypeCodecTest.java | 59 +-
.../security/SaslMechanismsTypeCodecTest.java | 36 +-
.../codec/security/SaslOutcomeTypeCodecTest.java | 45 +-
.../codec/security/SaslResponseTypeCodecTest.java | 47 +-
.../transactions/CoordinatorTypeCodecTest.java | 41 +-
.../codec/transactions/DeclareTypeCodecTest.java | 36 +-
.../codec/transactions/DeclaredTypeCodecTest.java | 49 +-
.../codec/transactions/DischargeTypeCodecTest.java | 49 +-
.../TransactionStateTypeCodecTest.java | 42 +-
.../codec/transport/AttachTypeCodecTest.java | 42 +-
.../codec/transport/BeginTypeCodecTest.java | 46 +-
.../codec/transport/CloseTypeCodecTest.java | 66 +-
.../codec/transport/DetachTypeCodecTest.java | 42 +-
.../codec/transport/DispositionTypeCodecTest.java | 46 +-
.../protonj2/codec/transport/EndTypeCodecTest.java | 37 +-
.../transport/ErrorConditionTypeCodecTest.java | 36 +-
.../codec/transport/FlowTypeCodecTest.java | 38 +-
.../codec/transport/OpenTypeCodecTest.java | 56 +-
.../codec/transport/TransferTypeCodeTest.java | 49 +-
.../protonj2/codec/util/NoLocalTypeEncoder.java | 4 +-
.../protonj2/engine/ProtocolFramePoolTest.java | 6 +-
.../engine/impl/ProtonDecodeErrorTest.java | 7 +-
.../protonj2/engine/impl/ProtonEngineTest.java | 9 +-
.../engine/impl/ProtonEngineTestSupport.java | 45 +-
.../impl/ProtonFrameDecodingHandlerTest.java | 93 +-
.../impl/ProtonFrameEncodingHandlerTest.java | 18 +-
.../engine/impl/ProtonIncomingDeliveryTest.java | 64 +-
.../protonj2/engine/impl/ProtonReceiverTest.java | 20 +-
.../protonj2/engine/impl/ProtonSenderTest.java | 104 +-
.../impl/ProtonSequentialTagGeneratorTest.java | 4 +-
.../protonj2/engine/impl/ProtonSessionTest.java | 48 +-
.../impl/ProtonTransactionControllerTest.java | 30 +-
.../engine/impl/ProtonUuidTagGeneratorTest.java | 27 +-
.../client/AbstractScramSHAMechanismTestBase.java | 20 +-
.../engine/sasl/client/CramMD5MechanismTest.java | 10 +-
.../engine/sasl/client/MechanismTestBase.java | 5 +-
.../engine/sasl/client/ScramSHA1MechanismTest.java | 20 +-
.../sasl/client/ScramSHA256MechanismTest.java | 20 +-
.../sasl/client/ScramSHA512MechanismTest.java | 20 +-
.../org/apache/qpid/protonj2/types/BinaryTest.java | 7 +-
.../org/apache/qpid/protonj2/types/SymbolTest.java | 10 +-
.../qpid/protonj2/types/messaging/DataTest.java | 6 +-
.../protonj2/types/security/SaslChallengeTest.java | 3 +-
.../qpid/protonj2/types/security/SaslInitTest.java | 3 +-
.../protonj2/types/security/SaslOutcomeTest.java | 3 +-
.../protonj2/types/security/SaslResponseTest.java | 3 +-
.../protonj2/types/transport/AMQPHeaderTest.java | 31 +-
402 files changed, 24422 insertions(+), 17341 deletions(-)
diff --git a/pom.xml b/pom.xml
index 832cec68..95342f90 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,6 +48,7 @@
<hamcrest.version>2.2</hamcrest.version>
<netty.version>4.1.86.Final</netty.version>
<netty.iouring.version>0.0.16.Final</netty.iouring.version>
+ <netty5.version>5.0.0.Alpha5</netty5.version>
<netty.tcnative.version>2.0.54.Final</netty.tcnative.version>
<!-- Plugin versions -->
@@ -58,10 +59,16 @@
<surefire.runOrder>filesystem</surefire.runOrder>
<proton.trace.frames>false</proton.trace.frames>
+ <netty-scope>compile</netty-scope>
<netty-transport-native-io-uring-classifier>linux-x86_64</netty-transport-native-io-uring-classifier>
<netty-transport-native-epoll-classifier>linux-x86_64</netty-transport-native-epoll-classifier>
<netty-transport-native-kqueue-classifier>osx-x86_64</netty-transport-native-kqueue-classifier>
+ <netty5-scope>provided</netty5-scope>
+ <netty5-transport-native-io-uring-classifier>linux-x86_64</netty5-transport-native-io-uring-classifier>
+ <netty5-transport-native-epoll-classifier>linux-x86_64</netty5-transport-native-epoll-classifier>
+ <netty5-transport-native-kqueue-classifier>osx-x86_64</netty5-transport-native-kqueue-classifier>
+
<!-- surefire forked jvm arguments -->
<argLine>-Xmx2g -enableassertions ${jacoco-config}</argLine>
@@ -163,6 +170,44 @@
<version>${netty.iouring.version}</version>
<classifier>${netty-transport-native-io-uring-classifier}</classifier>
</dependency>
+ <!-- Netty 5 Dependencies-->
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-buffer</artifactId>
+ <version>${netty5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-common</artifactId>
+ <version>${netty5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-handler</artifactId>
+ <version>${netty5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-transport</artifactId>
+ <version>${netty5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-codec-http</artifactId>
+ <version>${netty5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-transport-native-epoll</artifactId>
+ <version>${netty5.version}</version>
+ <classifier>${netty-transport-native-epoll-classifier}</classifier>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-transport-native-kqueue</artifactId>
+ <version>${netty5.version}</version>
+ <classifier>${netty-transport-native-kqueue-classifier}</classifier>
+ </dependency>
<!-- Testing only Uber Jar inclusion -->
<dependency>
<groupId>io.netty</groupId>
diff --git a/protonj2-client/pom.xml b/protonj2-client/pom.xml
index 15d82d79..9d32d4f8 100644
--- a/protonj2-client/pom.xml
+++ b/protonj2-client/pom.xml
@@ -39,26 +39,37 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <!-- 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>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>${netty-transport-native-epoll-classifier}</classifier>
+ <scope>${netty-scope}</scope>
</dependency>
<dependency>
<groupId>io.netty.incubator</groupId>
@@ -70,11 +81,47 @@
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<classifier>${netty-transport-native-kqueue-classifier}</classifier>
+ <scope>${netty-scope}</scope>
</dependency>
+ <!-- Netty 5 Development dependencies -->
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
+ <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>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-transport-native-epoll</artifactId>
+ <classifier>${netty-transport-native-epoll-classifier}</classifier>
+ <scope>${netty5-scope}</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty5-transport-native-kqueue</artifactId>
+ <classifier>${netty5-transport-native-kqueue-classifier}</classifier>
+ <scope>${netty5-scope}</scope>
</dependency>
+ <!-- Test dependencies -->
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>protonj2-test-driver</artifactId>
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/AdvancedMessage.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/AdvancedMessage.java
index 13aa1033..175c854a 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/AdvancedMessage.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/AdvancedMessage.java
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.exceptions.ClientException;
import org.apache.qpid.protonj2.client.impl.ClientMessage;
import org.apache.qpid.protonj2.types.messaging.ApplicationProperties;
@@ -277,6 +278,25 @@ public interface AdvancedMessage<E> extends Message<E> {
*
* @throws ClientException if an error occurs while encoding the message data.
*/
- ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientException;
+ default ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientException {
+ return encode(deliveryAnnotations, ProtonBufferAllocator.defaultAllocator());
+ }
+
+ /**
+ * Encodes the {@link AdvancedMessage} for transmission by the client. The provided {@link DeliveryAnnotations}
+ * can be included or augmented by the {@link AdvancedMessage} implementation based on the target message format.
+ * The implementation is responsible for ensuring that the delivery annotations are treated correctly encoded into
+ * the correct location in the message.
+ *
+ * @param deliveryAnnotations
+ * A {@link Map} of delivery annotation values that were requested to be included in the transmitted message.
+ * @param allocator
+ * An allocator that should be used to create the buffer the message is encoded into.
+ *
+ * @return the encoded form of this message in a {@link ProtonBuffer} instance.
+ *
+ * @throws ClientException if an error occurs while encoding the message data.
+ */
+ ProtonBuffer encode(Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientException;
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/futures/ProgressiveClientFuture.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/futures/ProgressiveClientFuture.java
index df33ca8c..f709c4cf 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/futures/ProgressiveClientFuture.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/futures/ProgressiveClientFuture.java
@@ -31,9 +31,9 @@ public class ProgressiveClientFuture<V> extends ClientFuture<V> {
// Using a progressive wait strategy helps to avoid wait happening before
// completion and avoid using expensive thread signaling
- private static final int SPIN_COUNT = 10;
- private static final int YIELD_COUNT = 100;
- private static final int TINY_PARK_COUNT = 1000;
+ private static final int SPIN_COUNT = 15;
+ private static final int YIELD_COUNT = 150;
+ private static final int TINY_PARK_COUNT = 1500;
private static final int TINY_PARK_NANOS = 1;
private static final int SMALL_PARK_COUNT = 101_000;
private static final int SMALL_PARK_NANOS = 10_000;
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientConnection.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientConnection.java
index a1b0ce20..876b01ca 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientConnection.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientConnection.java
@@ -25,7 +25,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
@@ -63,12 +62,13 @@ import org.apache.qpid.protonj2.client.exceptions.ClientOperationTimedOutExcepti
import org.apache.qpid.protonj2.client.exceptions.ClientUnsupportedOperationException;
import org.apache.qpid.protonj2.client.futures.ClientFuture;
import org.apache.qpid.protonj2.client.futures.ClientFutureFactory;
-import org.apache.qpid.protonj2.client.transport.NettyIOContext;
+import org.apache.qpid.protonj2.client.transport.IOContext;
import org.apache.qpid.protonj2.client.transport.Transport;
import org.apache.qpid.protonj2.client.util.ReconnectLocationPool;
import org.apache.qpid.protonj2.client.util.TrackableThreadFactory;
import org.apache.qpid.protonj2.engine.Engine;
import org.apache.qpid.protonj2.engine.EngineFactory;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.apache.qpid.protonj2.engine.sasl.client.SaslAuthenticator;
import org.apache.qpid.protonj2.engine.sasl.client.SaslCredentialsProvider;
import org.apache.qpid.protonj2.engine.sasl.client.SaslMechanismSelector;
@@ -98,9 +98,9 @@ public final class ClientConnection implements Connection {
private final ClientFutureFactory futureFactory;
private final ClientSessionBuilder sessionBuilder;
private final ReconnectLocationPool reconnectPool = new ReconnectLocationPool();
- private final NettyIOContext ioContext;
+ private final IOContext ioContext;
private final String connectionId;
- private final ScheduledExecutorService executor;
+ private final Scheduler executor;
private final ThreadPoolExecutor notifications;
private Engine engine;
@@ -138,10 +138,9 @@ public final class ClientConnection implements Connection {
this.openFuture = futureFactory.createFuture();
this.closeFuture = futureFactory.createFuture();
this.sessionBuilder = new ClientSessionBuilder(this);
- this.ioContext = new NettyIOContext(options.transportOptions(),
- options.sslOptions(),
- "ClientConnection :(" + connectionId + "): I/O Thread");
- this.executor = ioContext.eventLoop();
+ this.ioContext = IOContext.create(options.transportOptions(), options.sslOptions(),
+ "ClientConnection :(" + connectionId + "): I/O Thread");
+ this.executor = ioContext.ioScheduler();
// This executor can be used for dispatching asynchronous tasks that might block or result
// in reentrant calls to this Connection that could block.
@@ -569,7 +568,7 @@ public final class ClientConnection implements Connection {
return closed > 0;
}
- ScheduledExecutorService getScheduler() {
+ Scheduler getScheduler() {
return executor;
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientDelivery.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientDelivery.java
index 0f25a50c..dcdabf45 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientDelivery.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientDelivery.java
@@ -75,7 +75,9 @@ public final class ClientDelivery extends ClientDeliverable<ClientDelivery, Clie
Message<E> message = (Message<E>) cachedMessage;
if (message == null && payload.isReadable()) {
- message = (Message<E>)(cachedMessage = ClientMessageSupport.decodeMessage(payload, this::deliveryAnnotations));
+ try (payload) {
+ message = (Message<E>)(cachedMessage = ClientMessageSupport.decodeMessage(payload, this::deliveryAnnotations));
+ }
}
return message;
@@ -88,7 +90,9 @@ public final class ClientDelivery extends ClientDeliverable<ClientDelivery, Clie
}
if (rawInputStream == null) {
- rawInputStream = new ProtonBufferInputStream(payload);
+ try (payload) {
+ rawInputStream = new ProtonBufferInputStream(payload);
+ }
}
return rawInputStream;
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientLinkType.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientLinkType.java
index 62552f18..b2155942 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientLinkType.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientLinkType.java
@@ -21,7 +21,6 @@ import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.Consumer;
@@ -39,6 +38,7 @@ import org.apache.qpid.protonj2.client.exceptions.ClientResourceRemotelyClosedEx
import org.apache.qpid.protonj2.client.futures.ClientFuture;
import org.apache.qpid.protonj2.engine.Connection;
import org.apache.qpid.protonj2.engine.Engine;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +64,7 @@ public abstract class ClientLinkType<LinkType extends Link<LinkType>,
protected ClientException failureCause;
protected final ClientSession session;
- protected final ScheduledExecutorService executor;
+ protected final Scheduler executor;
protected final String linkId;
protected final LinkOptions<?> options;
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessage.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessage.java
index 6f5df4d4..b6881d6e 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessage.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessage.java
@@ -28,6 +28,7 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.AdvancedMessage;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.exceptions.ClientException;
@@ -195,7 +196,7 @@ public final class ClientMessage<E> implements AdvancedMessage<E> {
public byte[] userId() {
byte[] copyOfUserId = null;
if (properties != null && properties.getUserId() != null) {
- copyOfUserId = properties.getUserId().arrayCopy();
+ copyOfUserId = properties.getUserId().asByteArray();
}
return copyOfUserId;
@@ -618,8 +619,8 @@ public final class ClientMessage<E> implements AdvancedMessage<E> {
}
@Override
- public ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientException {
- return ClientMessageSupport.encodeMessage(this, deliveryAnnotations);
+ public ProtonBuffer encode(Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientException {
+ return ClientMessageSupport.encodeMessage(this, deliveryAnnotations, allocator);
}
@SuppressWarnings({ "unchecked" })
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessageSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessageSupport.java
index 718d52da..6c33da53 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessageSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientMessageSupport.java
@@ -23,7 +23,6 @@ import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
import org.apache.qpid.protonj2.client.AdvancedMessage;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.exceptions.ClientException;
@@ -102,15 +101,19 @@ public abstract class ClientMessageSupport {
//----- Message Encoding
public static ProtonBuffer encodeMessage(AdvancedMessage<?> message, Map<String, Object> deliveryAnnotations) throws ClientException {
- return encodeMessage(DEFAULT_ENCODER, THREAD_LOCAL_ENCODER_STATE.get(), ProtonByteBufferAllocator.DEFAULT, message, deliveryAnnotations);
+ return encodeMessage(DEFAULT_ENCODER, THREAD_LOCAL_ENCODER_STATE.get(), ProtonBufferAllocator.defaultAllocator(), message, deliveryAnnotations);
+ }
+
+ public static ProtonBuffer encodeMessage(AdvancedMessage<?> message, Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientException {
+ return encodeMessage(DEFAULT_ENCODER, THREAD_LOCAL_ENCODER_STATE.get(), allocator, message, deliveryAnnotations);
}
public static ProtonBuffer encodeMessage(Encoder encoder, ProtonBufferAllocator allocator, AdvancedMessage<?> message, Map<String, Object> deliveryAnnotations) throws ClientException {
- return encodeMessage(encoder, encoder.newEncoderState(), ProtonByteBufferAllocator.DEFAULT, message, deliveryAnnotations);
+ return encodeMessage(encoder, encoder.newEncoderState(), allocator, message, deliveryAnnotations);
}
public static ProtonBuffer encodeMessage(Encoder encoder, EncoderState encoderState, ProtonBufferAllocator allocator, AdvancedMessage<?> message, Map<String, Object> deliveryAnnotations) throws ClientException {
- ProtonBuffer buffer = allocator.allocate(DEFAULT_BUFFER_ALLOCATION);
+ ProtonBuffer buffer = allocator.outputBuffer(DEFAULT_BUFFER_ALLOCATION);
Header header = message.header();
MessageAnnotations messageAnnotations = message.annotations();
@@ -140,7 +143,7 @@ public abstract class ClientMessageSupport {
SECTION_ENCODER.write(buffer, footer);
}
- return buffer;
+ return buffer.convertToReadOnly();
}
//----- Message Decoding
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientReceiverLinkType.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientReceiverLinkType.java
index 74fde357..3927b1b1 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientReceiverLinkType.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientReceiverLinkType.java
@@ -18,7 +18,7 @@
package org.apache.qpid.protonj2.client.impl;
import java.lang.invoke.MethodHandles;
-import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.Future;
import org.apache.qpid.protonj2.client.Link;
import org.apache.qpid.protonj2.client.LinkOptions;
@@ -42,7 +42,7 @@ public abstract class ClientReceiverLinkType<ReceiverType extends Link<ReceiverT
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
protected ClientFuture<ReceiverType> drainingFuture;
- protected ScheduledFuture<?> drainingTimeout;
+ protected Future<?> drainingTimeout;
protected Receiver protonReceiver;
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSender.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSender.java
index 15a45e39..a2df99d6 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSender.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSender.java
@@ -19,10 +19,11 @@ package org.apache.qpid.protonj2.client.impl;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
-import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.AdvancedMessage;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.Sender;
@@ -151,7 +152,7 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
private Tracker sendMessage(AdvancedMessage<?> message, Map<String, Object> deliveryAnnotations, boolean waitForCredit) throws ClientException {
final ClientFuture<Tracker> operation = session.getFutureFactory().createFuture();
- final ProtonBuffer buffer = message.encode(deliveryAnnotations);
+ final ProtonBuffer buffer = message.encode(deliveryAnnotations, ProtonBufferAllocator.defaultAllocator());
executor.execute(() -> {
if (notClosedOrFailed(operation)) {
@@ -249,7 +250,7 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
private final ClientSender sender;
private final int messageFormat;
- private ScheduledFuture<?> sendTimeout;
+ private Future<?> sendTimeout;
private OutgoingDelivery delivery;
/**
@@ -273,19 +274,19 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
}
/**
- * @return the {@link ScheduledFuture} used to determine when the send should fail if no credit available to write.
+ * @return the {@link Future} used to determine when the send should fail if no credit available to write.
*/
- public ScheduledFuture<?> sendTimeout() {
+ public Future<?> sendTimeout() {
return sendTimeout;
}
/**
- * Sets the {@link ScheduledFuture} which should be used when a send cannot be immediately performed.
+ * Sets the {@link Future} which should be used when a send cannot be immediately performed.
*
* @param sendTimeout
- * The {@link ScheduledFuture} that will fail the send if not cancelled once it has been performed.
+ * The {@link Future} that will fail the send if not cancelled once it has been performed.
*/
- public void sendTimeout(ScheduledFuture<?> sendTimeout) {
+ public void sendTimeout(Future<?> sendTimeout) {
this.sendTimeout = sendTimeout;
}
@@ -298,6 +299,8 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
sendTimeout.cancel(true);
}
+ payload.close();
+
request.complete(delivery.getLinkedResource());
return this;
@@ -308,6 +311,8 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
sendTimeout.cancel(true);
}
+ payload.close();
+
request.failed(exception);
return this;
@@ -320,14 +325,16 @@ public final class ClientSender extends ClientSenderLinkType<Sender> implements
sendTimeout = null;
}
- if (delivery != null) {
- ClientTracker tracker = delivery.getLinkedResource();
- if (tracker != null) {
- tracker.settlementFuture().complete(tracker);
+ try (payload) {
+ if (delivery != null) {
+ ClientTracker tracker = delivery.getLinkedResource();
+ if (tracker != null) {
+ tracker.settlementFuture().complete(tracker);
+ }
+ request.complete(delivery.getLinkedResource());
+ } else {
+ request.complete(sender.createNoOpTracker());
}
- request.complete(delivery.getLinkedResource());
- } else {
- request.complete(sender.createNoOpTracker());
}
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSession.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSession.java
index c38beab6..0b812597 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSession.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientSession.java
@@ -21,8 +21,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.Supplier;
@@ -46,6 +44,7 @@ import org.apache.qpid.protonj2.client.futures.ClientFuture;
import org.apache.qpid.protonj2.client.futures.ClientFutureFactory;
import org.apache.qpid.protonj2.engine.Connection;
import org.apache.qpid.protonj2.engine.Engine;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,7 +66,7 @@ public class ClientSession implements Session {
private final SessionOptions options;
private final ClientConnection connection;
- private final ScheduledExecutorService serializer;
+ private final Scheduler serializer;
private final String sessionId;
private final ClientSenderBuilder senderBuilder;
private final ClientReceiverBuilder receiverBuilder;
@@ -441,7 +440,7 @@ public class ClientSession implements Session {
return this;
}
- ScheduledExecutorService getScheduler() {
+ Scheduler getScheduler() {
return serializer;
}
@@ -457,7 +456,7 @@ public class ClientSession implements Session {
return closed > 0;
}
- ScheduledFuture<?> scheduleRequestTimeout(final AsyncResult<?> request, long timeout, Supplier<ClientException> errorSupplier) {
+ Future<?> scheduleRequestTimeout(final AsyncResult<?> request, long timeout, Supplier<ClientException> errorSupplier) {
if (timeout != INFINITE) {
return serializer.schedule(() -> request.failed(errorSupplier.get()), timeout, TimeUnit.MILLISECONDS);
} else {
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamDelivery.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamDelivery.java
index bbbfa652..80450de5 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamDelivery.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamDelivery.java
@@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
@@ -32,6 +31,7 @@ import org.apache.qpid.protonj2.client.exceptions.ClientIllegalStateException;
import org.apache.qpid.protonj2.client.exceptions.ClientResourceRemotelyClosedException;
import org.apache.qpid.protonj2.client.futures.ClientFuture;
import org.apache.qpid.protonj2.engine.IncomingDelivery;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.apache.qpid.protonj2.engine.exceptions.EngineFailedException;
import org.apache.qpid.protonj2.engine.util.StringUtils;
import org.apache.qpid.protonj2.types.messaging.Accepted;
@@ -170,15 +170,24 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
private final int INVALID_MARK = -1;
- private final ProtonCompositeBuffer buffer = new ProtonCompositeBuffer();
- private final ScheduledExecutorService executor = receiver.session().getScheduler();
+ private final ProtonCompositeBuffer buffer;
+ private final Scheduler executor = receiver.session().getScheduler();
+ private final AtomicBoolean closed = new AtomicBoolean();
private ClientFuture<Integer> readRequest;
- private AtomicBoolean closed = new AtomicBoolean();
private int markIndex = INVALID_MARK;
private int markLimit;
+ public RawDeliveryInputStream() {
+ // Create a read-only composite to receive incoming data, we don't ever need to
+ // write to this buffer so it would be an error if it weren't read-only and we
+ // expect that inbound buffers should be read-only by nature of them being inbound.
+ buffer = receiver.session().connection().getEngine().configuration()
+ .getBufferAllocator()
+ .composite().convertToReadOnly();
+ }
+
@Override
public void close() throws IOException {
markLimit = 0;
@@ -200,8 +209,11 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
}
// Clear anything that wasn't yet read and then clear any pending read request as EOF
- buffer.setIndex(buffer.capacity(), buffer.capacity());
- buffer.reclaimRead();
+ try {
+ buffer.close();
+ } catch (Exception e) {
+ // Ignore
+ }
if (readRequest != null) {
readRequest.complete(-1);
@@ -216,6 +228,10 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
LOG.debug("Ignoring error on RawInputStream close: ", error);
} finally {
super.close();
+ try {
+ buffer.close();
+ } catch (Exception e) {
+ }
}
}
}
@@ -227,14 +243,14 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
@Override
public synchronized void mark(int readlimit) {
- markIndex = buffer.getReadIndex();
+ markIndex = buffer.getReadOffset();
markLimit = readlimit;
}
@Override
public synchronized void reset() throws IOException {
if (markIndex != INVALID_MARK) {
- buffer.setReadIndex(markIndex);
+ buffer.setReadOffset(markIndex);
markIndex = INVALID_MARK;
markLimit = 0;
@@ -335,9 +351,9 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
if (buffer.isReadable()) {
if (buffer.getReadableBytes() < remaining) {
remaining -= buffer.getReadableBytes();
- buffer.skipBytes(buffer.getReadableBytes());
+ buffer.advanceReadOffset(buffer.getReadableBytes());
} else {
- buffer.skipBytes((int) remaining);
+ buffer.advanceReadOffset((int) remaining);
remaining = 0;
}
@@ -359,10 +375,16 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
}
private void tryReleaseReadBuffers() {
- if (buffer.getReadIndex() - markIndex > markLimit) {
+ if (buffer.getReadOffset() - markIndex > markLimit) {
markIndex = INVALID_MARK;
markLimit = 0;
- buffer.reclaimRead();
+ try {
+ // Split off all buffers that come before the portion the read offset
+ // is located within and close them to ensure any pooled buffers are
+ // returned to the pool and the rest are discarded.
+ buffer.splitComponentsFloor(buffer.getReadOffset()).close();;
+ } catch (Exception e) {
+ }
}
}
@@ -373,7 +395,7 @@ public final class ClientStreamDelivery extends ClientDeliverable<ClientStreamDe
} else {
// An input stream is awaiting some more incoming bytes, check to see if
// the delivery had a non-empty transfer frame and provide them.
- if (readRequest != null) {
+ if (readRequest != null && !readRequest.isComplete()) {
if (delivery.available() > 0) {
buffer.append(protonDelivery.readAll());
readRequest.complete(buffer.getReadableBytes());
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiver.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiver.java
index 067b4b88..2a78bc3e 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiver.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiver.java
@@ -22,7 +22,6 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.client.StreamDelivery;
@@ -46,9 +45,9 @@ public final class ClientStreamReceiver extends ClientReceiverLinkType<StreamRec
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private ClientFuture<StreamReceiver> drainingFuture;
- private ScheduledFuture<?> drainingTimeout;
+ private Future<?> drainingTimeout;
private final StreamReceiverOptions options;
- private final Map<ClientFuture<StreamDelivery>, ScheduledFuture<?>> receiveRequests = new LinkedHashMap<>();
+ private final Map<ClientFuture<StreamDelivery>, Future<?>> receiveRequests = new LinkedHashMap<>();
ClientStreamReceiver(ClientSession session, StreamReceiverOptions options, String receiverId, org.apache.qpid.protonj2.engine.Receiver receiver) {
super(session, receiverId, options, receiver);
@@ -87,7 +86,7 @@ public final class ClientStreamReceiver extends ClientReceiverLinkType<StreamRec
if (timeout == 0) {
receive.complete(null);
} else {
- final ScheduledFuture<?> timeoutFuture;
+ final Future<?> timeoutFuture;
if (timeout > 0) {
timeoutFuture = session.getScheduler().schedule(() -> {
@@ -212,10 +211,10 @@ public final class ClientStreamReceiver extends ClientReceiverLinkType<StreamRec
if (delivery.getLinkedResource() == null) {
// New delivery that can be sent to a waiting receive caller
if (!receiveRequests.isEmpty()) {
- Iterator<Entry<ClientFuture<StreamDelivery>, ScheduledFuture<?>>> entries =
+ Iterator<Entry<ClientFuture<StreamDelivery>, Future<?>>> entries =
receiveRequests.entrySet().iterator();
- Entry<ClientFuture<StreamDelivery>, ScheduledFuture<?>> entry = entries.next();
+ Entry<ClientFuture<StreamDelivery>, Future<?>> entry = entries.next();
if (entry.getValue() != null) {
entry.getValue().cancel(false);
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiverMessage.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiverMessage.java
index ac6a44d3..30dbd338 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiverMessage.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamReceiverMessage.java
@@ -26,6 +26,7 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.StreamReceiverMessage;
import org.apache.qpid.protonj2.client.exceptions.ClientException;
@@ -221,9 +222,11 @@ public final class ClientStreamReceiverMessage implements StreamReceiverMessage
@Override
public byte[] userId() throws ClientException {
if (properties() != null) {
- byte[] copyOfUserId = null;
- if (properties != null && properties().getUserId() != null) {
- copyOfUserId = properties().getUserId().arrayCopy();
+ final byte[] copyOfUserId;
+ if (properties != null && properties.getUserId() != null) {
+ copyOfUserId = properties().getUserId().asByteArray();
+ } else {
+ copyOfUserId = null;
}
return copyOfUserId;
@@ -650,7 +653,7 @@ public final class ClientStreamReceiverMessage implements StreamReceiverMessage
//----- AdvancedMessage encoding API implementation.
@Override
- public ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientUnsupportedOperationException {
+ public ProtonBuffer encode(Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientUnsupportedOperationException {
throw new ClientUnsupportedOperationException("Cannot encode from an StreamReceiverMessage instance.");
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSender.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSender.java
index 12700a1f..b158e072 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSender.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSender.java
@@ -19,7 +19,7 @@ package org.apache.qpid.protonj2.client.impl;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
-import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
@@ -396,7 +396,7 @@ public final class ClientStreamSender extends ClientSenderLinkType<StreamSender>
private final int messageFormat;
private boolean aborted;
- private ScheduledFuture<?> sendTimeout;
+ private Future<?> sendTimeout;
private OutgoingDelivery delivery;
/**
@@ -425,19 +425,19 @@ public final class ClientStreamSender extends ClientSenderLinkType<StreamSender>
}
/**
- * @return the {@link ScheduledFuture} used to determine when the send should fail if no credit available to write.
+ * @return the {@link Future} used to determine when the send should fail if no credit available to write.
*/
- public ScheduledFuture<?> sendTimeout() {
+ public Future<?> sendTimeout() {
return sendTimeout;
}
/**
- * Sets the {@link ScheduledFuture} which should be used when a send cannot be immediately performed.
+ * Sets the {@link Future} which should be used when a send cannot be immediately performed.
*
* @param sendTimeout
- * The {@link ScheduledFuture} that will fail the send if not cancelled once it has been performed.
+ * The {@link Future} that will fail the send if not cancelled once it has been performed.
*/
- public void sendTimeout(ScheduledFuture<?> sendTimeout) {
+ public void sendTimeout(Future<?> sendTimeout) {
this.sendTimeout = sendTimeout;
}
@@ -465,6 +465,10 @@ public final class ClientStreamSender extends ClientSenderLinkType<StreamSender>
sendTimeout = null;
}
+ if (payload != null) {
+ payload.close();
+ }
+
if (delivery != null) {
ClientTracker tracker = delivery.getLinkedResource();
if (tracker != null) {
@@ -481,6 +485,10 @@ public final class ClientStreamSender extends ClientSenderLinkType<StreamSender>
sendTimeout.cancel(true);
}
+ if (payload != null) {
+ payload.close();
+ }
+
request.complete(delivery.getLinkedResource());
return this;
@@ -491,6 +499,10 @@ public final class ClientStreamSender extends ClientSenderLinkType<StreamSender>
sendTimeout.cancel(true);
}
+ if (payload != null) {
+ payload.close();
+ }
+
request.failed(exception);
return this;
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSenderMessage.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSenderMessage.java
index 4906ea0c..2d90c67a 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSenderMessage.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/impl/ClientStreamSenderMessage.java
@@ -29,7 +29,7 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.OutputStreamOptions;
@@ -135,8 +135,9 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
private void doFlush() throws ClientException {
if (buffer != null && buffer.isReadable()) {
try {
- sender.sendMessage(this, buffer, messageFormat);
+ sender.sendMessage(this, buffer.convertToReadOnly().transfer(), messageFormat);
} finally {
+ buffer.close();
buffer = null;
}
}
@@ -149,8 +150,15 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
}
if (!aborted()) {
- currentState = StreamState.ABORTED;
- sender.abort(getProtonDelivery(), tracker);
+ try {
+ currentState = StreamState.ABORTED;
+ sender.abort(getProtonDelivery(), tracker);
+ } finally {
+ if (buffer != null) {
+ buffer.close();
+ }
+ buffer = null;
+ }
}
return this;
@@ -167,23 +175,30 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
throw new ClientIllegalStateException("Cannot complete an already aborted send context");
}
- if (!completed()) {
- // This may result in completion if the write surpasses the buffer limit but we still
- // need to check in case it does not, or if there are no footers...
- if (footer != null) {
- write(footer);
- }
+ try {
+ if (!completed()) {
+ // This may result in completion if the write surpasses the buffer limit but we still
+ // need to check in case it does not, or if there are no footers...
+ if (footer != null) {
+ write(footer);
+ }
- currentState = StreamState.COMPLETE;
+ currentState = StreamState.COMPLETE;
- // If there is buffered data we can flush and complete in one Transfer
- // frame otherwise we only need to do work if there was ever a send on
- // this context which would imply we have a Tracker and a Delivery.
- if (buffer != null && buffer.isReadable()) {
- doFlush();
- } else {
- sender.complete(getProtonDelivery(), tracker);
+ // If there is buffered data we can flush and complete in one Transfer
+ // frame otherwise we only need to do work if there was ever a send on
+ // this context which would imply we have a Tracker and a Delivery.
+ if (buffer != null && buffer.isReadable()) {
+ doFlush();
+ } else {
+ sender.complete(getProtonDelivery(), tracker);
+ }
}
+ } finally {
+ if (buffer != null) {
+ buffer.close();
+ }
+ buffer = null;
}
return this;
@@ -215,7 +230,7 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
transitionToWritableState();
- appendDataToBuffer(ClientMessageSupport.encodeSection(bodySection, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(bodySection, ProtonBufferAllocator.defaultAllocator().allocate()));
return this;
}
@@ -271,7 +286,9 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
transitionToWritableState();
- ProtonBuffer streamBuffer = ProtonByteBufferAllocator.DEFAULT.allocate(writeBufferSize, writeBufferSize);
+ final ProtonBuffer streamBuffer = ProtonBufferAllocator.defaultAllocator()
+ .allocate(writeBufferSize)
+ .implicitGrowthLimit(writeBufferSize);
if (options.bodyLength() > 0) {
return new SingularDataSectionOutputStream(options, streamBuffer);
@@ -296,7 +313,8 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
transitionToWritableState();
- return new SendContextRawBytesOutputStream(ProtonByteBufferAllocator.DEFAULT.allocate(writeBufferSize, writeBufferSize));
+ return new SendContextRawBytesOutputStream(
+ ProtonBufferAllocator.defaultAllocator().allocate(writeBufferSize).implicitGrowthLimit(writeBufferSize));
}
//----- OutputStream implementation for the Send Context
@@ -321,7 +339,7 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
public void write(int value) throws IOException {
checkClosed();
checkOutputLimitReached(1);
- streamBuffer.writeByte(value);
+ streamBuffer.writeByte((byte) value);
if (!streamBuffer.isWritable()) {
flush();
}
@@ -374,16 +392,18 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
if (closed.compareAndSet(false, true) && !completed()) {
currentState = StreamState.BODY_WRITABLE;
- if (options.bodyLength() > 0 && options.bodyLength() != bytesWritten) {
- // Limit was set but user did not write all of it so we must abort.
- try {
- abort();
- } catch (ClientException e) {
- throw new IOException(e);
+ try (streamBuffer) {
+ if (options.bodyLength() > 0 && options.bodyLength() != bytesWritten) {
+ // Limit was set but user did not write all of it so we must abort.
+ try {
+ abort();
+ } catch (ClientException e) {
+ throw new IOException(e);
+ }
+ } else {
+ // Limit not set or was set and user wrote that many bytes so we can complete.
+ doFlushPending(options.completeSendOnClose());
}
- } else {
- // Limit not set or was set and user wrote that many bytes so we can complete.
- doFlushPending(options.completeSendOnClose());
}
}
}
@@ -413,7 +433,8 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
protected void doFlushPending(boolean complete) throws IOException {
try {
if (streamBuffer.isReadable()) {
- appendDataToBuffer(streamBuffer);
+ // Send the readable portion and preserve any allocated writable space
+ appendDataToBuffer(streamBuffer.split());
}
if (complete) {
@@ -423,7 +444,11 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
}
if (!complete) {
- streamBuffer.setIndex(0, 0);
+ // Extend the buffer to the full write buffer size limit so the other
+ // stream write operations don't need to try and extend it each write.
+ streamBuffer.ensureWritable(writeBufferSize, writeBufferSize, true);
+ } else {
+ streamBuffer.close();
}
} catch (ClientException e) {
throw new IOException(e);
@@ -443,12 +468,15 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
public SingularDataSectionOutputStream(OutputStreamOptions options, ProtonBuffer buffer) throws ClientException {
super(options, buffer);
- ProtonBuffer preamble = ProtonByteBufferAllocator.DEFAULT.allocate(DATA_SECTION_HEADER_ENCODING_SIZE, DATA_SECTION_HEADER_ENCODING_SIZE);
+ ProtonBuffer preamble = ProtonBufferAllocator.defaultAllocator().allocate(DATA_SECTION_HEADER_ENCODING_SIZE)
+ .implicitGrowthLimit(DATA_SECTION_HEADER_ENCODING_SIZE);
preamble.writeBytes(DATA_SECTION_PREAMBLE);
preamble.writeInt(options.bodyLength());
- appendDataToBuffer(preamble);
+ try (preamble) {
+ appendDataToBuffer(preamble);
+ }
}
}
@@ -461,13 +489,13 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
@Override
protected void doFlushPending(boolean complete) throws IOException {
if (streamBuffer.isReadable()) {
-
- ProtonBuffer preamble = ProtonByteBufferAllocator.DEFAULT.allocate(DATA_SECTION_HEADER_ENCODING_SIZE, DATA_SECTION_HEADER_ENCODING_SIZE);
+ ProtonBuffer preamble = ProtonBufferAllocator.defaultAllocator().allocate(DATA_SECTION_HEADER_ENCODING_SIZE)
+ .implicitGrowthLimit(DATA_SECTION_HEADER_ENCODING_SIZE);
preamble.writeBytes(DATA_SECTION_PREAMBLE);
preamble.writeInt(streamBuffer.getReadableBytes());
- try {
+ try (preamble) {
appendDataToBuffer(preamble);
} catch (ClientException e) {
throw new IOException(e);
@@ -550,12 +578,11 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
@Override
public byte[] userId() {
- byte[] copyOfUserId = null;
if (properties != null && properties.getUserId() != null) {
- copyOfUserId = properties.getUserId().arrayCopy();
+ return properties.getUserId().asByteArray();
+ } else {
+ return null;
}
-
- return copyOfUserId;
}
@Override
@@ -911,23 +938,22 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
}
@Override
- public ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientException {
+ public ProtonBuffer encode(Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientException {
throw new ClientUnsupportedOperationException("StreamSenderMessage cannot be directly encoded");
}
//----- Internal API
private void appendDataToBuffer(ProtonBuffer incoming) throws ClientException {
+ incoming = Objects.requireNonNull(incoming, "Appended buffer cannot be null").convertToReadOnly();
+
if (buffer == null) {
- buffer = incoming;
+ buffer = incoming.transfer();
} else {
if (buffer instanceof ProtonCompositeBuffer) {
((ProtonCompositeBuffer) buffer).append(incoming);
} else {
- ProtonCompositeBuffer composite = new ProtonCompositeBuffer();
- composite.append(buffer).append(incoming);
-
- buffer = composite;
+ buffer = ProtonBufferAllocator.defaultAllocator().composite(new ProtonBuffer[] { buffer, incoming });
}
}
@@ -938,8 +964,9 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
if (buffer.getReadableBytes() >= writeBufferSize) {
try {
- sender.sendMessage(this, buffer, messageFormat);
+ sender.sendMessage(this, buffer.convertToReadOnly().transfer(), messageFormat);
} finally {
+ buffer.close();
buffer = null;
}
}
@@ -949,19 +976,19 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
if (currentState == StreamState.PREAMBLE) {
if (header != null) {
- appendDataToBuffer(ClientMessageSupport.encodeSection(header, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(header, ProtonBufferAllocator.defaultAllocator().allocate()));
}
if (deliveryAnnotations != null) {
- appendDataToBuffer(ClientMessageSupport.encodeSection(deliveryAnnotations, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(deliveryAnnotations, ProtonBufferAllocator.defaultAllocator().allocate()));
}
if (annotations != null) {
- appendDataToBuffer(ClientMessageSupport.encodeSection(annotations, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(annotations, ProtonBufferAllocator.defaultAllocator().allocate()));
}
if (properties != null) {
- appendDataToBuffer(ClientMessageSupport.encodeSection(properties, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(properties, ProtonBufferAllocator.defaultAllocator().allocate()));
}
if (applicationProperties != null) {
- appendDataToBuffer(ClientMessageSupport.encodeSection(applicationProperties, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(applicationProperties, ProtonBufferAllocator.defaultAllocator().allocate()));
}
currentState = StreamState.BODY_WRITABLE;
@@ -977,7 +1004,7 @@ final class ClientStreamSenderMessage implements StreamSenderMessage {
throw new ClientIllegalStateException("Cannot write a Section to an already completed send context");
}
- appendDataToBuffer(ClientMessageSupport.encodeSection(section, ProtonByteBufferAllocator.DEFAULT.allocate()));
+ appendDataToBuffer(ClientMessageSupport.encodeSection(section, ProtonBufferAllocator.defaultAllocator().allocate()));
return this;
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOContext.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOContext.java
new file mode 100644
index 00000000..22c9e52a
--- /dev/null
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOContext.java
@@ -0,0 +1,78 @@
+/*
+ * 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.client.transport;
+
+import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.netty4.Netty4IOContext;
+import org.apache.qpid.protonj2.client.transport.netty4.Netty4Support;
+import org.apache.qpid.protonj2.client.transport.netty5.Netty5IOContext;
+import org.apache.qpid.protonj2.client.transport.netty5.Netty5Support;
+import org.apache.qpid.protonj2.engine.Scheduler;
+
+/**
+ * An I/O context used to abstract the implementation of the IO layer in use.
+ */
+public interface IOContext {
+
+ /**
+ * Shutdown the event loop synchronously with a grace period for work that might be in-bound
+ * at the time of termination. This is not safe to call from inside the event loop as it blocks
+ * until the shutdown has completed.
+ */
+ void shutdown();
+
+ /**
+ * Shutdown the event loop asynchronously with a grace period for work that might be in-bound
+ * at the time of termination. This is safe to call from inside the event loop where the
+ * standard blocking shutdown API is not.
+ */
+ void shutdownAsync();
+
+ /**
+ * @return the single threaded IO work scheduler for this {@link IOContext}
+ */
+ Scheduler ioScheduler();
+
+ /**
+ * @return a new {@link Transport} instance that is tied to this {@link IOContext}
+ */
+ Transport newTransport();
+
+ /**
+ * Create an IOContext from the available options.
+ *
+ * @param options
+ * The {@link TransportOptions} that configure the IO Transport the context creates.
+ * @param sslOptions
+ * The {@link SslOptions} that configure the SSL layer of the IO Transport the context creates.
+ * @param ioThreadName
+ * The name to given the single IO Thread the context must provide.
+ *
+ * @return a new {@link IOContext} from available options.
+ */
+ static IOContext create(TransportOptions options, SslOptions sslOptions, String ioThreadName) {
+ if (Netty4Support.isAvailable()) {
+ return new Netty4IOContext(options, sslOptions, ioThreadName);
+ } else if (Netty5Support.isAvailable()) {
+ return new Netty5IOContext(options, sslOptions, ioThreadName);
+ }
+
+ throw new UnsupportedOperationException("Netty not available on the class path");
+ }
+}
\ No newline at end of file
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/EpollSupport.java
similarity index 95%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/EpollSupport.java
index 14e9e980..7f815c0b 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/EpollSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.util.concurrent.ThreadFactory;
@@ -28,7 +28,7 @@ import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollSocketChannel;
-public class EpollSupport {
+public final class EpollSupport {
private static final Logger LOG = LoggerFactory.getLogger(EpollSupport.class);
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/IOUringSupport.java
similarity index 95%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/IOUringSupport.java
index 5ddd8fff..bc33dc85 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/IOUringSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.util.concurrent.ThreadFactory;
@@ -28,7 +28,7 @@ import io.netty.incubator.channel.uring.IOUring;
import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
import io.netty.incubator.channel.uring.IOUringSocketChannel;
-public class IOUringSupport {
+public final class IOUringSupport {
private static final Logger LOG = LoggerFactory.getLogger(IOUringSupport.class);
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/KQueueSupport.java
similarity index 95%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/KQueueSupport.java
index 38354d09..287da94d 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/KQueueSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.util.concurrent.ThreadFactory;
@@ -28,7 +28,7 @@ import io.netty.channel.kqueue.KQueue;
import io.netty.channel.kqueue.KQueueEventLoopGroup;
import io.netty.channel.kqueue.KQueueSocketChannel;
-public class KQueueSupport {
+public final class KQueueSupport {
private static final Logger LOG = LoggerFactory.getLogger(KQueueSupport.class);
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/Netty4IOContext.java
similarity index 71%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/Netty4IOContext.java
index 18de96e9..c1b87797 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/Netty4IOContext.java
@@ -14,15 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.util.Objects;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.IOContext;
import org.apache.qpid.protonj2.client.util.TrackableThreadFactory;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,27 +35,27 @@ import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.util.concurrent.Future;
/**
* Builder of Transport instances that will validate the build options and produce a
* correctly configured transport based on the options set.
*/
-public final class NettyIOContext {
+public final class Netty4IOContext implements IOContext {
- private static final Logger LOG = LoggerFactory.getLogger(NettyIOContext.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Netty4IOContext.class);
private static final int SHUTDOWN_TIMEOUT = 50;
private static final int ASYNC_SHUTDOWN_TIMEOUT = 100;
private static final int ASYNC_SHUTDOWN_QUIET_PERIOD = 10;
private final EventLoopGroup group;
+ private final NettyIOScheduler scheduler = new NettyIOScheduler();
private final Class<? extends Channel> channelClass;
private final TransportOptions options;
private final SslOptions sslOptions;
private final ThreadFactory threadFactory;
- public NettyIOContext(TransportOptions options, SslOptions ssl, String ioThreadName) {
+ public Netty4IOContext(TransportOptions options, SslOptions ssl, String ioThreadName) {
Objects.requireNonNull(options, "Transport Options cannot be null");
Objects.requireNonNull(ssl, "Transport SSL Options cannot be null");
@@ -104,30 +108,33 @@ public final class NettyIOContext {
this.channelClass = selectedChannelClass;
}
+ @Override
public void shutdown() {
if (!group.isShutdown()) {
- Future<?> fut = group.shutdownGracefully(0, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
- if (!fut.awaitUninterruptibly(2 * SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
- LOG.trace("Connection IO Event Loop shutdown failed to complete in allotted time");
+ group.shutdownGracefully(0, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
+ try {
+ if (!group.awaitTermination(2 * SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ LOG.trace("Connection IO Event Loop shutdown failed to complete in allotted time");
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
}
}
- /**
- * Shutdown the event loop asynchronously with a grace period for work that might be in-bound
- * at the time of termination. This is safe to call from inside the event loop where the
- * standard blocking shutdown API is not.
- */
+ @Override
public void shutdownAsync() {
if (!group.isShutdown()) {
group.shutdownGracefully(ASYNC_SHUTDOWN_QUIET_PERIOD, ASYNC_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
}
}
- public EventLoopGroup eventLoop() {
- return group;
+ @Override
+ public Scheduler ioScheduler() {
+ return scheduler;
}
+ @Override
public TcpTransport newTransport() {
if (group.isShutdown() || group.isShuttingDown() || group.isTerminated()) {
throw new IllegalStateException("Cannot create a Transport from a shutdown IO context");
@@ -145,4 +152,37 @@ public final class NettyIOContext {
return transport;
}
+
+ public class NettyIOScheduler implements Scheduler, Executor {
+
+ @Override
+ public void execute(Runnable command) {
+ group.execute(command);
+ }
+
+ @Override
+ public java.util.concurrent.Future<?> schedule(Runnable command, long delay, TimeUnit unit) {
+ return group.schedule(command, delay, unit);
+ }
+
+ @Override
+ public <V> java.util.concurrent.Future<V> schedule(Callable<V> task, long delay, TimeUnit unit) {
+ return group.schedule(task, delay, unit);
+ }
+
+ @Override
+ public java.util.concurrent.Future<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
+ return group.scheduleAtFixedRate(command, initialDelay, period, unit);
+ }
+
+ @Override
+ public java.util.concurrent.Future<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
+ return group.scheduleWithFixedDelay(command, initialDelay, delay, unit);
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return group.isShutdown();
+ }
+ }
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/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-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/Netty4Support.java
index 557a3fde..8d96b9d9 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/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.netty.buffer.ByteBuf;
+package org.apache.qpid.protonj2.client.transport.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(ByteBuf buffer) {
- if (buffer.isWritable() && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public static final boolean isAvailable() {
+ return UNAVAILABILITY_CAUSE == null;
}
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupport.java
similarity index 99%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupport.java
index 7a2c422f..5dd5c23d 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.io.File;
import java.io.FileInputStream;
@@ -36,6 +36,7 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.X509AliasKeyManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +52,7 @@ import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
/**
* Static class that provides various utility methods used by Transport implementations.
*/
-public class SslSupport {
+public final class SslSupport {
private static final Logger LOG = LoggerFactory.getLogger(SslSupport.class);
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransport.java
similarity index 80%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransport.java
index 119467cf..a21f06e6 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.io.IOException;
import java.net.URI;
@@ -25,10 +25,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonBufferComponent;
+import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
+import org.apache.qpid.protonj2.buffer.netty.Netty4ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.netty.Netty4ToProtonBufferAdapter;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
+import org.apache.qpid.protonj2.client.transport.TransportListener;
import org.apache.qpid.protonj2.client.util.IOExceptionSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,6 +46,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelPromise;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.logging.LoggingHandler;
@@ -69,6 +74,7 @@ public class TcpTransport implements Transport {
protected String host;
protected int port;
protected TransportListener listener;
+ protected Netty4ProtonBufferAllocator nettyAllocator;
/**
* Create a new {@link TcpTransport} instance with the given configuration.
@@ -133,6 +139,8 @@ public class TcpTransport implements Transport {
@Override
public void initChannel(Channel transportChannel) throws Exception {
channel = transportChannel;
+ nettyAllocator = new Netty4ProtonBufferAllocator(channel.alloc());
+
configureChannel(transportChannel);
try {
listener.transportInitialized(TcpTransport.this);
@@ -196,18 +204,7 @@ public class TcpTransport implements Transport {
@Override
public ProtonBufferAllocator getBufferAllocator() {
- return new ProtonNettyByteBufferAllocator() {
-
- @Override
- public ProtonBuffer outputBuffer(int initialCapacity) {
- return new ProtonNettyByteBuffer(channel.alloc().ioBuffer(initialCapacity));
- }
-
- @Override
- public ProtonBuffer outputBuffer(int initialCapacity, int maximumCapacity) {
- return new ProtonNettyByteBuffer(channel.alloc().ioBuffer(initialCapacity, maximumCapacity));
- }
- };
+ return nettyAllocator;
}
@Override
@@ -219,10 +216,12 @@ public class TcpTransport implements Transport {
public TcpTransport write(ProtonBuffer output, Runnable onComplete) throws IOException {
checkConnected(output);
LOG.trace("Attempted write of buffer: {}", output);
+ final ChannelPromise promise;
+
if (onComplete == null) {
- channel.write(toOutputBuffer(output), channel.voidPromise());
+ promise = channel.voidPromise();
} else {
- channel.write(toOutputBuffer(output), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
+ promise = channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
@@ -230,9 +229,10 @@ public class TcpTransport implements Transport {
onComplete.run();
}
}
- }));
+ });
}
- return this;
+
+ return writeOutputBuffer(output, false, promise);
}
@Override
@@ -244,10 +244,12 @@ public class TcpTransport implements Transport {
public TcpTransport writeAndFlush(ProtonBuffer output, Runnable onComplete) throws IOException {
checkConnected(output);
LOG.trace("Attempted write and flush of buffer: {}", output);
+ final ChannelPromise promise;
+
if (onComplete == null) {
- channel.writeAndFlush(toOutputBuffer(output), channel.voidPromise());
+ promise = channel.voidPromise();
} else {
- channel.writeAndFlush(toOutputBuffer(output), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
+ promise = channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
@@ -255,9 +257,10 @@ public class TcpTransport implements Transport {
onComplete.run();
}
}
- }));
+ });
}
- return this;
+
+ return writeOutputBuffer(output, true, promise);
}
@Override
@@ -298,17 +301,54 @@ public class TcpTransport implements Transport {
protected final ByteBuf toOutputBuffer(final ProtonBuffer output) throws IOException {
final ByteBuf nettyBuf;
- if (output instanceof ProtonNettyByteBuffer) {
- nettyBuf = (ByteBuf) output.unwrap();
+ if (output instanceof Netty4ToProtonBufferAdapter) {
+ nettyBuf = ((Netty4ToProtonBufferAdapter) output).unwrapAndRelease();
} else {
- ProtonNettyByteBuffer wrapped = new ProtonNettyByteBuffer(channel.alloc().ioBuffer(output.getReadableBytes()));
- wrapped.writeBytes(output);
- nettyBuf = wrapped.unwrap();
+ try (output) {
+ Netty4ToProtonBufferAdapter wrapped = nettyAllocator.outputBuffer(output.getReadableBytes());
+ wrapped.writeBytes(output);
+ nettyBuf = wrapped.unwrap();
+ }
}
return nettyBuf;
}
+ private TcpTransport writeOutputBuffer(final ProtonBuffer buffer, boolean flush, ChannelPromise promise) {
+ int writeCount = buffer.componentCount();
+
+ try (ProtonBuffer ioBuffer = buffer; ProtonBufferComponentAccessor accessor = buffer.componentAccessor()) {
+ for (ProtonBufferComponent output = accessor.firstReadable(); output != null; output = accessor.nextReadable()) {
+ final ByteBuf nettyBuf;
+
+ if (output instanceof Netty4ToProtonBufferAdapter) {
+ nettyBuf = ((Netty4ToProtonBufferAdapter)output).unwrapAndRelease();
+ } else if (output.unwrap() instanceof ByteBuf) {
+ nettyBuf = (ByteBuf) ReferenceCountUtil.retain(output.unwrap());
+ } else {
+ nettyBuf = channel.alloc().ioBuffer(output.getReadableBytes());
+ if (output.hasReadbleArray()) {
+ nettyBuf.writeBytes(output.getReadableArray(), output.getReadableArrayOffset(), output.getReadableBytes());
+ } else {
+ nettyBuf.writeBytes(output.getReadableBuffer());
+ }
+ }
+
+ if (--writeCount > 0) {
+ channel.write(nettyBuf, channel.voidPromise());
+ } else {
+ if (flush) {
+ channel.writeAndFlush(nettyBuf, promise);
+ } else {
+ channel.write(nettyBuf, promise);
+ }
+ }
+ }
+ }
+
+ return this;
+ }
+
//----- Internal implementation details, can be overridden as needed -----//
protected void addAdditionalHandlers(ChannelPipeline pipeline) {
@@ -360,7 +400,7 @@ public class TcpTransport implements Transport {
private void checkConnected(ProtonBuffer output) throws IOException {
if (!connected.get() || !channel.isActive()) {
- if (output instanceof ProtonNettyByteBuffer) {
+ if (output instanceof Netty4ToProtonBufferAdapter) {
ReferenceCountUtil.release(output.unwrap());
}
throw new IOException("Cannot send to a non-connected transport.", failureCause);
@@ -422,6 +462,10 @@ public class TcpTransport implements Transport {
protected abstract class NettyDefaultHandler<E> extends SimpleChannelInboundHandler<E> {
+ public NettyDefaultHandler() {
+ super(false); // We will release buffer references manually.
+ }
+
@Override
public final void channelRegistered(ChannelHandlerContext context) throws Exception {
channel = context.channel();
@@ -464,6 +508,20 @@ public class TcpTransport implements Transport {
public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
handleTransportFailure(context.channel(), cause);
}
+
+ protected void dispatchReadBuffer(ByteBuf buffer) throws Exception {
+ LOG.trace("New data read: {}", buffer);
+
+ // Wrap the buffer and make it read-only as the handlers should not be altering the
+ // read bytes and if they need to they should be copying them. If the handler doesn't
+ // take ownership of the incoming buffer then we will close it and the reference count
+ // will be decremented here (default auto decrement has been disabled).
+ final ProtonBuffer wrapped = nettyAllocator.wrap(buffer).convertToReadOnly();
+
+ try (wrapped) {
+ listener.transportRead(wrapped);
+ }
+ }
}
//----- Handle binary data over socket connections -----------------------//
@@ -472,18 +530,7 @@ public class TcpTransport implements Transport {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
- LOG.trace("New data read: {}", buffer);
-
- final ProtonNettyByteBuffer wrapped = new ProtonNettyByteBuffer(buffer);
-
- // Avoid all doubts to the contrary
- if (channel.eventLoop().inEventLoop()) {
- listener.transportRead(wrapped);
- } else {
- channel.eventLoop().execute(() -> {
- listener.transportRead(wrapped);
- });
- }
+ dispatchReadBuffer(buffer);
}
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransport.java
similarity index 97%
copy from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java
copy to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransport.java
index 8a1f8e06..f150a2c9 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import java.io.IOException;
import java.net.URI;
@@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
@@ -237,11 +236,11 @@ public class WebSocketTransport extends TcpTransport {
} else if (frame instanceof BinaryWebSocketFrame) {
BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame;
LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.content().readableBytes());
- listener.transportRead(new ProtonNettyByteBuffer(binaryFrame.content()));
+ dispatchReadBuffer(binaryFrame.content());
} else if (frame instanceof ContinuationWebSocketFrame) {
ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame;
LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.content().readableBytes());
- listener.transportRead(new ProtonNettyByteBuffer(continuationFrame.content()));
+ dispatchReadBuffer(continuationFrame.content());
} else if (frame instanceof PingWebSocketFrame) {
LOG.trace("WebSocket Client received ping, response with pong");
ch.write(new PongWebSocketFrame(frame.content()));
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java
similarity index 78%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java
index 14e9e980..2b774d92 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/EpollSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.util.concurrent.ThreadFactory;
@@ -22,13 +22,14 @@ import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.epoll.Epoll;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty5.channel.Channel;
+import io.netty5.channel.EventLoopGroup;
+import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.epoll.Epoll;
+import io.netty5.channel.epoll.EpollHandler;
+import io.netty5.channel.epoll.EpollSocketChannel;
-public class EpollSupport {
+public final class EpollSupport {
private static final Logger LOG = LoggerFactory.getLogger(EpollSupport.class);
@@ -44,7 +45,7 @@ public class EpollSupport {
}
public static EventLoopGroup createGroup(int nThreads, ThreadFactory ioThreadFactory) {
- return new EpollEventLoopGroup(nThreads, ioThreadFactory);
+ return new MultithreadEventLoopGroup(nThreads, ioThreadFactory, EpollHandler.newFactory());
}
public static Class<? extends Channel> getChannelClass() {
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java
similarity index 74%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java
index 5ddd8fff..7a435e14 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/IOUringSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.util.concurrent.ThreadFactory;
@@ -22,11 +22,8 @@ import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.incubator.channel.uring.IOUring;
-import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
-import io.netty.incubator.channel.uring.IOUringSocketChannel;
+import io.netty5.channel.Channel;
+import io.netty5.channel.EventLoopGroup;
public class IOUringSupport {
@@ -36,7 +33,7 @@ public class IOUringSupport {
public static boolean isAvailable(TransportOptions transportOptions) {
try {
- return transportOptions.allowNativeIO() && IOUring.isAvailable();
+ return false; //transportOptions.allowNativeIO() && IOUring.isAvailable();
} catch (NoClassDefFoundError ncdfe) {
LOG.debug("Unable to check for IO_Uring support due to missing class definition", ncdfe);
return false;
@@ -44,10 +41,12 @@ public class IOUringSupport {
}
public static EventLoopGroup createGroup(int nThreads, ThreadFactory ioThreadFactory) {
- return new IOUringEventLoopGroup(nThreads, ioThreadFactory);
+ // return new MultithreadEventLoopGroup(nThreads, ioThreadFactory, null);
+ throw new UnsupportedOperationException("Netty v5 doesn't yet support IO_Uring");
}
public static Class<? extends Channel> getChannelClass() {
- return IOUringSocketChannel.class;
+ // return IOUringSocketChannel.class;
+ throw new UnsupportedOperationException("Netty v5 doesn't yet support IO_Uring");
}
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/KQueueSupport.java
similarity index 78%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/KQueueSupport.java
index 38354d09..7c4fd76e 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/KQueueSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/KQueueSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.util.concurrent.ThreadFactory;
@@ -22,13 +22,14 @@ import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.kqueue.KQueue;
-import io.netty.channel.kqueue.KQueueEventLoopGroup;
-import io.netty.channel.kqueue.KQueueSocketChannel;
+import io.netty5.channel.Channel;
+import io.netty5.channel.EventLoopGroup;
+import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.kqueue.KQueue;
+import io.netty5.channel.kqueue.KQueueHandler;
+import io.netty5.channel.kqueue.KQueueSocketChannel;
-public class KQueueSupport {
+public final class KQueueSupport {
private static final Logger LOG = LoggerFactory.getLogger(KQueueSupport.class);
@@ -44,7 +45,7 @@ public class KQueueSupport {
}
public static EventLoopGroup createGroup(int nThreads, ThreadFactory ioThreadFactory) {
- return new KQueueEventLoopGroup(nThreads, ioThreadFactory);
+ return new MultithreadEventLoopGroup(nThreads, ioThreadFactory, KQueueHandler.newFactory());
}
public static Class<? extends Channel> getChannelClass() {
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java
similarity index 67%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java
index 18de96e9..cffa2187 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/NettyIOContext.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java
@@ -14,44 +14,50 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.util.Objects;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.IOContext;
import org.apache.qpid.protonj2.client.util.TrackableThreadFactory;
+import org.apache.qpid.protonj2.engine.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.util.concurrent.Future;
+import io.netty5.bootstrap.Bootstrap;
+import io.netty5.channel.Channel;
+import io.netty5.channel.EventLoopGroup;
+import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.nio.NioHandler;
+import io.netty5.channel.socket.nio.NioSocketChannel;
/**
* Builder of Transport instances that will validate the build options and produce a
* correctly configured transport based on the options set.
*/
-public final class NettyIOContext {
+public final class Netty5IOContext implements IOContext {
- private static final Logger LOG = LoggerFactory.getLogger(NettyIOContext.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Netty5IOContext.class);
private static final int SHUTDOWN_TIMEOUT = 50;
private static final int ASYNC_SHUTDOWN_TIMEOUT = 100;
private static final int ASYNC_SHUTDOWN_QUIET_PERIOD = 10;
private final EventLoopGroup group;
+ private final NettyIOScheduler scheduler = new NettyIOScheduler();
private final Class<? extends Channel> channelClass;
private final TransportOptions options;
private final SslOptions sslOptions;
private final ThreadFactory threadFactory;
- public NettyIOContext(TransportOptions options, SslOptions ssl, String ioThreadName) {
+ public Netty5IOContext(TransportOptions options, SslOptions ssl, String ioThreadName) {
Objects.requireNonNull(options, "Transport Options cannot be null");
Objects.requireNonNull(ssl, "Transport SSL Options cannot be null");
@@ -96,7 +102,7 @@ public final class NettyIOContext {
if (selectedGroup == null) {
LOG.trace("Netty Transports will be using NIO mode");
- selectedGroup = new NioEventLoopGroup(1, threadFactory);
+ selectedGroup = new MultithreadEventLoopGroup(1, threadFactory, NioHandler.newFactory());
selectedChannelClass = NioSocketChannel.class;
}
@@ -104,11 +110,16 @@ public final class NettyIOContext {
this.channelClass = selectedChannelClass;
}
+ @Override
public void shutdown() {
if (!group.isShutdown()) {
- Future<?> fut = group.shutdownGracefully(0, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
- if (!fut.awaitUninterruptibly(2 * SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
- LOG.trace("Connection IO Event Loop shutdown failed to complete in allotted time");
+ group.shutdownGracefully(0, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
+ try {
+ if (!group.awaitTermination(2 * SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ LOG.trace("Connection IO Event Loop shutdown failed to complete in allotted time");
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
}
}
@@ -118,16 +129,19 @@ public final class NettyIOContext {
* at the time of termination. This is safe to call from inside the event loop where the
* standard blocking shutdown API is not.
*/
+ @Override
public void shutdownAsync() {
if (!group.isShutdown()) {
group.shutdownGracefully(ASYNC_SHUTDOWN_QUIET_PERIOD, ASYNC_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
}
}
- public EventLoopGroup eventLoop() {
- return group;
+ @Override
+ public Scheduler ioScheduler() {
+ return scheduler;
}
+ @Override
public TcpTransport newTransport() {
if (group.isShutdown() || group.isShuttingDown() || group.isTerminated()) {
throw new IllegalStateException("Cannot create a Transport from a shutdown IO context");
@@ -145,4 +159,37 @@ public final class NettyIOContext {
return transport;
}
+
+ public class NettyIOScheduler implements Scheduler, Executor {
+
+ @Override
+ public void execute(Runnable command) {
+ group.execute(command);
+ }
+
+ @Override
+ public Future<?> schedule(Runnable command, long delay, TimeUnit unit) {
+ return group.schedule(command, delay, unit).asStage();
+ }
+
+ @Override
+ public <V> Future<V> schedule(Callable<V> task, long delay, TimeUnit unit) {
+ return group.schedule(task, delay, unit).asStage();
+ }
+
+ @Override
+ public Future<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
+ return group.scheduleAtFixedRate(command, initialDelay, period, unit).asStage();
+ }
+
+ @Override
+ public Future<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
+ return group.scheduleWithFixedDelay(command, initialDelay, delay, unit).asStage();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return group.isShutdown();
+ }
+ }
}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/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-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5Support.java
index 557a3fde..1bb8ac87 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/codec/NullElement.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/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.netty.buffer.ByteBuf;
+package org.apache.qpid.protonj2.client.transport.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(ByteBuf buffer) {
- if (buffer.isWritable() && !isElementOfArray()) {
- buffer.writeByte((byte) 0x40);
- return 1;
- }
- return 0;
+ public static final boolean isAvailable() {
+ return UNAVAILABILITY_CAUSE == null;
}
}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java
similarity index 95%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java
index 7a2c422f..88acd345 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/SslSupport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.io.File;
import java.io.FileInputStream;
@@ -36,22 +36,23 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.X509AliasKeyManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBufAllocator;
-import io.netty.handler.ssl.OpenSsl;
-import io.netty.handler.ssl.OpenSslX509KeyManagerFactory;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslContextBuilder;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.handler.ssl.SslProvider;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty5.buffer.BufferAllocator;
+import io.netty5.handler.ssl.OpenSsl;
+import io.netty5.handler.ssl.OpenSslX509KeyManagerFactory;
+import io.netty5.handler.ssl.SslContext;
+import io.netty5.handler.ssl.SslContextBuilder;
+import io.netty5.handler.ssl.SslHandler;
+import io.netty5.handler.ssl.SslProvider;
+import io.netty5.handler.ssl.util.InsecureTrustManagerFactory;
/**
* Static class that provides various utility methods used by Transport implementations.
*/
-public class SslSupport {
+public final class SslSupport {
private static final Logger LOG = LoggerFactory.getLogger(SslSupport.class);
@@ -106,7 +107,7 @@ public class SslSupport {
*
* @throws Exception if an error occurs while creating the SslHandler instance.
*/
- public static SslHandler createSslHandler(ByteBufAllocator allocator, String host, int port, SslOptions options) throws Exception {
+ public static SslHandler createSslHandler(BufferAllocator allocator, String host, int port, SslOptions options) throws Exception {
final SSLEngine sslEngine;
if (isOpenSSLPossible(options)) {
@@ -238,7 +239,7 @@ public class SslSupport {
* TransportOptions instances.
*
* @param allocator
- * the Netty ByteBufAllocator to use to create the OpenSSL engine
+ * the Netty BufferAllocator to use to create the OpenSSL engine
* @param host
* the host name or IP address that this transport connects to.
* @param port
@@ -252,7 +253,7 @@ public class SslSupport {
*
* @throws Exception if an error occurs while creating the new SSLEngine.
*/
- public static SSLEngine createOpenSslEngine(ByteBufAllocator allocator, String host, int port, SslContext context, SslOptions options) throws Exception {
+ public static SSLEngine createOpenSslEngine(BufferAllocator allocator, String host, int port, SslContext context, SslOptions options) throws Exception {
SSLEngine engine = null;
if (allocator == null) {
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java
similarity index 71%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java
index 119467cf..5fba50b6 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/TcpTransport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.io.IOException;
import java.net.URI;
@@ -25,30 +25,32 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonBufferComponent;
+import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
+import org.apache.qpid.protonj2.buffer.netty.Netty5ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.netty.Netty5ToProtonBufferAdapter;
+import org.apache.qpid.protonj2.buffer.netty.ProtonBufferToNetty5Adapter;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
+import org.apache.qpid.protonj2.client.transport.TransportListener;
import org.apache.qpid.protonj2.client.util.IOExceptionSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.FixedRecvByteBufAllocator;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.handler.logging.LoggingHandler;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.util.ReferenceCountUtil;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GenericFutureListener;
+import io.netty5.bootstrap.Bootstrap;
+import io.netty5.buffer.Buffer;
+import io.netty5.channel.Channel;
+import io.netty5.channel.ChannelHandler;
+import io.netty5.channel.ChannelHandlerContext;
+import io.netty5.channel.ChannelInitializer;
+import io.netty5.channel.ChannelOption;
+import io.netty5.channel.ChannelPipeline;
+import io.netty5.channel.SimpleChannelInboundHandler;
+import io.netty5.handler.logging.LoggingHandler;
+import io.netty5.handler.ssl.SslHandler;
+import io.netty5.util.concurrent.Future;
+import io.netty5.util.concurrent.FutureListener;
/**
* TCP based transport that uses Netty as the underlying IO layer.
@@ -69,6 +71,7 @@ public class TcpTransport implements Transport {
protected String host;
protected int port;
protected TransportListener listener;
+ protected Netty5ProtonBufferAllocator nettyAllocator;
/**
* Create a new {@link TcpTransport} instance with the given configuration.
@@ -133,6 +136,8 @@ public class TcpTransport implements Transport {
@Override
public void initChannel(Channel transportChannel) throws Exception {
channel = transportChannel;
+ nettyAllocator = new Netty5ProtonBufferAllocator(channel.bufferAllocator());
+
configureChannel(transportChannel);
try {
listener.transportInitialized(TcpTransport.this);
@@ -146,7 +151,15 @@ public class TcpTransport implements Transport {
configureNetty(bootstrap, options);
- bootstrap.connect(getHost(), getPort()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
+ bootstrap.connect(getHost(), getPort()).addListener(new FutureListener<Channel>() {
+
+ @Override
+ public void operationComplete(Future<? extends Channel> future) throws Exception {
+ if (future.isFailed()) {
+ bootstrap.config().group().execute(() -> handleTransportFailure(channel, future.cause()));
+ }
+ }
+ });
return this;
}
@@ -189,25 +202,18 @@ public class TcpTransport implements Transport {
connected.set(false);
connectedLatch.countDown();
if (channel != null) {
- channel.close().syncUninterruptibly();
+ try {
+ channel.close().asStage().await();
+ } catch (InterruptedException e) {
+ Thread.interrupted();
+ }
}
}
}
@Override
public ProtonBufferAllocator getBufferAllocator() {
- return new ProtonNettyByteBufferAllocator() {
-
- @Override
- public ProtonBuffer outputBuffer(int initialCapacity) {
- return new ProtonNettyByteBuffer(channel.alloc().ioBuffer(initialCapacity));
- }
-
- @Override
- public ProtonBuffer outputBuffer(int initialCapacity, int maximumCapacity) {
- return new ProtonNettyByteBuffer(channel.alloc().ioBuffer(initialCapacity, maximumCapacity));
- }
- };
+ return nettyAllocator;
}
@Override
@@ -219,20 +225,7 @@ public class TcpTransport implements Transport {
public TcpTransport write(ProtonBuffer output, Runnable onComplete) throws IOException {
checkConnected(output);
LOG.trace("Attempted write of buffer: {}", output);
- if (onComplete == null) {
- channel.write(toOutputBuffer(output), channel.voidPromise());
- } else {
- channel.write(toOutputBuffer(output), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
-
- @Override
- public void operationComplete(Future<? super Void> future) throws Exception {
- if (future.isSuccess()) {
- onComplete.run();
- }
- }
- }));
- }
- return this;
+ return writeOutputBuffer(output, false, onComplete);
}
@Override
@@ -244,20 +237,7 @@ public class TcpTransport implements Transport {
public TcpTransport writeAndFlush(ProtonBuffer output, Runnable onComplete) throws IOException {
checkConnected(output);
LOG.trace("Attempted write and flush of buffer: {}", output);
- if (onComplete == null) {
- channel.writeAndFlush(toOutputBuffer(output), channel.voidPromise());
- } else {
- channel.writeAndFlush(toOutputBuffer(output), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
-
- @Override
- public void operationComplete(Future<? super Void> future) throws Exception {
- if (future.isSuccess()) {
- onComplete.run();
- }
- }
- }));
- }
- return this;
+ return writeOutputBuffer(output, true, onComplete);
}
@Override
@@ -295,18 +275,65 @@ public class TcpTransport implements Transport {
return result;
}
- protected final ByteBuf toOutputBuffer(final ProtonBuffer output) throws IOException {
- final ByteBuf nettyBuf;
+ private TcpTransport writeOutputBuffer(final ProtonBuffer buffer, boolean flush, Runnable onComplete) {
+ int writeCount = buffer.componentCount();
+ Future<Void> writeFuture = null;
+
+ try (ProtonBuffer ioBuffer = buffer; ProtonBufferComponentAccessor accessor = buffer.componentAccessor()) {
+ for (ProtonBufferComponent output = accessor.firstReadable(); output != null; output = accessor.nextReadable()) {
+ final Buffer nettyBuf;
+
+ if (output instanceof Netty5ToProtonBufferAdapter) {
+ nettyBuf = ((Netty5ToProtonBufferAdapter)output).unwrapAndRelease();
+ } else if (output.unwrap() instanceof Buffer) {
+ nettyBuf = ((Buffer) output.unwrap()).copy(true);
+ } else {
+ nettyBuf = channel.bufferAllocator().allocate(output.getReadableBytes());
+ if (output.hasReadbleArray()) {
+ nettyBuf.writeBytes(output.getReadableArray(), output.getReadableArrayOffset(), output.getReadableBytes());
+ } else {
+ nettyBuf.writeBytes(output.getReadableBuffer());
+ }
+ }
+
+ if (--writeCount == 0 && flush) {
+ writeFuture = channel.writeAndFlush(nettyBuf);
+ } else {
+ writeFuture = channel.write(nettyBuf);
+ }
+ }
+
+ if (onComplete != null) {
+ writeFuture.addListener(onComplete, TcpTransport::handleWriteComplete);
+ }
+ }
+
+ return this;
+ }
+
+ @SuppressWarnings("unused")
+ private TcpTransport writeOutputBufferAsWrappedNettyBuffer(final ProtonBuffer buffer, boolean flush, Runnable onComplete) {
+ Future<Void> writeFuture = null;
+
+ final Buffer nettyBuf = new ProtonBufferToNetty5Adapter(buffer.transfer());
- if (output instanceof ProtonNettyByteBuffer) {
- nettyBuf = (ByteBuf) output.unwrap();
+ if (flush) {
+ writeFuture = channel.writeAndFlush(nettyBuf);
} else {
- ProtonNettyByteBuffer wrapped = new ProtonNettyByteBuffer(channel.alloc().ioBuffer(output.getReadableBytes()));
- wrapped.writeBytes(output);
- nettyBuf = wrapped.unwrap();
+ writeFuture = channel.write(nettyBuf);
}
- return nettyBuf;
+ if (onComplete != null) {
+ writeFuture.addListener(onComplete, TcpTransport::handleWriteComplete);
+ }
+
+ return this;
+ }
+
+ private static void handleWriteComplete(Runnable onComplete, Future<? extends Void> future) {
+ if (future.isSuccess()) {
+ onComplete.run();
+ }
}
//----- Internal implementation details, can be overridden as needed -----//
@@ -315,7 +342,7 @@ public class TcpTransport implements Transport {
}
- protected ChannelInboundHandlerAdapter createChannelHandler() {
+ protected ChannelHandler createChannelHandler() {
return new NettyTcpTransportHandler();
}
@@ -338,10 +365,10 @@ public class TcpTransport implements Transport {
connectedLatch.countDown();
LOG.trace("Firing onTransportError listener");
- if (channel.eventLoop().inEventLoop()) {
+ if (channel.executor().inEventLoop()) {
listener.transportError(failureCause);
} else {
- channel.eventLoop().execute(() -> {
+ channel.executor().execute(() -> {
listener.transportError(failureCause);
});
}
@@ -360,9 +387,7 @@ public class TcpTransport implements Transport {
private void checkConnected(ProtonBuffer output) throws IOException {
if (!connected.get() || !channel.isActive()) {
- if (output instanceof ProtonNettyByteBuffer) {
- ReferenceCountUtil.release(output.unwrap());
- }
+ output.close();
throw new IOException("Cannot send to a non-connected transport.", failureCause);
}
}
@@ -379,7 +404,6 @@ public class TcpTransport implements Transport {
if (options.receiveBufferSize() != -1) {
bootstrap.option(ChannelOption.SO_RCVBUF, options.receiveBufferSize());
- bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(options.receiveBufferSize()));
}
if (options.trafficClass() != -1) {
@@ -399,7 +423,7 @@ public class TcpTransport implements Transport {
if (isSecure()) {
final SslHandler sslHandler;
try {
- sslHandler = SslSupport.createSslHandler(channel.alloc(), host, port, sslOptions);
+ sslHandler = SslSupport.createSslHandler(channel.bufferAllocator(), host, port, sslOptions);
} catch (Exception ex) {
LOG.warn("Error during initialization of channel from SSL Handler creation:");
handleTransportFailure(channel, IOExceptionSupport.create(ex));
@@ -422,6 +446,10 @@ public class TcpTransport implements Transport {
protected abstract class NettyDefaultHandler<E> extends SimpleChannelInboundHandler<E> {
+ public NettyDefaultHandler() {
+ super(false); // We will release buffer references manually.
+ }
+
@Override
public final void channelRegistered(ChannelHandlerContext context) throws Exception {
channel = context.channel();
@@ -435,9 +463,9 @@ public class TcpTransport implements Transport {
handleConnected(context.channel());
} else {
SslHandler sslHandler = context.pipeline().get(SslHandler.class);
- sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {
+ sslHandler.handshakeFuture().addListener(new FutureListener<Channel>() {
@Override
- public void operationComplete(Future<Channel> future) throws Exception {
+ public void operationComplete(Future<? extends Channel> future) throws Exception {
if (future.isSuccess()) {
LOG.trace("SSL Handshake has completed: {}", channel);
handleConnected(channel);
@@ -461,32 +489,35 @@ public class TcpTransport implements Transport {
}
@Override
- public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
+ public void channelExceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
handleTransportFailure(context.channel(), cause);
}
- }
-
- //----- Handle binary data over socket connections -----------------------//
- protected class NettyTcpTransportHandler extends NettyDefaultHandler<ByteBuf> {
-
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
+ protected void dispatchReadBuffer(Buffer buffer) throws Exception {
LOG.trace("New data read: {}", buffer);
- final ProtonNettyByteBuffer wrapped = new ProtonNettyByteBuffer(buffer);
+ // Wrap the buffer and make it read-only as the handlers should not be altering the
+ // read bytes and if they need to they should be copying them. If the handler doesn't
+ // take ownership of the incoming buffer then we will close it and the reference count
+ // will be decremented here (default auto decrement has been disabled).
+ final ProtonBuffer wrapped = nettyAllocator.wrap(buffer).convertToReadOnly();
- // Avoid all doubts to the contrary
- if (channel.eventLoop().inEventLoop()) {
+ try (wrapped) {
listener.transportRead(wrapped);
- } else {
- channel.eventLoop().execute(() -> {
- listener.transportRead(wrapped);
- });
}
}
}
+ //----- Handle binary data over socket connections -----------------------//
+
+ protected class NettyTcpTransportHandler extends NettyDefaultHandler<Buffer> {
+
+ @Override
+ protected void messageReceived(ChannelHandlerContext ctx, Buffer buffer) throws Exception {
+ dispatchReadBuffer(buffer);
+ }
+ }
+
@Override
public URI getRemoteURI() {
if (host != null) {
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java
similarity index 59%
rename from protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java
rename to protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java
index 8a1f8e06..59337461 100644
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/WebSocketTransport.java
+++ b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.io.IOException;
import java.net.URI;
@@ -22,35 +22,35 @@ import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelPipeline;
-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.util.concurrent.Future;
-import io.netty.util.concurrent.GenericFutureListener;
-import io.netty.util.concurrent.ScheduledFuture;
+import io.netty5.bootstrap.Bootstrap;
+import io.netty5.buffer.Buffer;
+import io.netty5.channel.Channel;
+import io.netty5.channel.ChannelHandler;
+import io.netty5.channel.ChannelHandlerAdapter;
+import io.netty5.channel.ChannelHandlerContext;
+import io.netty5.channel.ChannelPipeline;
+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.util.concurrent.Future;
+import io.netty5.util.concurrent.FutureListener;
/**
* Netty based WebSockets Transport that wraps and extends the TCP Transport.
@@ -61,7 +61,7 @@ public class WebSocketTransport extends TcpTransport {
private static final String AMQP_SUB_PROTOCOL = "amqp";
- private ScheduledFuture<?> handshakeTimeoutFuture;
+ private Future<Void> handshakeTimeoutFuture;
/**
* Create a new {@link WebSocketTransport} instance with the given configuration.
@@ -77,60 +77,6 @@ public class WebSocketTransport extends TcpTransport {
super(bootstrap, options, sslOptions);
}
- @Override
- public WebSocketTransport write(ProtonBuffer output, Runnable onComplete) throws IOException {
- checkConnected();
- int length = output.getReadableBytes();
- if (length == 0) {
- return this;
- }
-
- LOG.trace("Attempted write of: {} bytes", length);
-
- if (onComplete == null) {
- channel.write(new BinaryWebSocketFrame(toOutputBuffer(output)), channel.voidPromise());
- } else {
- channel.write(new BinaryWebSocketFrame(toOutputBuffer(output)), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
-
- @Override
- public void operationComplete(Future<? super Void> future) throws Exception {
- if (future.isSuccess()) {
- onComplete.run();
- }
- }
- }));
- }
-
- return this;
- }
-
- @Override
- public WebSocketTransport writeAndFlush(ProtonBuffer output, Runnable onComplete) throws IOException {
- checkConnected();
- int length = output.getReadableBytes();
- if (length == 0) {
- return this;
- }
-
- LOG.trace("Attempted write and flush of: {} bytes", length);
-
- if (onComplete == null) {
- channel.writeAndFlush(new BinaryWebSocketFrame(toOutputBuffer(output)), channel.voidPromise());
- } else {
- channel.writeAndFlush(new BinaryWebSocketFrame(toOutputBuffer(output)), channel.newPromise().addListener(new GenericFutureListener<Future<? super Void>>() {
-
- @Override
- public void operationComplete(Future<? super Void> future) throws Exception {
- if (future.isSuccess()) {
- onComplete.run();
- }
- }
- }));
- }
-
- return this;
- }
-
@Override
public URI getRemoteURI() {
if (host != null) {
@@ -144,14 +90,14 @@ public class WebSocketTransport extends TcpTransport {
}
@Override
- protected ChannelInboundHandlerAdapter createChannelHandler() {
+ protected ChannelHandler createChannelHandler() {
return new NettyWebSocketTransportHandler();
}
@Override
protected void addAdditionalHandlers(ChannelPipeline pipeline) {
pipeline.addLast(new HttpClientCodec());
- pipeline.addLast(new HttpObjectAggregator(8192));
+ pipeline.addLast(new HttpObjectAggregator<DefaultHttpContent>(8192));
}
@Override
@@ -166,12 +112,20 @@ public class WebSocketTransport extends TcpTransport {
//----- Handle connection events -----------------------------------------//
- private class NettyWebSocketTransportHandler extends NettyDefaultHandler<Object> {
+ private class OutputBufferToBinaryFrameHandler extends ChannelHandlerAdapter {
+
+ @Override
+ public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
+ return ctx.write(new BinaryWebSocketFrame((Buffer) msg));
+ }
+ }
+
+ private class NettyWebSocketTransportHandler extends NettyDefaultHandler<Object> implements ChannelHandler {
private final WebSocketClientHandshaker handshaker;
public NettyWebSocketTransportHandler() {
- DefaultHttpHeaders headers = new DefaultHttpHeaders();
+ HttpHeaders headers = HttpHeaders.newHeaders();
options.webSocketHeaders().forEach((key, value) -> {
headers.set(key, value);
@@ -185,7 +139,7 @@ public class WebSocketTransport extends TcpTransport {
@Override
public void channelInactive(ChannelHandlerContext context) throws Exception {
if (handshakeTimeoutFuture != null) {
- handshakeTimeoutFuture.cancel(false);
+ handshakeTimeoutFuture.cancel();
}
super.channelInactive(context);
@@ -193,7 +147,17 @@ public class WebSocketTransport extends TcpTransport {
@Override
public void channelActive(ChannelHandlerContext context) throws Exception {
- handshaker.handshake(context.channel());
+ handshaker.handshake(context.channel()).addListener(new FutureListener<Void>() {
+
+ @Override
+ public void operationComplete(Future<? extends Void> future) throws Exception {
+ if (future.isSuccess()) {
+ // Now we can add a transformer for outbound buffers that will produce
+ // binary websocket frame wrappers to ensure our writes are encoded.
+ context.pipeline().addLast(new OutputBufferToBinaryFrameHandler());
+ }
+ }
+ });
handshakeTimeoutFuture = context.executor().schedule(()-> {
LOG.trace("WebSocket handshake timed out! Channel is {}", context.channel());
@@ -206,7 +170,7 @@ public class WebSocketTransport extends TcpTransport {
}
@Override
- protected void channelRead0(ChannelHandlerContext ctx, Object message) throws Exception {
+ protected void messageReceived(ChannelHandlerContext ctx, Object message) throws Exception {
LOG.trace("New data read: incoming: {}", message);
Channel ch = ctx.channel();
@@ -214,7 +178,7 @@ public class WebSocketTransport extends TcpTransport {
handshaker.finishHandshake(ch, (FullHttpResponse) message);
LOG.trace("WebSocket Client connected! {}", ctx.channel());
// Now trigger super processing as we are really connected.
- if (handshakeTimeoutFuture.cancel(false)) {
+ if (handshakeTimeoutFuture.cancel()) {
WebSocketTransport.super.handleConnected(ch);
}
@@ -226,25 +190,25 @@ public class WebSocketTransport extends TcpTransport {
FullHttpResponse response = (FullHttpResponse) message;
throw new IllegalStateException(
"Unexpected FullHttpResponse (getStatus=" + response.status() +
- ", content=" + response.content().toString(StandardCharsets.UTF_8) + ')');
+ ", 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.fireExceptionCaught(new IOException("Received invalid frame over WebSocket."));
+ 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.content().readableBytes());
- listener.transportRead(new ProtonNettyByteBuffer(binaryFrame.content()));
+ LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.binaryData().readableBytes());
+ dispatchReadBuffer(binaryFrame.binaryData());
} else if (frame instanceof ContinuationWebSocketFrame) {
ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.content().readableBytes());
- listener.transportRead(new ProtonNettyByteBuffer(continuationFrame.content()));
+ LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.binaryData().readableBytes());
+ dispatchReadBuffer(continuationFrame.binaryData());
} else if (frame instanceof PingWebSocketFrame) {
LOG.trace("WebSocket Client received ping, response with pong");
- ch.write(new PongWebSocketFrame(frame.content()));
+ ch.write(new PongWebSocketFrame(frame.binaryData()));
} else if (frame instanceof CloseWebSocketFrame) {
LOG.trace("WebSocket Client received closing");
ch.close();
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/ClientMessageTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/ClientMessageTest.java
index c41a16f5..1391ac87 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/ClientMessageTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/ClientMessageTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.qpid.protonj2.client.impl;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -366,8 +367,8 @@ class ClientMessageTest {
message.bodySections().forEach(section -> {
assertTrue(section instanceof Data);
final Data dataView = (Data) section;
- assertEquals(counter.get(), dataView.getBuffer().getArray()[0]);
- assertEquals(counter.getAndIncrement(), dataView.getBinary().getArray()[0]);
+ assertEquals(counter.get(), dataView.getBuffer().getByte(0));
+ assertEquals(counter.getAndIncrement(), dataView.getBinary().asByteArray()[0]);
});
}
@@ -452,21 +453,21 @@ class ClientMessageTest {
message.body(expected.get(0).getValue());
- assertEquals(expected.get(0).getValue(), message.body());
+ assertArrayEquals(expected.get(0).getValue(), message.body());
assertNotNull(message.bodySections());
assertFalse(message.bodySections().isEmpty());
assertEquals(1, message.bodySections().size());
message.addBodySection(expected.get(1));
- assertEquals(expected.get(0).getValue(), message.body());
+ assertArrayEquals(expected.get(0).getValue(), message.body());
assertNotNull(message.bodySections());
assertFalse(message.bodySections().isEmpty());
assertEquals(2, message.bodySections().size());
message.addBodySection(expected.get(2));
- assertEquals(expected.get(0).getValue(), message.body());
+ assertArrayEquals(expected.get(0).getValue(), message.body());
assertNotNull(message.bodySections());
assertFalse(message.bodySections().isEmpty());
assertEquals(3, message.bodySections().size());
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/SslConnectionTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/SslConnectionTest.java
index 8b71151a..c0f61a9c 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/SslConnectionTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/impl/SslConnectionTest.java
@@ -39,7 +39,7 @@ import org.apache.qpid.protonj2.client.Connection;
import org.apache.qpid.protonj2.client.ConnectionOptions;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.test.ImperativeClientTestCase;
-import org.apache.qpid.protonj2.client.transport.SslSupport;
+import org.apache.qpid.protonj2.client.transport.netty5.SslSupport;
import org.apache.qpid.protonj2.test.driver.ProtonTestServer;
import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
import org.apache.qpid.protonj2.types.security.SaslCode;
@@ -50,7 +50,7 @@ import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.handler.ssl.OpenSsl;
+import io.netty5.handler.ssl.OpenSsl;
/**
* Test for the Connection class
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/test/ImperativeClientTestCase.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/test/ImperativeClientTestCase.java
index 8a240b55..0aaf1d8e 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/test/ImperativeClientTestCase.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/test/ImperativeClientTestCase.java
@@ -22,7 +22,7 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.codec.CodecFactory;
import org.apache.qpid.protonj2.codec.Encoder;
import org.apache.qpid.protonj2.types.messaging.Data;
@@ -105,32 +105,32 @@ public abstract class ImperativeClientTestCase {
protected byte[] createEncodedMessage(Section<Object> body) {
Encoder encoder = CodecFactory.getEncoder();
- ProtonBuffer buffer = new ProtonByteBufferAllocator().allocate();
+ ProtonBuffer buffer = ProtonBufferAllocator.defaultAllocator().allocate();
encoder.writeObject(buffer, encoder.newEncoderState(), body);
byte[] result = new byte[buffer.getReadableBytes()];
- buffer.readBytes(result);
+ buffer.copyInto(buffer.getReadOffset(), result, 0, result.length);
return result;
}
protected byte[] createEncodedMessage(Section<?>... body) {
Encoder encoder = CodecFactory.getEncoder();
- ProtonBuffer buffer = new ProtonByteBufferAllocator().allocate();
+ ProtonBuffer buffer = ProtonBufferAllocator.defaultAllocator().allocate();
for (Section<?> section : body) {
encoder.writeObject(buffer, encoder.newEncoderState(), section);
}
byte[] result = new byte[buffer.getReadableBytes()];
- buffer.readBytes(result);
+ buffer.copyInto(buffer.getReadOffset(), result, 0, result.length);
return result;
}
protected byte[] createEncodedMessage(Data... body) {
Encoder encoder = CodecFactory.getEncoder();
- ProtonBuffer buffer = new ProtonByteBufferAllocator().allocate();
+ ProtonBuffer buffer = ProtonBufferAllocator.defaultAllocator().allocate();
for (Data data : body) {
encoder.writeObject(buffer, encoder.newEncoderState(), data);
}
byte[] result = new byte[buffer.getReadableBytes()];
- buffer.readBytes(result);
+ buffer.copyInto(buffer.getReadOffset(), result, 0, result.length);
return result;
}
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyBlackHoleServer.java
similarity index 97%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyBlackHoleServer.java
index 0b0c1510..9a0810f6 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyBlackHoleServer.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyEchoServer.java
similarity index 97%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyEchoServer.java
index 90c9e4de..c6876d88 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyEchoServer.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyIOContextTest.java
similarity index 76%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyIOContextTest.java
index 0d63eda0..9e271b86 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyIOContextTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -23,13 +23,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.IOContext;
import org.junit.jupiter.api.Test;
class NettyIOContextTest {
@Test
void testCannotCreateNewTransportFromShutdownBootStrap() {
- NettyIOContext context = new NettyIOContext(new TransportOptions(), new SslOptions(), "test");
+ IOContext context = new Netty4IOContext(new TransportOptions(), new SslOptions(), "test");
context.shutdown();
@@ -38,13 +39,13 @@ class NettyIOContextTest {
@Test
void testEventLoopGroupAccessibleAfterCreate() {
- NettyIOContext context = new NettyIOContext(new TransportOptions(), new SslOptions(), "test");
+ IOContext context = new Netty4IOContext(new TransportOptions(), new SslOptions(), "test");
- assertNotNull(context.eventLoop());
- assertFalse(context.eventLoop().isShutdown());
+ assertNotNull(context.ioScheduler());
+ assertFalse(context.ioScheduler().isShutdown());
context.shutdown();
- assertTrue(context.eventLoop().isShutdown());
+ assertTrue(context.ioScheduler().isShutdown());
}
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyServer.java
similarity index 99%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyServer.java
index d753c88d..c02f890a 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/NettyServer.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/OpenSslTransportTest.java
similarity index 98%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/OpenSslTransportTest.java
index 2e4992cb..d9c13191 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/OpenSslTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -28,6 +28,7 @@ import java.lang.reflect.Field;
import javax.net.ssl.SSLContext;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SecureWebSocketTransportTest.java
similarity index 95%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SecureWebSocketTransportTest.java
index 5aa020ca..a7b7be04 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SecureWebSocketTransportTest.java
@@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupportTest.java
similarity index 99%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupportTest.java
index dbb0d84e..52dab6c7 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslSupportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslTransportTest.java
similarity index 99%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslTransportTest.java
index f4c12e00..42401424 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/SslTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -30,6 +30,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
@@ -123,7 +124,7 @@ public class SslTransportTest extends TcpTransportTest {
sslOptions.keyStorePassword("wrong");
Transport transport = createTransport(createTransportOptions(), sslOptions);
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportError(Throwable cause) {
@@ -160,7 +161,7 @@ public class SslTransportTest extends TcpTransportTest {
sslOptions.trustStorePassword("wrong");
Transport transport = createTransport(createTransportOptions(), sslOptions);
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportError(Throwable cause) {
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransportTest.java
similarity index 89%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransportTest.java
index 202dd31a..3d17e55f 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/TcpTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -35,12 +35,17 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.netty.Netty4ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.apache.qpid.protonj2.client.test.ImperativeClientTestCase;
import org.apache.qpid.protonj2.client.test.Wait;
+import org.apache.qpid.protonj2.client.transport.IOContext;
+import org.apache.qpid.protonj2.client.transport.Transport;
+import org.apache.qpid.protonj2.client.transport.TransportListener;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@@ -49,8 +54,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.kqueue.KQueue;
@@ -78,9 +82,18 @@ public class TcpTransportTest extends ImperativeClientTestCase {
protected final List<ProtonBuffer> data = new ArrayList<>();
protected final AtomicInteger bytesRead = new AtomicInteger();
- protected final TransportListener testListener = new NettyTransportListener(false);
+ protected final TransportListener testListener = new NettyTransportListener();
- protected NettyIOContext context;
+ protected ProtonBufferAllocator allocator;
+ protected Netty4IOContext context;
+
+ @Override
+ @BeforeEach
+ public void setUp(TestInfo testInfo) throws Exception {
+ super.setUp(testInfo);
+
+ allocator = new Netty4ProtonBufferAllocator(UnpooledByteBufAllocator.DEFAULT);
+ }
@Override
@AfterEach
@@ -91,6 +104,11 @@ public class TcpTransportTest extends ImperativeClientTestCase {
context.shutdown();
context = null;
}
+
+ data.removeIf((buffer) -> {
+ buffer.close();
+ return true;
+ });
}
@Test
@@ -149,19 +167,19 @@ public class TcpTransportTest extends ImperativeClientTestCase {
@Test
public void testCreateWithNullOptionsThrowsIAE() throws Exception {
try {
- new NettyIOContext(null, null, getTestName());
+ new Netty4IOContext(null, null, getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
try {
- new NettyIOContext(createTransportOptions(), null, getTestName());
+ new Netty4IOContext(createTransportOptions(), null, getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
try {
- new NettyIOContext(null, createSSLOptions(), getTestName());
+ new Netty4IOContext(null, createSSLOptions(), getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
@@ -281,7 +299,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
List<Transport> transports = new ArrayList<>();
- NettyIOContext context = createContext(createTransportOptions(), createSSLOptions());
+ IOContext context = createContext(createTransportOptions(), createSSLOptions());
for (int i = 0; i < CONNECTION_COUNT; ++i) {
Transport transport = context.newTransport();
@@ -311,9 +329,9 @@ public class TcpTransportTest extends ImperativeClientTestCase {
final int CONNECTION_COUNT = 10;
final int FRAME_SIZE = 8;
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < 8; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -323,7 +341,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
List<Transport> transports = new ArrayList<>();
- NettyIOContext context = createContext(createTransportOptions(), createSSLOptions());
+ IOContext context = createContext(createTransportOptions(), createSSLOptions());
for (int i = 0; i < CONNECTION_COUNT; ++i) {
Transport transport = context.newTransport();
@@ -417,10 +435,12 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
+ final ProtonBuffer sendBuffer = allocator.allocate(0);
+
if (writeAndFlush) {
- transport.writeAndFlush(new ProtonNettyByteBuffer(Unpooled.buffer(0)));
+ transport.writeAndFlush(sendBuffer);
} else {
- transport.write(new ProtonNettyByteBuffer(Unpooled.buffer(0)));
+ transport.write(sendBuffer);
transport.flush();
}
@@ -449,10 +469,10 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonBuffer buffer = transport.getBufferAllocator().outputBuffer(64, 512);
+ ProtonBuffer buffer = transport.getBufferAllocator().allocate(64).implicitGrowthLimit(512);
assertEquals(64, buffer.capacity());
- assertEquals(512, buffer.maxCapacity());
+ assertEquals(512, buffer.implicitGrowthLimit());
transport.writeAndFlush(buffer);
@@ -481,10 +501,10 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonBuffer buffer = transport.getBufferAllocator().allocate(64, 512);
+ ProtonBuffer buffer = transport.getBufferAllocator().allocate(64).implicitGrowthLimit(512);
assertEquals(64, buffer.capacity());
- assertEquals(512, buffer.maxCapacity());
+ assertEquals(512, buffer.implicitGrowthLimit());
transport.writeAndFlush(buffer);
@@ -515,7 +535,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
ProtonBuffer sendBuffer = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
transport.write(sendBuffer, () -> LOG.debug("Netty reports write complete"));
@@ -538,6 +558,54 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(exceptions.isEmpty());
}
+ @Test
+ public void testDataSentWithinCompositeBufferIsReceived() throws Exception {
+ try (NettyEchoServer server = createEchoServer()) {
+ server.start();
+
+ int port = server.getServerPort();
+
+ Transport transport = createTransport(createTransportOptions(), createSSLOptions());
+ try {
+ transport.connect(HOSTNAME, port, testListener).awaitConnect();
+ LOG.info("Connected to server:{}:{} as expected.", HOSTNAME, port);
+ } catch (Exception e) {
+ fail("Should not have failed to connect to the server at " + HOSTNAME + ":" + port + " but got exception: " + e);
+ }
+
+ assertTrue(transport.isConnected());
+
+ ProtonBuffer sendBuffer1 = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
+ for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
+ sendBuffer1.writeByte((byte) 'A');
+ }
+ ProtonBuffer sendBuffer2 = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT + 10);
+ for (int i = 0; i < SEND_BYTE_COUNT + 10; ++i) {
+ sendBuffer2.writeByte((byte) 'A');
+ }
+
+ ProtonBuffer sendBuffer = transport.getBufferAllocator().composite(new ProtonBuffer[] { sendBuffer1, sendBuffer2});
+
+ transport.write(sendBuffer, () -> LOG.debug("Netty reports write complete"));
+ LOG.trace("Flush of Transport happens now");
+ transport.flush();
+
+ sendBuffer.close();
+
+ assertTrue(Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return bytesRead.get() == SEND_BYTE_COUNT + SEND_BYTE_COUNT + 10;
+ }
+ }, 10000, 50));
+
+ transport.close();
+ }
+
+ assertTrue(!transportErrored); // Normal shutdown does not trigger the event.
+ assertTrue(exceptions.isEmpty());
+ }
+
@Test
public void testDataSentWithWriteAndFlushIsReceived() throws Exception {
try (NettyEchoServer server = createEchoServer()) {
@@ -557,7 +625,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
ProtonBuffer sendBuffer = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
transport.writeAndFlush(sendBuffer, () -> LOG.debug("Netty reports write complete"));
@@ -604,13 +672,14 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(byteCount));
+ final ProtonBuffer sendBuffer = allocator.allocate(byteCount);
+
for (int i = 0; i < byteCount; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
for (int i = 0; i < iterations; ++i) {
- transport.writeAndFlush(sendBuffer.copy());
+ transport.writeAndFlush(sendBuffer.copy(true));
}
assertTrue(Wait.waitFor(new Wait.Condition() {
@@ -648,7 +717,8 @@ public class TcpTransportTest extends ImperativeClientTestCase {
transport.close();
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(10));
+ final ProtonBuffer sendBuffer = allocator.allocate(10);
+
try {
transport.writeAndFlush(sendBuffer);
fail("Should throw on send of closed transport");
@@ -667,7 +737,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
Transport transport = createTransport(createTransportOptions(), createSSLOptions());
try {
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportInitialized(Transport transport) {
@@ -705,7 +775,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
Transport transport = createTransport(createTransportOptions(), createSSLOptions());
try {
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportInitialized(Transport transport) {
@@ -1039,19 +1109,19 @@ public class TcpTransportTest extends ImperativeClientTestCase {
}
}
- protected NettyIOContext createContext(TransportOptions options, SslOptions sslOptions) {
+ protected IOContext createContext(TransportOptions options, SslOptions sslOptions) {
if (context != null) {
throw new IllegalStateException("Test already has a defined Netty IO Context");
}
- return this.context = new NettyIOContext(options, sslOptions, getTestName());
+ return this.context = new Netty4IOContext(options, sslOptions, getTestName());
}
- protected TcpTransport createTransport(TransportOptions options, SslOptions sslOptions) {
+ protected Transport createTransport(TransportOptions options, SslOptions sslOptions) {
if (context != null) {
throw new IllegalStateException("Test already has a defined Netty IO Context");
} else {
- this.context = new NettyIOContext(options, sslOptions, getTestName());
+ this.context = new Netty4IOContext(options, sslOptions, getTestName());
}
return context.newTransport();
@@ -1102,21 +1172,12 @@ public class TcpTransportTest extends ImperativeClientTestCase {
}
public class NettyTransportListener implements TransportListener {
- final boolean retainDataBufs;
-
- NettyTransportListener(boolean retainDataBufs) {
- this.retainDataBufs = retainDataBufs;
- }
@Override
public void transportRead(ProtonBuffer incoming) {
LOG.debug("Client has new incoming data of size: {}", incoming.getReadableBytes());
- data.add(incoming);
bytesRead.addAndGet(incoming.getReadableBytes());
-
- if (retainDataBufs) {
- ((ByteBuf) incoming.unwrap()).retain();
- }
+ data.add(incoming.transfer());
}
@Override
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransportTest.java
similarity index 94%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransportTest.java
index 865b3429..7927d11c 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/WebSocketTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -28,11 +28,11 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.apache.qpid.protonj2.client.test.Wait;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
@@ -40,7 +40,6 @@ import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
@@ -141,9 +140,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testConnectionsSendReceiveLargeDataWhenFrameSizeAllowsIt() throws Exception {
final int FRAME_SIZE = 8192;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -197,9 +196,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
final int FRAME_SIZE = 5317;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A' + (i % 10));
+ sendBuffer.writeByte((byte) ('A' + (i % 10)));
}
try (NettyEchoServer server = createEchoServer()) {
@@ -216,17 +215,17 @@ public class WebSocketTransportTest extends TcpTransportTest {
clientOptions.traceBytes(true);
clientOptions.webSocketMaxFrameSize(FRAME_SIZE);
- NettyTransportListener wsListener = new NettyTransportListener(true);
+ NettyTransportListener wsListener = new NettyTransportListener();
Transport transport = createTransport(clientOptions, createSSLOptions());
try {
transport.connect(HOSTNAME, port, wsListener).awaitConnect();
transports.add(transport);
if (writeAndFlush) {
- transport.writeAndFlush(ProtonByteBufferAllocator.DEFAULT.allocate());
+ transport.writeAndFlush(allocator.allocate());
transport.writeAndFlush(sendBuffer.copy());
} else {
- transport.write(ProtonByteBufferAllocator.DEFAULT.allocate());
+ transport.write(allocator.allocate());
transport.write(sendBuffer.copy());
transport.flush();
}
@@ -249,9 +248,10 @@ public class WebSocketTransportTest extends TcpTransportTest {
assertEquals(2, data.size(), "Expected 2 data packets due to separate websocket frames");
- ProtonBuffer receivedBuffer = ProtonByteBufferAllocator.DEFAULT.allocate(FRAME_SIZE);
+ ProtonBuffer receivedBuffer = ProtonBufferAllocator.defaultAllocator().allocate(FRAME_SIZE);
for (ProtonBuffer buf : data) {
- buf.readBytes(receivedBuffer, buf.getReadableBytes());
+ buf.copyInto(buf.getReadOffset(), receivedBuffer, receivedBuffer.getWriteOffset(), buf.getReadableBytes());
+ receivedBuffer.advanceWriteOffset(buf.getReadableBytes());
}
assertEquals(FRAME_SIZE, receivedBuffer.getReadableBytes(), "Unexpected data length");
@@ -269,9 +269,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testConnectionsSendReceiveLargeDataFailsDueToMaxFrameSize() throws Exception {
final int FRAME_SIZE = 1024;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -306,9 +306,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testTransportDetectsConnectionDropWhenServerEnforcesMaxFrameSize() throws Exception {
final int FRAME_SIZE = 1024;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/X509AliasKeyManagerTest.java
similarity index 98%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/X509AliasKeyManagerTest.java
index 3964938e..51393d93 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty4/X509AliasKeyManagerTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty4;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -32,6 +32,7 @@ import java.security.cert.X509Certificate;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedKeyManager;
+import org.apache.qpid.protonj2.client.transport.X509AliasKeyManager;
import org.junit.jupiter.api.Test;
public class X509AliasKeyManagerTest {
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyBlackHoleServer.java
similarity index 86%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyBlackHoleServer.java
index 0b0c1510..67b5d72d 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyBlackHoleServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyBlackHoleServer.java
@@ -14,16 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty5.channel.ChannelHandler;
+import io.netty5.channel.ChannelHandlerAdapter;
+import io.netty5.channel.ChannelHandlerContext;
public class NettyBlackHoleServer extends NettyServer {
@@ -42,7 +42,7 @@ public class NettyBlackHoleServer extends NettyServer {
return new BlackHoleInboundHandler();
}
- private class BlackHoleInboundHandler extends ChannelInboundHandlerAdapter {
+ private class BlackHoleInboundHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyEchoServer.java
similarity index 83%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyEchoServer.java
index 90c9e4de..ba86b7da 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyEchoServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyEchoServer.java
@@ -14,17 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty5.buffer.Buffer;
+import io.netty5.channel.ChannelHandler;
+import io.netty5.channel.ChannelHandlerContext;
+import io.netty5.channel.SimpleChannelInboundHandler;
/**
* Simple Netty Server used to echo all data.
@@ -42,10 +42,10 @@ public class NettyEchoServer extends NettyServer {
return new EchoServerHandler();
}
- private class EchoServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
+ private class EchoServerHandler extends SimpleChannelInboundHandler<Buffer> {
@Override
- public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
+ public void messageReceived(ChannelHandlerContext ctx, Buffer msg) {
LOG.trace("Channel read: {}", msg);
ctx.write(msg.copy());
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyIOContextTest.java
similarity index 77%
copy from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java
copy to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyIOContextTest.java
index 0d63eda0..1affaeb6 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyIOContextTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyIOContextTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -29,7 +29,7 @@ class NettyIOContextTest {
@Test
void testCannotCreateNewTransportFromShutdownBootStrap() {
- NettyIOContext context = new NettyIOContext(new TransportOptions(), new SslOptions(), "test");
+ Netty5IOContext context = new Netty5IOContext(new TransportOptions(), new SslOptions(), "test");
context.shutdown();
@@ -38,13 +38,13 @@ class NettyIOContextTest {
@Test
void testEventLoopGroupAccessibleAfterCreate() {
- NettyIOContext context = new NettyIOContext(new TransportOptions(), new SslOptions(), "test");
+ Netty5IOContext context = new Netty5IOContext(new TransportOptions(), new SslOptions(), "test");
- assertNotNull(context.eventLoop());
- assertFalse(context.eventLoop().isShutdown());
+ assertNotNull(context.ioScheduler());
+ assertFalse(context.ioScheduler().isShutdown());
context.shutdown();
- assertTrue(context.eventLoop().isShutdown());
+ assertTrue(context.ioScheduler().isShutdown());
}
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyServer.java
similarity index 67%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyServer.java
index d753c88d..2a3bbd85 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/NettyServer.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/NettyServer.java
@@ -14,14 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
-
-import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
-import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+package org.apache.qpid.protonj2.client.transport.netty5;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,38 +33,39 @@ import org.apache.qpid.protonj2.client.TransportOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-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.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;
+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.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.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
@@ -89,7 +89,7 @@ public abstract class NettyServer implements AutoCloseable {
private String webSocketPath = WEBSOCKET_PATH;
private volatile boolean fragmentWrites;
private volatile SslHandler sslHandler;
- private volatile HandshakeComplete handshakeComplete;
+ private volatile WebSocketServerHandshakeCompletionEvent handshakeComplete;
private final CountDownLatch handshakeCompletion = new CountDownLatch(1);
private final AtomicBoolean started = new AtomicBoolean();
@@ -144,7 +144,7 @@ public abstract class NettyServer implements AutoCloseable {
return handshakeCompletion.await(delayMs, TimeUnit.MILLISECONDS);
}
- public HandshakeComplete getHandshakeComplete() {
+ public WebSocketServerHandshakeCompletionEvent getHandshakeComplete() {
return handshakeComplete;
}
@@ -189,8 +189,8 @@ public abstract class NettyServer implements AutoCloseable {
if (started.compareAndSet(false, true)) {
// Configure the server.
- bossGroup = new NioEventLoopGroup(1);
- workerGroup = new NioEventLoopGroup();
+ bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
+ workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup);
@@ -212,7 +212,7 @@ public abstract class NettyServer implements AutoCloseable {
if (isWebSocketServer()) {
ch.pipeline().addLast(new HttpServerCodec());
- ch.pipeline().addLast(new HttpObjectAggregator(65536));
+ ch.pipeline().addLast(new HttpObjectAggregator<DefaultHttpContent>(65536));
ch.pipeline().addLast(new WebSocketServerProtocolHandler(getWebSocketPath(), "amqp", true, maxFrameSize));
}
@@ -223,7 +223,7 @@ public abstract class NettyServer implements AutoCloseable {
});
// Start the server.
- serverChannel = server.bind(getServerPort()).sync().channel();
+ serverChannel = server.bind(getServerPort()).asStage().get();
serverPort = ((InetSocketAddress) serverChannel.localAddress()).getPort();
}
}
@@ -233,19 +233,28 @@ public abstract class NettyServer implements AutoCloseable {
public void stop() throws InterruptedException {
if (started.compareAndSet(true, false)) {
try {
- LOG.info("Syncing channel close");
- serverChannel.close().sync();
+ LOG.info("Sync on server channel close");
+ serverChannel.close().asStage().await();
} catch (InterruptedException e) {
}
+ for (Channel channel : clients) {
+ try {
+ channel.close().asStage().await();
+ } catch (Exception ex) {}
+ }
+
+ clients.clear();
+
// Shut down all event loops to terminate all threads.
- int timeout = 100;
LOG.trace("Shutting down boss group");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).awaitUninterruptibly(timeout);
+ bossGroup.shutdownGracefully(0, 2, TimeUnit.MILLISECONDS);
+ bossGroup.awaitTermination(3, TimeUnit.MILLISECONDS);
LOG.trace("Boss group shut down");
LOG.trace("Shutting down worker group");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).awaitUninterruptibly(timeout);
+ workerGroup.shutdownGracefully(0, 2, TimeUnit.MILLISECONDS);
+ workerGroup.awaitTermination(3, TimeUnit.MILLISECONDS);
LOG.trace("Worker group shut down");
}
}
@@ -263,42 +272,48 @@ public abstract class NettyServer implements AutoCloseable {
return serverPort;
}
- private class NettyServerOutboundHandler extends ChannelOutboundHandlerAdapter {
+ public int getClientCount() {
+ return clients.size();
+ }
+
+ private class NettyServerOutboundHandler extends ChannelHandlerAdapter {
@Override
- public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
+ public Future<Void> write(ChannelHandlerContext ctx, Object msg) {
LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (isWebSocketServer() && msg instanceof ByteBuf) {
+ if (isWebSocketServer() && msg instanceof Buffer) {
if (isFragmentWrites()) {
- ByteBuf orig = (ByteBuf) msg;
- int origIndex = orig.readerIndex();
+ Buffer orig = (Buffer) msg;
+ int origIndex = orig.readerOffset();
int split = orig.readableBytes()/2;
- ByteBuf part1 = orig.copy(origIndex, split);
+ Buffer part1 = orig.copy(origIndex, split);
LOG.trace("NettyServerHandler: Part1: {}", part1);
- orig.readerIndex(origIndex + split);
+ 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);
- ctx.write(frame2, promise);
+ return ctx.write(frame2);
} else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((ByteBuf) msg);
- ctx.write(frame, promise);
+ BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
+ return ctx.write(frame);
}
} else {
- ctx.write(msg, promise);
+ return ctx.write(msg);
}
}
}
- private class NettyServerInboundHandler extends ChannelInboundHandlerAdapter {
+ private static final Set<Channel> clients = new ConcurrentSkipListSet<>();
+
+ private class NettyServerInboundHandler extends ChannelHandlerAdapter {
@Override
- public void userEventTriggered(ChannelHandlerContext context, Object payload) {
- if (payload instanceof HandshakeComplete) {
- handshakeComplete = (HandshakeComplete) payload;
+ public void channelInboundEvent(ChannelHandlerContext context, Object payload) {
+ if (payload instanceof WebSocketServerHandshakeCompletionEvent) {
+ handshakeComplete = (WebSocketServerHandshakeCompletionEvent) payload;
handshakeCompletion.countDown();
}
}
@@ -308,9 +323,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 GenericFutureListener<Future<Channel>>() {
+ handler.handshakeFuture().addListener(new FutureListener<Channel>() {
@Override
- public void operationComplete(Future<Channel> future) throws Exception {
+ public void operationComplete(Future<? extends Channel> future) throws Exception {
LOG.info("Server -> SSL handshake completed. Succeeded: {}", future.isSuccess());
if (!future.isSuccess()) {
ctx.close();
@@ -318,12 +333,15 @@ public abstract class NettyServer implements AutoCloseable {
}
});
}
+
+ clients.add(ctx.channel());
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
LOG.info("NettyServerHandler: channel has gone inactive: {}", ctx.channel());
ctx.close();
+ clients.remove(ctx.channel());
}
@Override
@@ -331,11 +349,13 @@ public abstract class NettyServer implements AutoCloseable {
LOG.trace("NettyServerHandler: Channel read: {}", msg);
if (msg instanceof WebSocketFrame) {
WebSocketFrame frame = (WebSocketFrame) msg;
- ctx.fireChannelRead(frame.content());
+ 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(HTTP_1_1, BAD_REQUEST));
+ 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);
@@ -348,7 +368,7 @@ public abstract class NettyServer implements AutoCloseable {
}
@Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ 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();
@@ -359,16 +379,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) {
- ByteBuf buf = Unpooled.copiedBuffer(response.status().toString(), StandardCharsets.UTF_8);
- response.content().writeBytes(buf);
- buf.release();
- HttpUtil.setContentLength(response, response.content().readableBytes());
+ try (Buffer buf = BufferAllocator.onHeapUnpooled().copyOf(response.status().toString().getBytes(StandardCharsets.UTF_8))) {
+ response.payload().writeBytes(buf);
+ HttpUtil.setContentLength(response, response.payload().readableBytes());
+ }
}
// Send the response and close the connection if necessary.
- ChannelFuture f = ctx.channel().writeAndFlush(response);
+ Future<Void> f = ctx.channel().writeAndFlush(response);
if (!HttpUtil.isKeepAlive(request) || response.status().code() != 200) {
- f.addListener(ChannelFutureListener.CLOSE);
+ f.addListener((channel) -> ctx.channel().close());
}
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/OpenSslTransportTest.java
similarity index 96%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/OpenSslTransportTest.java
index 2e4992cb..0d4c7ae3 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/OpenSslTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/OpenSslTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -28,17 +28,18 @@ import java.lang.reflect.Field;
import javax.net.ssl.SSLContext;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.handler.ssl.OpenSsl;
-import io.netty.handler.ssl.OpenSslEngine;
-import io.netty.handler.ssl.SslHandler;
+import io.netty5.channel.Channel;
+import io.netty5.channel.ChannelHandler;
+import io.netty5.handler.ssl.OpenSsl;
+import io.netty5.handler.ssl.OpenSslEngine;
+import io.netty5.handler.ssl.SslHandler;
/**
* Test basic functionality of the Netty based TCP Transport running in secure mode (SSL).
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SecureWebSocketTransportTest.java
similarity index 95%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SecureWebSocketTransportTest.java
index 5aa020ca..992679c8 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SecureWebSocketTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SecureWebSocketTransportTest.java
@@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.apache.qpid.protonj2.client.TransportOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupportTest.java
similarity index 94%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupportTest.java
index dbb0d84e..5984ff3b 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslSupportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -39,11 +39,11 @@ import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.test.ImperativeClientTestCase;
import org.junit.jupiter.api.Test;
-import io.netty.buffer.PooledByteBufAllocator;
-import io.netty.handler.ssl.OpenSsl;
-import io.netty.handler.ssl.OpenSslEngine;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslHandler;
+import io.netty5.buffer.BufferAllocator;
+import io.netty5.handler.ssl.OpenSsl;
+import io.netty5.handler.ssl.OpenSslEngine;
+import io.netty5.handler.ssl.SslContext;
+import io.netty5.handler.ssl.SslHandler;
/**
* Tests for the TransportSupport class.
@@ -107,7 +107,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
List<String> engineProtocols = Arrays.asList(engine.getEnabledProtocols());
@@ -375,7 +375,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
List<String> engineProtocols = Arrays.asList(engine.getEnabledProtocols());
@@ -405,7 +405,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected");
@@ -435,7 +435,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
List<String> engineProtocols = Arrays.asList(engine.getEnabledProtocols());
@@ -465,7 +465,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected");
@@ -507,7 +507,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
String[] trimmedProtocols = Arrays.copyOf(protocols, protocols.length - 1);
options.disabledProtocols(disabledProtocol);
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
// verify the option took effect
assertNotNull(engine);
@@ -558,7 +558,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
options.enabledProtocols(enabledProtocols);
options.disabledProtocols(disabledProtocol);
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
// Because Netty cannot currently disable SSLv2Hello in OpenSSL we need to account for it popping up.
ArrayList<String> remainingProtocolsList = new ArrayList<>(Arrays.asList(remainingProtocols));
@@ -610,7 +610,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
String[] enabledCipher = new String[] { cipher };
options.enabledCipherSuites(enabledCipher);
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
// verify the option took effect
assertNotNull(engine);
@@ -653,7 +653,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
String[] trimmedCiphers = Arrays.copyOf(ciphers, ciphers.length - 1);
options.disabledCipherSuites(disabledCipher);
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
// verify the option took effect
assertNotNull(engine);
@@ -704,7 +704,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
options.enabledCipherSuites(enabledCiphers);
options.disabledCipherSuites(disabledCipher);
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
// verify the option took effect, that the disabled ciphers were removed from the enabled list.
assertNotNull(engine);
@@ -735,7 +735,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
List<String> engineProtocols = Arrays.asList(engine.getEnabledProtocols());
@@ -767,7 +767,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected");
@@ -799,7 +799,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
assertEquals("HTTPS", engine.getSSLParameters().getEndpointIdentificationAlgorithm());
@@ -831,7 +831,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslContext context = SslSupport.createOpenSslContext(options);
assertNotNull(context);
- SSLEngine engine = SslSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, -1, context, options);
+ SSLEngine engine = SslSupport.createOpenSslEngine(BufferAllocator.onHeapUnpooled(), null, -1, context, options);
assertNotNull(engine);
assertNull(engine.getSSLParameters().getEndpointIdentificationAlgorithm());
@@ -927,7 +927,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
SslOptions options = new SslOptions();
options.allowNativeSSL(true);
- SslHandler handler = SslSupport.createSslHandler(PooledByteBufAllocator.DEFAULT, null, -1, options);
+ SslHandler handler = SslSupport.createSslHandler(BufferAllocator.onHeapUnpooled(), null, -1, options);
assertNotNull(handler);
assertTrue(handler.engine() instanceof OpenSslEngine);
}
@@ -1014,7 +1014,7 @@ public class SslSupportTest extends ImperativeClientTestCase {
private SSLEngine createOpenSSLEngineDirectly(SslOptions options) throws Exception {
SslContext context = SslSupport.createOpenSslContext(options);
- SSLEngine engine = context.newEngine(PooledByteBufAllocator.DEFAULT);
+ SSLEngine engine = context.newEngine(BufferAllocator.onHeapUnpooled());
return engine;
}
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslTransportTest.java
similarity index 96%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslTransportTest.java
index f4c12e00..c7e0c118 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/SslTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/SslTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -30,6 +30,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.client.SslOptions;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
@@ -123,7 +124,7 @@ public class SslTransportTest extends TcpTransportTest {
sslOptions.keyStorePassword("wrong");
Transport transport = createTransport(createTransportOptions(), sslOptions);
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportError(Throwable cause) {
@@ -160,7 +161,7 @@ public class SslTransportTest extends TcpTransportTest {
sslOptions.trustStorePassword("wrong");
Transport transport = createTransport(createTransportOptions(), sslOptions);
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportError(Throwable cause) {
@@ -228,7 +229,9 @@ public class SslTransportTest extends TcpTransportTest {
assertTrue(transport.isSecure());
// Verify there was a certificate sent to the server
- assertTrue(server.getSslHandler().handshakeFuture().await(2, TimeUnit.SECONDS), "Server handshake did not complete in allotted time");
+ server.getSslHandler().handshakeFuture().asStage().await(2, TimeUnit.SECONDS);
+
+ assertTrue(server.getSslHandler().handshakeFuture().isSuccess(), "Server handshake did not complete in allotted time");
assertNotNull(server.getSslHandler().engine().getSession().getPeerCertificates());
transport.close();
@@ -269,7 +272,9 @@ public class SslTransportTest extends TcpTransportTest {
assertTrue(transport.isConnected());
assertTrue(transport.isSecure());
- assertTrue(server.getSslHandler().handshakeFuture().await(2, TimeUnit.SECONDS), "Server handshake did not complete in allotted time");
+ server.getSslHandler().handshakeFuture().asStage().await(2, TimeUnit.SECONDS);
+
+ assertTrue(server.getSslHandler().handshakeFuture().isSuccess(), "Server handshake did not complete in allotted time");
Certificate[] peerCertificates = server.getSslHandler().engine().getSession().getPeerCertificates();
assertNotNull(peerCertificates);
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransportTest.java
similarity index 84%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransportTest.java
index 202dd31a..62f33bfd 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/TcpTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -35,30 +35,36 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.netty.Netty4ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.apache.qpid.protonj2.client.test.ImperativeClientTestCase;
import org.apache.qpid.protonj2.client.test.Wait;
+import org.apache.qpid.protonj2.client.transport.Transport;
+import org.apache.qpid.protonj2.client.transport.TransportListener;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.epoll.Epoll;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.kqueue.KQueue;
-import io.netty.channel.kqueue.KQueueEventLoopGroup;
+import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.incubator.channel.uring.IOUring;
-import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
-import io.netty.util.ResourceLeakDetector;
-import io.netty.util.ResourceLeakDetector.Level;
+import io.netty5.bootstrap.Bootstrap;
+import io.netty5.channel.IoHandler;
+import io.netty5.channel.MultithreadEventLoopGroup;
+import io.netty5.channel.SingleThreadEventLoop;
+import io.netty5.channel.epoll.Epoll;
+import io.netty5.channel.epoll.EpollHandler;
+import io.netty5.channel.kqueue.KQueue;
+import io.netty5.channel.kqueue.KQueueHandler;
+import io.netty5.util.ResourceLeakDetector;
+import io.netty5.util.ResourceLeakDetector.Level;
/**
* Test basic functionality of the Netty based TCP transport.
@@ -78,9 +84,18 @@ public class TcpTransportTest extends ImperativeClientTestCase {
protected final List<ProtonBuffer> data = new ArrayList<>();
protected final AtomicInteger bytesRead = new AtomicInteger();
- protected final TransportListener testListener = new NettyTransportListener(false);
+ protected final TransportListener testListener = new NettyTransportListener();
- protected NettyIOContext context;
+ protected ProtonBufferAllocator allocator;
+ protected Netty5IOContext context;
+
+ @Override
+ @BeforeEach
+ public void setUp(TestInfo testInfo) throws Exception {
+ super.setUp(testInfo);
+
+ allocator = new Netty4ProtonBufferAllocator(UnpooledByteBufAllocator.DEFAULT);
+ }
@Override
@AfterEach
@@ -91,6 +106,11 @@ public class TcpTransportTest extends ImperativeClientTestCase {
context.shutdown();
context = null;
}
+
+ data.removeIf((buffer) -> {
+ buffer.close();
+ return true;
+ });
}
@Test
@@ -149,19 +169,19 @@ public class TcpTransportTest extends ImperativeClientTestCase {
@Test
public void testCreateWithNullOptionsThrowsIAE() throws Exception {
try {
- new NettyIOContext(null, null, getTestName());
+ new Netty5IOContext(null, null, getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
try {
- new NettyIOContext(createTransportOptions(), null, getTestName());
+ new Netty5IOContext(createTransportOptions(), null, getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
try {
- new NettyIOContext(null, createSSLOptions(), getTestName());
+ new Netty5IOContext(null, createSSLOptions(), getTestName());
fail("Should have thrown NullPointerException");
} catch (NullPointerException npe) {
}
@@ -281,7 +301,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
List<Transport> transports = new ArrayList<>();
- NettyIOContext context = createContext(createTransportOptions(), createSSLOptions());
+ Netty5IOContext context = createContext(createTransportOptions(), createSSLOptions());
for (int i = 0; i < CONNECTION_COUNT; ++i) {
Transport transport = context.newTransport();
@@ -311,9 +331,9 @@ public class TcpTransportTest extends ImperativeClientTestCase {
final int CONNECTION_COUNT = 10;
final int FRAME_SIZE = 8;
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < 8; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -323,7 +343,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
List<Transport> transports = new ArrayList<>();
- NettyIOContext context = createContext(createTransportOptions(), createSSLOptions());
+ Netty5IOContext context = createContext(createTransportOptions(), createSSLOptions());
for (int i = 0; i < CONNECTION_COUNT; ++i) {
Transport transport = context.newTransport();
@@ -352,7 +372,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(exceptions.isEmpty());
}
- @Test
+ @RepeatedTest(1)
public void testDetectServerClose() throws Exception {
Transport transport = null;
@@ -371,7 +391,12 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- server.close();
+ assertTrue(Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return server.getClientCount() == 1;
+ }
+ }, 10000, 50));
}
final Transport connectedTransport = transport;
@@ -417,10 +442,12 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
+ final ProtonBuffer sendBuffer = allocator.allocate(0);
+
if (writeAndFlush) {
- transport.writeAndFlush(new ProtonNettyByteBuffer(Unpooled.buffer(0)));
+ transport.writeAndFlush(sendBuffer);
} else {
- transport.write(new ProtonNettyByteBuffer(Unpooled.buffer(0)));
+ transport.write(sendBuffer);
transport.flush();
}
@@ -449,10 +476,10 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonBuffer buffer = transport.getBufferAllocator().outputBuffer(64, 512);
+ ProtonBuffer buffer = transport.getBufferAllocator().allocate(64).implicitGrowthLimit(512);
assertEquals(64, buffer.capacity());
- assertEquals(512, buffer.maxCapacity());
+ assertEquals(512, buffer.implicitGrowthLimit());
transport.writeAndFlush(buffer);
@@ -481,10 +508,10 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonBuffer buffer = transport.getBufferAllocator().allocate(64, 512);
+ ProtonBuffer buffer = transport.getBufferAllocator().allocate(64).implicitGrowthLimit(512);
assertEquals(64, buffer.capacity());
- assertEquals(512, buffer.maxCapacity());
+ assertEquals(512, buffer.implicitGrowthLimit());
transport.writeAndFlush(buffer);
@@ -515,7 +542,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
ProtonBuffer sendBuffer = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
transport.write(sendBuffer, () -> LOG.debug("Netty reports write complete"));
@@ -538,6 +565,54 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(exceptions.isEmpty());
}
+ @Test
+ public void testDataSentWithinCompositeBufferIsReceived() throws Exception {
+ try (NettyEchoServer server = createEchoServer()) {
+ server.start();
+
+ int port = server.getServerPort();
+
+ Transport transport = createTransport(createTransportOptions(), createSSLOptions());
+ try {
+ transport.connect(HOSTNAME, port, testListener).awaitConnect();
+ LOG.info("Connected to server:{}:{} as expected.", HOSTNAME, port);
+ } catch (Exception e) {
+ fail("Should not have failed to connect to the server at " + HOSTNAME + ":" + port + " but got exception: " + e);
+ }
+
+ assertTrue(transport.isConnected());
+
+ ProtonBuffer sendBuffer1 = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
+ for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
+ sendBuffer1.writeByte((byte) 'A');
+ }
+ ProtonBuffer sendBuffer2 = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT + 10);
+ for (int i = 0; i < SEND_BYTE_COUNT + 10; ++i) {
+ sendBuffer2.writeByte((byte) 'A');
+ }
+
+ ProtonBuffer sendBuffer = transport.getBufferAllocator().composite(new ProtonBuffer[] { sendBuffer1, sendBuffer2});
+
+ transport.write(sendBuffer, () -> LOG.debug("Netty reports write complete"));
+ LOG.trace("Flush of Transport happens now");
+ transport.flush();
+
+ sendBuffer.close();
+
+ assertTrue(Wait.waitFor(new Wait.Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ return bytesRead.get() == SEND_BYTE_COUNT + SEND_BYTE_COUNT + 10;
+ }
+ }, 10000, 50));
+
+ transport.close();
+ }
+
+ assertTrue(!transportErrored); // Normal shutdown does not trigger the event.
+ assertTrue(exceptions.isEmpty());
+ }
+
@Test
public void testDataSentWithWriteAndFlushIsReceived() throws Exception {
try (NettyEchoServer server = createEchoServer()) {
@@ -557,7 +632,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
ProtonBuffer sendBuffer = transport.getBufferAllocator().outputBuffer(SEND_BYTE_COUNT);
for (int i = 0; i < SEND_BYTE_COUNT; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
transport.writeAndFlush(sendBuffer, () -> LOG.debug("Netty reports write complete"));
@@ -604,13 +679,14 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(transport.isConnected());
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(byteCount));
+ final ProtonBuffer sendBuffer = allocator.allocate(byteCount);
+
for (int i = 0; i < byteCount; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
for (int i = 0; i < iterations; ++i) {
- transport.writeAndFlush(sendBuffer.copy());
+ transport.writeAndFlush(sendBuffer.copy(true));
}
assertTrue(Wait.waitFor(new Wait.Condition() {
@@ -648,7 +724,8 @@ public class TcpTransportTest extends ImperativeClientTestCase {
transport.close();
- ProtonNettyByteBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(10));
+ final ProtonBuffer sendBuffer = allocator.allocate(10);
+
try {
transport.writeAndFlush(sendBuffer);
fail("Should throw on send of closed transport");
@@ -667,7 +744,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
Transport transport = createTransport(createTransportOptions(), createSSLOptions());
try {
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportInitialized(Transport transport) {
@@ -705,7 +782,7 @@ public class TcpTransportTest extends ImperativeClientTestCase {
Transport transport = createTransport(createTransportOptions(), createSSLOptions());
try {
- transport.connect(HOSTNAME, port, new NettyTransportListener(false) {
+ transport.connect(HOSTNAME, port, new NettyTransportListener() {
@Override
public void transportInitialized(Transport transport) {
@@ -822,11 +899,13 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(data.isEmpty());
}
+ @Disabled("IU_Uring support not ready for Netty 5")
@Test
public void testConnectToServerWithIOUringEnabled() throws Exception {
doTestIORingSupport(true);
}
+ @Disabled("IU_Uring support not ready for Netty 5")
@Test
public void testConnectToServerWithIOUringDisabled() throws Exception {
doTestIORingSupport(false);
@@ -867,62 +946,6 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(data.isEmpty());
}
- private void assertEpoll(String message, boolean expected, Transport transport) throws Exception {
- Field bootstrap = null;
- Class<?> transportType = transport.getClass();
-
- while (transportType != null && bootstrap == null) {
- try {
- bootstrap = transportType.getDeclaredField("bootstrap");
- } catch (NoSuchFieldException error) {
- transportType = transportType.getSuperclass();
- if (Object.class.equals(transportType)) {
- transportType = null;
- }
- }
- }
-
- assertNotNull(bootstrap, "Transport implementation unknown");
-
- bootstrap.setAccessible(true);
-
- Bootstrap transportBootstrap = (Bootstrap) bootstrap.get(transport);
-
- if (expected) {
- assertTrue(transportBootstrap.config().group() instanceof EpollEventLoopGroup, message);
- } else {
- assertFalse(transportBootstrap.config().group() instanceof EpollEventLoopGroup, message);
- }
- }
-
- private void assertIOUring(String message, boolean expected, Transport transport) throws Exception {
- Field bootstrap = null;
- Class<?> transportType = transport.getClass();
-
- while (transportType != null && bootstrap == null) {
- try {
- bootstrap = transportType.getDeclaredField("bootstrap");
- } catch (NoSuchFieldException error) {
- transportType = transportType.getSuperclass();
- if (Object.class.equals(transportType)) {
- transportType = null;
- }
- }
- }
-
- assertNotNull(bootstrap, "Transport implementation unknown");
-
- bootstrap.setAccessible(true);
-
- Bootstrap transportBootstrap = (Bootstrap) bootstrap.get(transport);
-
- if (expected) {
- assertTrue(transportBootstrap.config().group() instanceof IOUringEventLoopGroup, message);
- } else {
- assertFalse(transportBootstrap.config().group() instanceof IOUringEventLoopGroup, message);
- }
- }
-
@Test
public void testConnectToServerWithKQueueEnabled() throws Exception {
doTestKQueueSupport(true);
@@ -1014,44 +1037,19 @@ public class TcpTransportTest extends ImperativeClientTestCase {
assertTrue(data.isEmpty());
}
- private void assertKQueue(String message, boolean expected, Transport transport) throws Exception {
- Field group = null;
- Class<?> transportType = transport.getClass();
-
- while (transportType != null && group == null) {
- try {
- group = transportType.getDeclaredField("group");
- } catch (NoSuchFieldException error) {
- transportType = transportType.getSuperclass();
- if (Object.class.equals(transportType)) {
- transportType = null;
- }
- }
- }
-
- assertNotNull(group, "Transport implementation unknown");
-
- group.setAccessible(true);
- if (expected) {
- assertTrue(group.get(transport) instanceof KQueueEventLoopGroup, message);
- } else {
- assertFalse(group.get(transport) instanceof KQueueEventLoopGroup, message);
- }
- }
-
- protected NettyIOContext createContext(TransportOptions options, SslOptions sslOptions) {
+ protected Netty5IOContext createContext(TransportOptions options, SslOptions sslOptions) {
if (context != null) {
throw new IllegalStateException("Test already has a defined Netty IO Context");
}
- return this.context = new NettyIOContext(options, sslOptions, getTestName());
+ return this.context = new Netty5IOContext(options, sslOptions, getTestName());
}
- protected TcpTransport createTransport(TransportOptions options, SslOptions sslOptions) {
+ protected Transport createTransport(TransportOptions options, SslOptions sslOptions) {
if (context != null) {
throw new IllegalStateException("Test already has a defined Netty IO Context");
} else {
- this.context = new NettyIOContext(options, sslOptions, getTestName());
+ this.context = new Netty5IOContext(options, sslOptions, getTestName());
}
return context.newTransport();
@@ -1102,21 +1100,12 @@ public class TcpTransportTest extends ImperativeClientTestCase {
}
public class NettyTransportListener implements TransportListener {
- final boolean retainDataBufs;
-
- NettyTransportListener(boolean retainDataBufs) {
- this.retainDataBufs = retainDataBufs;
- }
@Override
public void transportRead(ProtonBuffer incoming) {
LOG.debug("Client has new incoming data of size: {}", incoming.getReadableBytes());
- data.add(incoming);
bytesRead.addAndGet(incoming.getReadableBytes());
-
- if (retainDataBufs) {
- ((ByteBuf) incoming.unwrap()).retain();
- }
+ data.add(incoming.transfer());
}
@Override
@@ -1136,4 +1125,68 @@ public class TcpTransportTest extends ImperativeClientTestCase {
transportInitialized = true;
}
}
+
+ private void assertEpoll(String message, boolean expected, Transport transport) throws Exception {
+ assertEventLoopIoHandlerType(message, expected, transport ,EpollHandler.class);
+ }
+
+ private void assertKQueue(String message, boolean expected, Transport transport) throws Exception {
+ assertEventLoopIoHandlerType(message, expected, transport, KQueueHandler.class);
+ }
+
+ private void assertIOUring(String message, boolean expected, Transport transport) throws Exception {
+ //assertEventLoopIoHandlerType(message, expected, transport, IOUringHandler.class);
+ fail("Netty 5 doesn't have IO_Uring support yet");
+ }
+
+ private static void assertEventLoopIoHandlerType(String message, boolean expected, Transport transport, Class<? extends IoHandler> ioHandlerClass) throws Exception {
+ Field bootstrap = null;
+ Class<?> transportType = transport.getClass();
+
+ while (transportType != null && bootstrap == null) {
+ try {
+ bootstrap = transportType.getDeclaredField("bootstrap");
+ } catch (NoSuchFieldException error) {
+ transportType = transportType.getSuperclass();
+ if (Object.class.equals(transportType)) {
+ transportType = null;
+ }
+ }
+ }
+
+ assertNotNull(bootstrap, "Transport implementation unknown");
+
+ bootstrap.setAccessible(true);
+
+ final Bootstrap transportBootstrap = (Bootstrap) bootstrap.get(transport);
+
+ assertTrue(MultithreadEventLoopGroup.class.isInstance(transportBootstrap.config().group()), message);
+ assertTrue(SingleThreadEventLoop.class.isInstance(transportBootstrap.config().group().next()), message);
+
+ Field ioHandlerField = null;
+ Class<?> executorType = transportBootstrap.config().group().next().getClass();
+
+ while (executorType != null && ioHandlerField == null) {
+ try {
+ ioHandlerField = executorType.getDeclaredField("ioHandler");
+ } catch (NoSuchFieldException error) {
+ executorType = executorType.getSuperclass();
+ if (Object.class.equals(executorType)) {
+ executorType = null;
+ }
+ }
+ }
+
+ assertNotNull(ioHandlerField, "EventLoop implementation unknown");
+
+ ioHandlerField.setAccessible(true);
+
+ final IoHandler ioHandlerRef = (IoHandler) ioHandlerField.get(transportBootstrap.config().group().next());
+
+ if (expected) {
+ assertTrue(ioHandlerClass.isInstance(ioHandlerRef), message);
+ } else {
+ assertFalse(ioHandlerClass.isInstance(ioHandlerRef), message);
+ }
+ }
}
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransportTest.java
similarity index 92%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransportTest.java
index 865b3429..a8afb0d2 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/WebSocketTransportTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransportTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -28,21 +28,19 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonNettyByteBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.SslOptions;
import org.apache.qpid.protonj2.client.TransportOptions;
import org.apache.qpid.protonj2.client.test.Wait;
+import org.apache.qpid.protonj2.client.transport.Transport;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.handler.codec.http.HttpHeaders;
-import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
+import io.netty5.bootstrap.Bootstrap;
+import io.netty5.handler.codec.http.headers.HttpHeaders;
+import io.netty5.handler.codec.http.websocketx.WebSocketServerHandshakeCompletionEvent;
/**
* Test the Netty based WebSocket Transport
@@ -141,9 +139,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testConnectionsSendReceiveLargeDataWhenFrameSizeAllowsIt() throws Exception {
final int FRAME_SIZE = 8192;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -197,9 +195,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
final int FRAME_SIZE = 5317;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A' + (i % 10));
+ sendBuffer.writeByte((byte) ('A' + (i % 10)));
}
try (NettyEchoServer server = createEchoServer()) {
@@ -216,17 +214,17 @@ public class WebSocketTransportTest extends TcpTransportTest {
clientOptions.traceBytes(true);
clientOptions.webSocketMaxFrameSize(FRAME_SIZE);
- NettyTransportListener wsListener = new NettyTransportListener(true);
+ NettyTransportListener wsListener = new NettyTransportListener();
Transport transport = createTransport(clientOptions, createSSLOptions());
try {
transport.connect(HOSTNAME, port, wsListener).awaitConnect();
transports.add(transport);
if (writeAndFlush) {
- transport.writeAndFlush(ProtonByteBufferAllocator.DEFAULT.allocate());
+ transport.writeAndFlush(allocator.allocate());
transport.writeAndFlush(sendBuffer.copy());
} else {
- transport.write(ProtonByteBufferAllocator.DEFAULT.allocate());
+ transport.write(allocator.allocate());
transport.write(sendBuffer.copy());
transport.flush();
}
@@ -249,16 +247,17 @@ public class WebSocketTransportTest extends TcpTransportTest {
assertEquals(2, data.size(), "Expected 2 data packets due to separate websocket frames");
- ProtonBuffer receivedBuffer = ProtonByteBufferAllocator.DEFAULT.allocate(FRAME_SIZE);
+ ProtonBuffer receivedBuffer = ProtonBufferAllocator.defaultAllocator().allocate(FRAME_SIZE);
for (ProtonBuffer buf : data) {
- buf.readBytes(receivedBuffer, buf.getReadableBytes());
+ buf.copyInto(buf.getReadOffset(), receivedBuffer, receivedBuffer.getWriteOffset(), buf.getReadableBytes());
+ receivedBuffer.advanceWriteOffset(buf.getReadableBytes());
}
assertEquals(FRAME_SIZE, receivedBuffer.getReadableBytes(), "Unexpected data length");
assertEquals(sendBuffer, receivedBuffer, "Unexpected data");
} finally {
for (ProtonBuffer buf : data) {
- ((ByteBuf) buf.unwrap()).release();
+ buf.close();
}
}
@@ -269,9 +268,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testConnectionsSendReceiveLargeDataFailsDueToMaxFrameSize() throws Exception {
final int FRAME_SIZE = 1024;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -306,9 +305,9 @@ public class WebSocketTransportTest extends TcpTransportTest {
public void testTransportDetectsConnectionDropWhenServerEnforcesMaxFrameSize() throws Exception {
final int FRAME_SIZE = 1024;
- ProtonBuffer sendBuffer = new ProtonNettyByteBuffer(Unpooled.buffer(FRAME_SIZE));
+ final ProtonBuffer sendBuffer = allocator.allocate(FRAME_SIZE);
for (int i = 0; i < FRAME_SIZE; ++i) {
- sendBuffer.writeByte('A');
+ sendBuffer.writeByte((byte) 'A');
}
try (NettyEchoServer server = createEchoServer()) {
@@ -378,7 +377,8 @@ public class WebSocketTransportTest extends TcpTransportTest {
assertEquals(port, transport.getPort(), "Server port is incorrect");
assertTrue(server.awaitHandshakeCompletion(2000), "HandshakeCompletion not set within given time");
- HandshakeComplete handshake = server.getHandshakeComplete();
+
+ WebSocketServerHandshakeCompletionEvent handshake = server.getHandshakeComplete();
assertNotNull(handshake, "completion should not be null");
HttpHeaders requestHeaders = handshake.requestHeaders();
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/X509AliasKeyManagerTest.java
similarity index 98%
rename from protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java
rename to protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/X509AliasKeyManagerTest.java
index 3964938e..3373422d 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/X509AliasKeyManagerTest.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/transport/netty5/X509AliasKeyManagerTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.qpid.protonj2.client.transport;
+package org.apache.qpid.protonj2.client.transport.netty5;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -32,6 +32,7 @@ import java.security.cert.X509Certificate;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedKeyManager;
+import org.apache.qpid.protonj2.client.transport.X509AliasKeyManager;
import org.junit.jupiter.api.Test;
public class X509AliasKeyManagerTest {
diff --git a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/util/ExternalMessage.java b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/util/ExternalMessage.java
index 0053e5ca..bc2e1eca 100644
--- a/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/util/ExternalMessage.java
+++ b/protonj2-client/src/test/java/org/apache/qpid/protonj2/client/util/ExternalMessage.java
@@ -28,6 +28,7 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.apache.qpid.protonj2.client.AdvancedMessage;
import org.apache.qpid.protonj2.client.Message;
import org.apache.qpid.protonj2.client.exceptions.ClientException;
@@ -156,12 +157,11 @@ public class ExternalMessage<E> implements Message<E> {
@Override
public byte[] userId() {
- byte[] copyOfUserId = null;
if (properties != null && properties.getUserId() != null) {
- copyOfUserId = properties.getUserId().arrayCopy();
+ return properties.getUserId().asByteArray();
+ } else {
+ return null;
}
-
- return copyOfUserId;
}
@Override
@@ -597,7 +597,7 @@ public class ExternalMessage<E> implements Message<E> {
}
@Override
- public ProtonBuffer encode(Map<String, Object> deliveryAnnotations) throws ClientException {
+ public ProtonBuffer encode(Map<String, Object> deliveryAnnotations, ProtonBufferAllocator allocator) throws ClientException {
return ClientMessageSupport.encodeMessage(this, deliveryAnnotations);
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferAppendBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferAppendBenchmark.java
new file mode 100644
index 00000000..82e4fde4
--- /dev/null
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferAppendBenchmark.java
@@ -0,0 +1,75 @@
+/*
+ * 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.buffer.api;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+@Fork(value = 1, warmups = 1,
+ jvmArgsPrepend = {"-Xmx1g", "-Xms1g"},
+ jvmArgsAppend = {"-dsa",
+ "-da",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+DebugNonSafepoints",
+})
+@Warmup(iterations = 1, time = 3)
+@Measurement(iterations = 1, time = 3)
+@BenchmarkMode(Mode.Throughput)
+@State(Scope.Benchmark)
+public class CompositeBufferAppendBenchmark {
+
+ final static ProtonBufferAllocator ALLOC = ProtonBufferAllocator.defaultAllocator();
+ final static String dataString = Stream.generate(() -> "x").limit(100).collect(Collectors.joining());
+ final static byte[] data = dataString.getBytes(StandardCharsets.UTF_8);
+ final static int BUFFERS = 64;
+ List<ProtonBuffer> buffers;
+
+ @Setup
+ public void setUp() {
+ buffers = new ArrayList<>(BUFFERS);
+ for (int i = 0; i < BUFFERS; i++) {
+ buffers.add(ALLOC.copy(data).convertToReadOnly());
+ }
+ }
+
+ @Benchmark
+ public void compositeBufferBenchmark() {
+ ProtonCompositeBuffer cb = ALLOC.composite();
+ for (ProtonBuffer buffer : buffers) {
+ cb.append(buffer.copy(true));
+ }
+ cb.close();
+ }
+}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferImpBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferImpBenchmark.java
new file mode 100644
index 00000000..fb49af1f
--- /dev/null
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/buffer/api/CompositeBufferImpBenchmark.java
@@ -0,0 +1,194 @@
+/*
+ * 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.buffer.api;
+
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.qpid.protonj2.buffer.ProtonBuffer;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.profile.GCProfiler;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Base for benchmarks involving {@link Map} types.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 1)
+public class CompositeBufferImpBenchmark {
+
+ public static final int DEFAULT_MAP_VALUE_RANGE = 8192;
+
+ protected final String DUMMY_STRING = "ASDFGHJ";
+ protected final Random random = new Random();
+
+ private ProtonBuffer buffer1;
+ private ProtonBuffer buffer2;
+ private ProtonBuffer buffer3;
+
+ @Setup(Level.Invocation)
+ public void init() {
+ buffer1 = ProtonBufferAllocator.defaultAllocator().allocate(64);
+ buffer2 = ProtonBufferAllocator.defaultAllocator().allocate(64);
+ buffer3 = ProtonBufferAllocator.defaultAllocator().allocate(64);
+
+ this.random.setSeed(System.currentTimeMillis());
+ }
+
+ @Benchmark
+ public void ensureWritable() {
+ final ProtonCompositeBuffer buffer = ProtonBufferAllocator.defaultAllocator().composite();
+
+ buffer.ensureWritable(64);
+ buffer.ensureWritable(64);
+ buffer.ensureWritable(64);
+ }
+
+ @Benchmark
+ public void appendAllReadable() {
+ final ProtonCompositeBuffer buffer = ProtonBufferAllocator.defaultAllocator().composite();
+
+ buffer1.setWriteOffset(buffer1.capacity());
+ buffer2.setWriteOffset(buffer2.capacity());
+ buffer3.setWriteOffset(buffer3.capacity());
+
+ buffer.append(buffer1).append(buffer2).append(buffer3);
+ }
+
+ @Benchmark
+ public void appendAllWritable() {
+ final ProtonCompositeBuffer buffer = ProtonBufferAllocator.defaultAllocator().composite();
+
+ buffer.append(buffer1).append(buffer2).append(buffer3);
+ }
+
+ @Benchmark
+ public void appendReadableWithUnreadChunks() {
+ final ProtonCompositeBuffer buffer = ProtonBufferAllocator.defaultAllocator().composite();
+
+ buffer1.setWriteOffset(buffer1.capacity());
+ buffer2.setWriteOffset(buffer2.capacity());
+ buffer3.setWriteOffset(buffer3.capacity());
+
+ buffer1.advanceReadOffset(buffer1.capacity() / 2);
+ buffer2.advanceReadOffset(buffer2.capacity() / 2);
+ buffer3.advanceReadOffset(buffer3.capacity() / 2);
+
+ buffer.append(buffer1).append(buffer2).append(buffer3);
+ }
+
+ @Benchmark
+ public void appendBufferWithWrittenChunkAndAnotherAllReadable() {
+ final ProtonCompositeBuffer buffer = ProtonBufferAllocator.defaultAllocator().composite();
+
+ buffer1.setWriteOffset(buffer1.capacity() / 2);
+ buffer2.setWriteOffset(buffer2.capacity());
+
+ buffer.append(buffer1).append(buffer2);
+ }
+
+ @Benchmark
+ public void composeSingleReadable() {
+ buffer1.advanceWriteOffset(buffer1.capacity());
+
+ final ProtonCompositeBuffer composite = ProtonBufferAllocator.defaultAllocator().composite(buffer1);
+
+ composite.capacity();
+ }
+
+ @Benchmark
+ public void composeAllReadable() {
+ buffer1.setWriteOffset(buffer1.capacity());
+ buffer2.setWriteOffset(buffer2.capacity());
+ buffer3.setWriteOffset(buffer3.capacity());
+
+ final ProtonCompositeBuffer buffer =
+ ProtonBufferAllocator.defaultAllocator().composite(new ProtonBuffer[] { buffer1, buffer2, buffer3 });
+
+ buffer.capacity();
+ }
+
+ @Benchmark
+ public void composeAllWritable() {
+ final ProtonCompositeBuffer buffer =
+ ProtonBufferAllocator.defaultAllocator().composite(new ProtonBuffer[] { buffer1, buffer2, buffer3 });
+
+ buffer.capacity();
+ }
+
+ @Benchmark
+ public void composeReadableWithUnreadChunks() {
+ buffer1.setWriteOffset(buffer1.capacity());
+ buffer2.setWriteOffset(buffer2.capacity());
+ buffer3.setWriteOffset(buffer3.capacity());
+
+ buffer1.advanceReadOffset(buffer1.capacity() / 2);
+ buffer2.advanceReadOffset(buffer2.capacity() / 2);
+ buffer3.advanceReadOffset(buffer3.capacity() / 2);
+
+ final ProtonCompositeBuffer buffer =
+ ProtonBufferAllocator.defaultAllocator().composite(new ProtonBuffer[] { buffer1, buffer2, buffer3 });
+
+ buffer.capacity();
+ }
+
+ @Benchmark
+ public void composeBufferWithWrittenChunkAndAnotherAllReadable() {
+ buffer1.setWriteOffset(buffer1.capacity() / 2);
+ buffer2.setWriteOffset(buffer2.capacity());
+
+ final ProtonCompositeBuffer buffer =
+ ProtonBufferAllocator.defaultAllocator().composite(new ProtonBuffer[] { buffer1, buffer2 });
+
+ buffer.capacity();
+ }
+
+ public static void main(String[] args) throws RunnerException {
+ runBenchmark(CompositeBufferImpBenchmark.class);
+ }
+
+ public static void runBenchmark(Class<?> benchmarkClass) throws RunnerException {
+ final Options opt = new OptionsBuilder()
+ .include(benchmarkClass.getSimpleName())
+ .addProfiler(GCProfiler.class)
+ .shouldDoGC(true)
+ .warmupIterations(5)
+ .measurementIterations(5)
+ .forks(1)
+ .build();
+
+ new Runner(opt).run();
+ }
+}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/CodecBenchmarkBase.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/CodecBenchmarkBase.java
index d26804a8..017d7e78 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/CodecBenchmarkBase.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/CodecBenchmarkBase.java
@@ -19,7 +19,7 @@ package org.apache.qpid.protonj2.codec;
import java.util.concurrent.TimeUnit;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
+import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
@@ -59,7 +59,7 @@ public abstract class CodecBenchmarkBase {
}
private void initProtonBuffer() {
- buffer = ProtonByteBufferAllocator.DEFAULT.allocate(bufferSize());
+ buffer = ProtonBufferAllocator.defaultAllocator().allocate(bufferSize());
}
public void init() {
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/ApplicationPropertiesBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/ApplicationPropertiesBenchmark.java
index 2f93a1ef..0d08653b 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/ApplicationPropertiesBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/ApplicationPropertiesBenchmark.java
@@ -59,7 +59,7 @@ public class ApplicationPropertiesBenchmark extends CodecBenchmarkBase {
@Benchmark
public ProtonBuffer decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
return buffer;
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DataBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DataBenchmark.java
index d893b66b..57f3bb8d 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DataBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DataBenchmark.java
@@ -57,7 +57,7 @@ public class DataBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
blackhole.consume(decoder.readObject(buffer, decoderState));
blackhole.consume(decoder.readObject(buffer, decoderState));
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DispositionBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DispositionBenchmark.java
index e1fbaae8..b2d3eb5f 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DispositionBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/DispositionBenchmark.java
@@ -56,7 +56,7 @@ public class DispositionBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/FlowBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/FlowBenchmark.java
index 78de6e47..0072f151 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/FlowBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/FlowBenchmark.java
@@ -58,7 +58,7 @@ public class FlowBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/HeaderBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/HeaderBenchmark.java
index af3b1dd2..cf0b3010 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/HeaderBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/HeaderBenchmark.java
@@ -52,7 +52,7 @@ public class HeaderBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/MessageAnnotationsBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/MessageAnnotationsBenchmark.java
index 6bfdd2d3..dee95f9f 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/MessageAnnotationsBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/MessageAnnotationsBenchmark.java
@@ -58,7 +58,7 @@ public class MessageAnnotationsBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/PropertiesBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/PropertiesBenchmark.java
index 26163055..66472066 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/PropertiesBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/PropertiesBenchmark.java
@@ -53,7 +53,7 @@ public class PropertiesBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/TransferBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/TransferBenchmark.java
index 002b8a0e..edc24c9b 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/TransferBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/messaging/TransferBenchmark.java
@@ -54,7 +54,7 @@ public class TransferBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readObject(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/ListOfIntBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/ListOfIntBenchmark.java
index 9a4f728c..56130b03 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/ListOfIntBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/ListOfIntBenchmark.java
@@ -54,7 +54,7 @@ public class ListOfIntBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readList(buffer, decoderState));
}
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/StringBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/StringBenchmark.java
index 6276a44e..40ac6ee1 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/StringBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/StringBenchmark.java
@@ -71,7 +71,7 @@ public class StringBenchmark extends CodecBenchmarkBase {
@Benchmark
public ProtonBuffer decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readString(buffer, decoderState));
blackhole.consume(decoder.readString(buffer, decoderState));
blackhole.consume(decoder.readString(buffer, decoderState));
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/SymbolBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/SymbolBenchmark.java
index 7cca4b90..b76a9fdf 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/SymbolBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/SymbolBenchmark.java
@@ -56,7 +56,7 @@ public class SymbolBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readSymbol(buffer, decoderState));
blackhole.consume(decoder.readSymbol(buffer, decoderState));
blackhole.consume(decoder.readSymbol(buffer, decoderState));
diff --git a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/UUIDBenchmark.java b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/UUIDBenchmark.java
index 4417ce5a..9a793b07 100644
--- a/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/UUIDBenchmark.java
+++ b/protonj2-performance-tests/src/main/java/org/apache/qpid/protonj2/codec/primitives/UUIDBenchmark.java
@@ -50,7 +50,7 @@ public class UUIDBenchmark extends CodecBenchmarkBase {
@Benchmark
public void decode() throws IOException {
- buffer.setReadIndex(0);
+ buffer.setReadOffset(0);
blackhole.consume(decoder.readUUID(buffer, decoderState));
}
diff --git a/protonj2-test-driver/pom.xml b/protonj2-test-driver/pom.xml
index 7a76433b..5b3582c1 100644
--- a/protonj2-test-driver/pom.xml
+++ b/protonj2-test-driver/pom.xml
@@ -30,23 +30,23 @@
<dependencies>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
+ <artifactId>netty5-buffer</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
+ <artifactId>netty5-common</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
+ <artifactId>netty5-handler</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
+ <artifactId>netty5-transport</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
+ <artifactId>netty5-codec-http</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
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 d0440b82..d7476f4b 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
@@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Objects;
import java.util.Queue;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -37,8 +36,9 @@ import org.apache.qpid.protonj2.test.driver.exceptions.UnexpectedPerformativeErr
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+import io.netty5.buffer.Buffer;
+import io.netty5.buffer.BufferAllocator;
+import io.netty5.channel.EventLoop;
/**
* Test driver object used to drive inputs and inspect outputs of an Engine.
@@ -58,7 +58,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
private final Consumer<ByteBuffer> frameConsumer;
private final Consumer<AssertionError> assertionConsumer;
- private final Supplier<ScheduledExecutorService> schedulerSupplier;
+ private final Supplier<EventLoop> schedulerSupplier;
private volatile AssertionError failureCause;
@@ -88,7 +88,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<ScheduledExecutorService> scheduler) {
+ public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Supplier<EventLoop> scheduler) {
this(name, frameConsumer, null, scheduler);
}
@@ -104,7 +104,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<ScheduledExecutorService> scheduler) {
+ public AMQPTestDriver(String name, Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
this.frameConsumer = frameConsumer;
this.assertionConsumer = assertionConsumer;
this.schedulerSupplier = scheduler;
@@ -207,21 +207,23 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
@Override
public void accept(ByteBuffer buffer) {
- accept(Unpooled.wrappedBuffer(buffer));
+ try (Buffer copy = BufferAllocator.onHeapUnpooled().copyOf(buffer)) {
+ accept(copy);
+ }
}
/**
- * Supply incoming bytes read to the test driver via an Netty {@link ByteBuf} instance.
+ * Supply incoming bytes read to the test driver via an Netty {@link Buffer} instance.
*
* @param buffer
- * The Netty {@link ByteBuf} that contains new incoming bytes read.
+ * The Netty {@link Buffer} that contains new incoming bytes read.
*/
- public void accept(ByteBuf buffer) {
+ public void accept(Buffer buffer) {
LOG.trace("{} processing new inbound buffer of size: {}", driverName, buffer.readableBytes());
try {
// Process off all encoded frames from this buffer one at a time.
- while (buffer.isReadable() && failureCause == null) {
+ while (buffer.readableBytes() > 0 && failureCause == null) {
LOG.trace("{} ingesting {} bytes.", driverName, buffer.readableBytes());
frameParser.ingest(buffer);
LOG.trace("{} ingestion completed cycle, remaining bytes in buffer: {}", driverName, buffer.readableBytes());
@@ -280,7 +282,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- void handleSaslPerformative(int frameSize, SaslDescribedType sasl, int channel, ByteBuf payload) throws AssertionError {
+ void handleSaslPerformative(int frameSize, SaslDescribedType sasl, int channel, Buffer payload) throws AssertionError {
synchronized (script) {
final ScriptedElement scriptEntry = script.poll();
if (scriptEntry == null) {
@@ -312,7 +314,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- void handlePerformative(int frameSize, PerformativeDescribedType amqp, int channel, ByteBuf payload) throws AssertionError {
+ void handlePerformative(int frameSize, PerformativeDescribedType amqp, int channel, Buffer payload) throws AssertionError {
switch (amqp.getPerformativeType()) {
case HEARTBEAT:
break;
@@ -364,7 +366,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");
- ScheduledExecutorService scheduler = schedulerSupplier.get();
+ EventLoop scheduler = schedulerSupplier.get();
Objects.requireNonNull(scheduler, "This driver cannot schedule delayed events, no scheduler available");
scheduler.schedule(() -> {
@@ -499,7 +501,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, ByteBuf payload) {
+ public final void sendAMQPFrame(int channel, DescribedType performative, Buffer payload) {
sendAMQPFrame(channel, performative, payload, false);
}
@@ -515,7 +517,7 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param splitWrite
* Should the data be written in multiple chunks
*/
- public void sendAMQPFrame(int channel, DescribedType performative, ByteBuf payload, boolean splitWrite) {
+ public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
LOG.trace("{} Sending performative: {}", driverName, performative);
if (performative instanceof PerformativeDescribedType) {
@@ -527,20 +529,25 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
}
}
- try {
- final ByteBuf buffer = frameEncoder.handleWrite(performative, channel, payload, null);
+ try (Buffer buffer = frameEncoder.handleWrite(performative, channel, payload, null)) {
LOG.trace("{} Writing out buffer {} to consumer: {}", driverName, buffer, frameConsumer);
if (splitWrite) {
final int bufferSplitPoint = buffer.readableBytes() / 2;
- final ByteBuf front = buffer.slice(buffer.readerIndex(), bufferSplitPoint);
- final ByteBuf rear = buffer.slice(bufferSplitPoint, buffer.readableBytes() - bufferSplitPoint);
+ final ByteBuffer front = ByteBuffer.allocate(bufferSplitPoint - buffer.readerOffset());
+ final ByteBuffer rear = ByteBuffer.allocate(buffer.readableBytes() - bufferSplitPoint);
+
+ buffer.readBytes(front);
+ buffer.readBytes(rear);
- frameConsumer.accept(front.nioBuffer());
- frameConsumer.accept(rear.nioBuffer());
+ frameConsumer.accept(front.flip());
+ frameConsumer.accept(rear.flip());
} else {
- frameConsumer.accept(buffer.nioBuffer());
+ final ByteBuffer output = ByteBuffer.allocate(buffer.readableBytes());
+ buffer.readBytes(output);
+
+ frameConsumer.accept(output.flip());
}
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
@@ -564,9 +571,11 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
LOG.trace("{} Sending sasl performative: {}", driverName, performative);
- try {
- final ByteBuf buffer = frameEncoder.handleWrite(performative, channel);
- frameConsumer.accept(buffer.nioBuffer());
+ try (Buffer buffer = frameEncoder.handleWrite(performative, channel)) {
+ final ByteBuffer output = ByteBuffer.allocate(buffer.readableBytes());
+ buffer.readBytes(output);
+
+ frameConsumer.accept(output.flip());
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not written due to error.", t));
}
@@ -594,10 +603,11 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* the channel on which to send the empty frame.
*/
public void sendEmptyFrame(int channel) {
- ByteBuf buffer = frameEncoder.handleWrite(null, channel, null, null);
+ try (Buffer buffer = frameEncoder.handleWrite(null, channel, null, null)) {
+ final ByteBuffer output = ByteBuffer.allocate(buffer.readableBytes());
+ buffer.readBytes(output);
- try {
- frameConsumer.accept(buffer.nioBuffer());
+ frameConsumer.accept(output.flip());
} catch (Throwable t) {
signalFailure(new AssertionError("Frame was not consumed due to error.", t));
}
@@ -624,10 +634,13 @@ public class AMQPTestDriver implements Consumer<ByteBuffer> {
* @param buffer
* The buffer whose contents are to be written to the frame consumer.
*/
- public void sendBytes(ByteBuf buffer) {
+ public void sendBytes(Buffer buffer) {
LOG.trace("{} Sending bytes from ProtonBuffer: {}", driverName, buffer);
- try {
- frameConsumer.accept(buffer.nioBuffer());
+ 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));
}
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 e94a170f..6d3a3aed 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
@@ -24,8 +24,8 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.PerformativeDescribe
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+import io.netty5.buffer.Buffer;
+import io.netty5.buffer.BufferAllocator;
class FrameDecoder {
@@ -49,7 +49,7 @@ class FrameDecoder {
this.driver = driver;
}
- public void ingest(ByteBuf buffer) throws AssertionError {
+ public void ingest(Buffer 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
@@ -107,7 +107,7 @@ class FrameDecoder {
*
* @throws AssertionError if an error occurs while parsing incoming data.
*/
- void parse(ByteBuf input) throws AssertionError;
+ void parse(Buffer input) throws AssertionError;
/**
* Reset the stage to its defaults for a new cycle of parsing.
@@ -130,8 +130,8 @@ class FrameDecoder {
private int headerByte;
@Override
- public void parse(ByteBuf incoming) throws AssertionError {
- while (incoming.isReadable() && headerByte < AMQPHeader.HEADER_SIZE_BYTES) {
+ public void parse(Buffer incoming) throws AssertionError {
+ while (incoming.readableBytes() > 0 && headerByte < AMQPHeader.HEADER_SIZE_BYTES) {
headerBytes[headerByte++] = incoming.readByte();
}
@@ -163,8 +163,8 @@ class FrameDecoder {
private int multiplier = FRAME_SIZE_BYTES;
@Override
- public void parse(ByteBuf input) throws AssertionError {
- while (input.isReadable()) {
+ public void parse(Buffer input) throws AssertionError {
+ while (input.readableBytes() > 0) {
frameSize |= (input.readByte() & 0xFF) << (--multiplier * Byte.SIZE);
if (multiplier == 0) {
break;
@@ -209,19 +209,23 @@ class FrameDecoder {
private class FrameBufferingStage implements FrameParserStage {
- private ByteBuf buffer;
+ private Buffer buffer;
@Override
- public void parse(ByteBuf input) throws AssertionError {
+ public void parse(Buffer input) throws AssertionError {
if (input.readableBytes() < buffer.writableBytes()) {
buffer.writeBytes(input);
} else {
- buffer.writeBytes(input, buffer.writableBytes());
+ final int remaining = buffer.writableBytes();
+
+ input.copyInto(input.readerOffset(), buffer, buffer.writerOffset(), remaining);
+ input.skipReadableBytes(remaining);
+ buffer.skipWritableBytes(remaining);
// Now we can consume the buffer frame body.
initializeFrameBodyParsingStage(buffer.readableBytes());
- try {
- stage.parse(buffer);
+ try (Buffer frame = buffer.makeReadOnly()){
+ stage.parse(frame);
} finally {
buffer = null;
}
@@ -230,7 +234,7 @@ class FrameDecoder {
@Override
public FrameBufferingStage reset(int frameSize) {
- buffer = Unpooled.buffer(frameSize, frameSize);
+ buffer = BufferAllocator.onHeapUnpooled().allocate(frameSize).implicitCapacityLimit(frameSize);
return this;
}
}
@@ -240,7 +244,7 @@ class FrameDecoder {
private int frameSize;
@Override
- public void parse(ByteBuf input) throws AssertionError {
+ public void parse(Buffer input) throws AssertionError {
int dataOffset = (input.readByte() << 2) & 0x3FF;
int frameSize = this.frameSize + FRAME_SIZE_BYTES;
@@ -251,16 +255,16 @@ class FrameDecoder {
// note that this skips over the extended header if it's present
if (dataOffset != 8) {
- input.readerIndex(input.readerIndex() + dataOffset - 8);
+ input.readerOffset(input.readerOffset() + dataOffset - 8);
}
final int frameBodySize = frameSize - dataOffset;
- ByteBuf payload = null;
+ Buffer payload = null;
Object val = null;
if (frameBodySize > 0) {
- int frameBodyStartIndex = input.readerIndex();
+ int frameBodyStartIndex = input.readerOffset();
try {
codec.decode(input);
@@ -283,12 +287,12 @@ 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.isReadable()) {
+ if (input.readableBytes() > 0) {
// Check that the remaining bytes aren't part of another frame.
- int payloadSize = frameBodySize - (input.readerIndex() - frameBodyStartIndex);
+ int payloadSize = frameBodySize - (input.readerOffset() - frameBodyStartIndex);
if (payloadSize > 0) {
- payload = input.slice(input.readerIndex(), payloadSize);
- input.skipBytes(payloadSize);
+ payload = input.copy(input.readerOffset(), payloadSize, true);
+ input.skipReadableBytes(payloadSize);
}
}
} else {
@@ -345,7 +349,7 @@ class FrameDecoder {
}
@Override
- public void parse(ByteBuf input) throws AssertionError {
+ public void parse(Buffer 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 eecba3b9..e0577695 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
@@ -19,8 +19,8 @@ package org.apache.qpid.protonj2.test.driver;
import org.apache.qpid.protonj2.test.driver.codec.Codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+import io.netty5.buffer.Buffer;
+import io.netty5.buffer.BufferAllocator;
/**
* Encodes AMQP performatives into frames for transmission
@@ -47,25 +47,26 @@ public class FrameEncoder {
this.driver = driver;
}
- public ByteBuf handleWrite(DescribedType performative, int channel, ByteBuf payload, Runnable payloadToLarge) {
+ public Buffer handleWrite(DescribedType performative, int channel, Buffer payload, Runnable payloadToLarge) {
return writeFrame(performative, payload, AMQP_FRAME_TYPE, channel, driver.getOutboundMaxFrameSize(), payloadToLarge);
}
- public ByteBuf handleWrite(DescribedType performative, int channel) {
+ public Buffer handleWrite(DescribedType performative, int channel) {
return writeFrame(performative, null, SASL_FRAME_TYPE, (short) 0, driver.getOutboundMaxFrameSize(), null);
}
- private ByteBuf writeFrame(DescribedType performative, ByteBuf payload, byte frameType, int channel, int maxFrameSize, Runnable onPayloadTooLarge) {
- int outputBufferSize = AMQP_PERFORMATIVE_PAD + (payload != null ? payload.readableBytes() : 0);
-
- ByteBuf output = Unpooled.buffer(outputBufferSize);
+ 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);
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);
if (payloadSize > 0) {
- output.writeBytes(payload, payloadSize);
+ payload.copyInto(payload.readerOffset(), output, output.writerOffset(), payloadSize);
+ payload.skipReadableBytes(payloadSize);
+ output.skipWritableBytes(payloadSize);
}
endFrame(output, frameType, channel);
@@ -73,11 +74,11 @@ public class FrameEncoder {
return output;
}
- private int writePerformative(DescribedType performative, ByteBuf payload, int maxFrameSize, ByteBuf output, Runnable onPayloadTooLarge) {
- output.writerIndex(FRAME_HEADER_SIZE);
+ private int writePerformative(DescribedType performative, Buffer payload, int maxFrameSize, Buffer output, Runnable onPayloadTooLarge) {
+ output.writerOffset(FRAME_HEADER_SIZE);
long encodedSize = 0;
- int startIndex = output.writerIndex();
+ final int startIndex = output.writerOffset();
if (performative != null) {
try {
@@ -88,7 +89,7 @@ public class FrameEncoder {
}
}
- int performativeSize = output.writerIndex() - startIndex;
+ int performativeSize = output.writerOffset() - startIndex;
if (performativeSize != encodedSize) {
throw new IllegalStateException(String.format(
@@ -106,9 +107,9 @@ public class FrameEncoder {
return performativeSize;
}
- private static void endFrame(ByteBuf output, byte frameType, int channel) {
+ private static void endFrame(Buffer output, byte frameType, int channel) {
output.setInt(FRAME_START_BYTE, output.readableBytes());
- output.setByte(FRAME_DOFF_BYTE, FRAME_DOFF_SIZE);
+ output.setByte(FRAME_DOFF_BYTE, (byte) FRAME_DOFF_SIZE);
output.setByte(FRAME_TYPE_BYTE, frameType);
output.setShort(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 617e8ae6..04e764b9 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
@@ -28,7 +28,7 @@ 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.netty.buffer.ByteBuf;
+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, ByteBuf payload);
+ protected abstract void handleTransfer(Transfer transfer, Buffer 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 aca0d6a9..d798fb4f 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
@@ -18,7 +18,6 @@ package org.apache.qpid.protonj2.test.driver;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -28,12 +27,11 @@ import org.apache.qpid.protonj2.test.driver.netty.NettyClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.EventLoop;
-import io.netty.channel.SimpleChannelInboundHandler;
+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
@@ -99,7 +97,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
client.write(frame);
}
- protected void processChannelInput(ByteBuf input) {
+ protected void processChannelInput(Buffer input) {
LOG.trace("AMQP Test Client Channel processing: {}", input);
driver.accept(input);
}
@@ -109,7 +107,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
close();
}
- protected ScheduledExecutorService eventLoop() {
+ protected EventLoop eventLoop() {
return client.eventLoop();
}
@@ -117,7 +115,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
private final class NettyAwareAMQPTestDriver extends AMQPTestDriver {
- public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<ScheduledExecutorService> scheduler) {
+ public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
super(getPeerName(), frameConsumer, assertionConsumer, scheduler);
}
@@ -128,7 +126,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
// other driver resources being used on two different threads.
@Override
- public void sendAMQPFrame(int channel, DescribedType performative, ByteBuf payload, boolean splitWrite) {
+ public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
EventLoop loop = client.eventLoop();
if (loop.inEventLoop()) {
super.sendAMQPFrame(channel, performative, payload, splitWrite);
@@ -186,7 +184,7 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
@Override
protected ChannelHandler getClientHandler() {
- return new SimpleChannelInboundHandler<ByteBuf>() {
+ return new SimpleChannelInboundHandler<Buffer>() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
@@ -195,16 +193,11 @@ public class ProtonTestClient extends ProtonTestPeer implements AutoCloseable {
}
@Override
- protected void channelRead0(ChannelHandlerContext ctx, ByteBuf input) throws Exception {
+ protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
LOG.trace("AMQP Test Client Channel read: {}", input);
- try {
- // Create a stable copy to avoid issue with retained buffer slices when input is pooled.
- ByteBuf copy = Unpooled.buffer(input.readableBytes());
- copy.writeBytes(input.nioBuffer());
- input.skipBytes(input.readableBytes());
-
- // Driver processes new data and may produce output based on this.
+ // 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);
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 1ffc857f..f3595b93 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
@@ -18,7 +18,6 @@ package org.apache.qpid.protonj2.test.driver;
import java.net.URI;
import java.nio.ByteBuffer;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -30,12 +29,11 @@ import org.apache.qpid.protonj2.test.driver.netty.NettyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.EventLoop;
-import io.netty.channel.SimpleChannelInboundHandler;
+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
@@ -162,7 +160,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
protected ChannelHandler getServerHandler() {
- return new SimpleChannelInboundHandler<ByteBuf>() {
+ return new SimpleChannelInboundHandler<Buffer>() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
@@ -171,16 +169,11 @@ public class ProtonTestServer extends ProtonTestPeer {
}
@Override
- protected void channelRead0(ChannelHandlerContext ctx, ByteBuf input) throws Exception {
+ protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
LOG.trace("AMQP Test Server Channel read: {}", input);
- try {
- // Create a stable copy to avoid issue with retained buffer slices when input is pooled.
- ByteBuf copy = Unpooled.buffer(input.readableBytes());
- copy.writeBytes(input.nioBuffer());
- input.skipBytes(input.readableBytes());
-
- // Driver processes new data and may produce output based on this.
+ // 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);
@@ -195,7 +188,7 @@ public class ProtonTestServer extends ProtonTestPeer {
private final class NettyAwareAMQPTestDriver extends AMQPTestDriver {
- public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<ScheduledExecutorService> scheduler) {
+ public NettyAwareAMQPTestDriver(Consumer<ByteBuffer> frameConsumer, Consumer<AssertionError> assertionConsumer, Supplier<EventLoop> scheduler) {
super(getPeerName(), frameConsumer, assertionConsumer, scheduler);
}
@@ -206,7 +199,7 @@ public class ProtonTestServer extends ProtonTestPeer {
// other driver resources being used on two different threads.
@Override
- public void sendAMQPFrame(int channel, DescribedType performative, ByteBuf payload, boolean splitWrite) {
+ public void sendAMQPFrame(int channel, DescribedType performative, Buffer payload, boolean splitWrite) {
EventLoop loop = server.eventLoop();
if (loop.inEventLoop()) {
super.sendAMQPFrame(channel, performative, payload, splitWrite);
@@ -259,7 +252,7 @@ public class ProtonTestServer extends ProtonTestPeer {
@Override
protected void processCloseRequest() {
try {
- server.stop();
+ server.stopAsync();
} catch (Throwable e) {
LOG.info("Error suppressed on server stop: ", e);
}
@@ -282,12 +275,12 @@ public class ProtonTestServer extends ProtonTestPeer {
close();
}
- protected void processChannelInput(ByteBuf input) {
+ protected void processChannelInput(Buffer input) {
LOG.trace("AMQP Server Channel processing: {}", input);
driver.accept(input);
}
- protected ScheduledExecutorService eventLoop() {
+ protected EventLoop 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 94211a4e..a9462136 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
@@ -19,7 +19,7 @@ package org.apache.qpid.protonj2.test.driver;
import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* Link Tracker that manages tracking of the peer Receiver link which will
@@ -32,7 +32,7 @@ public class ReceiverTracker extends LinkTracker {
}
@Override
- protected void handleTransfer(Transfer transfer, ByteBuf payload) {
+ protected void handleTransfer(Transfer transfer, Buffer 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 2c3e88cb..e9888530 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
@@ -34,7 +34,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* Entry in the test script that produces some output to be sent to the AMQP
@@ -100,47 +100,47 @@ public interface ScriptedAction extends ScriptedElement {
}
@Override
- default void handleOpen(int frameSize, Open open, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleOpen(int frameSize, Open open, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Open arrived when expecting to perform an action");
}
@Override
- default void handleBegin(int frameSize, Begin begin, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleBegin(int frameSize, Begin begin, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Begin arrived when expecting to perform an action");
}
@Override
- default void handleAttach(int frameSize, Attach attach, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleAttach(int frameSize, Attach attach, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Attach arrived when expecting to perform an action");
}
@Override
- default void handleFlow(int frameSize, Flow flow, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleFlow(int frameSize, Flow flow, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Flow arrived when expecting to perform an action");
}
@Override
- default void handleTransfer(int frameSize, Transfer transfer, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleTransfer(int frameSize, Transfer transfer, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Transfer arrived when expecting to perform an action");
}
@Override
- default void handleDisposition(int frameSize, Disposition disposition, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleDisposition(int frameSize, Disposition disposition, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Disposition arrived when expecting to perform an action");
}
@Override
- default void handleDetach(int frameSize, Detach detach, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleDetach(int frameSize, Detach detach, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("Detach arrived when expecting to perform an action");
}
@Override
- default void handleEnd(int frameSize, End end, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleEnd(int frameSize, End end, Buffer payload, int channel, AMQPTestDriver context) {
throw new AssertionError("End arrived when expecting to perform an action");
}
@Override
- default void handleClose(int frameSize, Close close, ByteBuf payload, int channel, AMQPTestDriver context) {
+ default void handleClose(int frameSize, Close close, Buffer 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 3bdacd6a..82686c15 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
@@ -19,7 +19,7 @@ package org.apache.qpid.protonj2.test.driver;
import org.apache.qpid.protonj2.test.driver.codec.transport.Flow;
import org.apache.qpid.protonj2.test.driver.codec.transport.Transfer;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* Link Tracker that manages tracking of the peer Sender link which will
@@ -32,7 +32,7 @@ public class SenderTracker extends LinkTracker {
}
@Override
- protected void handleTransfer(Transfer transfer, ByteBuf payload) {
+ protected void handleTransfer(Transfer transfer, Buffer 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 0d0d3938..8ccaef8f 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
@@ -31,7 +31,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* Tracks information related to an opened Session and its various links
@@ -319,7 +319,7 @@ public class SessionTracker {
return tracker;
}
- public LinkTracker handleTransfer(Transfer transfer, ByteBuf payload) {
+ public LinkTracker handleTransfer(Transfer transfer, Buffer payload) {
LinkTracker tracker = remoteLinks.get(transfer.getHandle());
if (tracker.isSender()) {
@@ -332,7 +332,7 @@ public class SessionTracker {
return tracker;
}
- public void handleLocalTransfer(Transfer transfer, ByteBuf payload) {
+ public void handleLocalTransfer(Transfer transfer, Buffer 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 f527067b..ce763909 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
@@ -21,7 +21,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* Abstract base used by inject actions of AMQP Performatives
@@ -139,7 +139,7 @@ public abstract class AbstractPerformativeInjectAction<P extends DescribedType>
/**
* @return the buffer containing the payload that should be sent as part of this action.
*/
- public ByteBuf getPayload() {
+ public Buffer 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 11db9b28..84663225 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
@@ -19,17 +19,17 @@ package org.apache.qpid.protonj2.test.driver.actions;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedAction;
-import io.netty.buffer.ByteBuf;
+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 ByteBuf buffer;
+ private final Buffer buffer;
private final AMQPTestDriver driver;
- public ByteBufferInjectAction(AMQPTestDriver driver, ByteBuf buffer) {
+ public ByteBufferInjectAction(AMQPTestDriver driver, Buffer 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 55e6cc6b..d00cbc05 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
@@ -19,8 +19,8 @@ package org.apache.qpid.protonj2.test.driver.actions;
import org.apache.qpid.protonj2.test.driver.AMQPTestDriver;
import org.apache.qpid.protonj2.test.driver.ScriptedAction;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+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
@@ -29,7 +29,7 @@ import io.netty.buffer.Unpooled;
public class RawBytesInjectAction implements ScriptedAction {
private final AMQPTestDriver driver;
- private ByteBuf buffer;
+ private Buffer buffer;
public RawBytesInjectAction(AMQPTestDriver driver) {
this.driver = driver;
@@ -63,7 +63,7 @@ public class RawBytesInjectAction implements ScriptedAction {
}
public RawBytesInjectAction withBytes(byte[] bytes) {
- this.buffer = Unpooled.wrappedBuffer(bytes);
+ this.buffer = BufferAllocator.onHeapUnpooled().copyOf(bytes);
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 bd699d58..24c0d562 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
@@ -47,8 +47,8 @@ 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.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
+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
@@ -59,7 +59,7 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
private final Transfer transfer = new Transfer();
private final DeliveryStateBuilder stateBuilder = new DeliveryStateBuilder();
- private ByteBuf payload;
+ private Buffer payload;
private Header header;
private DeliveryAnnotations deliveryAnnotations;
@@ -81,7 +81,7 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
}
@Override
- public ByteBuf getPayload() {
+ public Buffer getPayload() {
if (payload == null) {
payload = encodePayload();
}
@@ -212,11 +212,11 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
}
public TransferInjectAction withPayload(byte[] payload) {
- this.payload = Unpooled.wrappedBuffer(payload);
+ this.payload = BufferAllocator.onHeapUnpooled().copyOf(payload);
return this;
}
- public TransferInjectAction withPayload(ByteBuf payload) {
+ public TransferInjectAction withPayload(Buffer payload) {
this.payload = payload;
return this;
}
@@ -293,10 +293,10 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
return footer;
}
- private ByteBuf encodePayload() {
+ private Buffer encodePayload() {
org.apache.qpid.protonj2.test.driver.codec.Codec codec =
org.apache.qpid.protonj2.test.driver.codec.Codec.Factory.create();
- ByteBuf buffer = Unpooled.buffer();
+ final Buffer buffer = BufferAllocator.onHeapUnpooled().allocate(128);
if (header != null) {
codec.putDescribedType(header);
@@ -322,7 +322,7 @@ public class TransferInjectAction extends AbstractPerformativeInjectAction<Trans
codec.encode(buffer);
- return buffer;
+ return buffer.makeReadOnly();
}
protected abstract class SectionBuilder {
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyReadableBuffer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyReadableBuffer.java
deleted file mode 100644
index 4b3d0d79..00000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyReadableBuffer.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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.buffer;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.StandardCharsets;
-
-import io.netty.buffer.ByteBuf;
-
-/**
- * ReadableBuffer implementation that wraps a Netty ByteBuf
- */
-public class NettyReadableBuffer implements ReadableBuffer {
-
- private ByteBuf buffer;
-
- public NettyReadableBuffer(ByteBuf buffer) {
- this.buffer = buffer;
- }
-
- public ByteBuf getBuffer() {
- return buffer;
- }
-
- @Override
- public int capacity() {
- return buffer.capacity();
- }
-
- @Override
- public boolean hasArray() {
- return buffer.hasArray();
- }
-
- @Override
- public byte[] array() {
- return buffer.array();
- }
-
- @Override
- public int arrayOffset() {
- return buffer.arrayOffset();
- }
-
- @Override
- public ReadableBuffer reclaimRead() {
- return this;
- }
-
- @Override
- public byte get() {
- return buffer.readByte();
- }
-
- @Override
- public byte get(int index) {
- return buffer.getByte(index);
- }
-
- @Override
- public int getInt() {
- return buffer.readInt();
- }
-
- @Override
- public long getLong() {
- return buffer.readLong();
- }
-
- @Override
- public short getShort() {
- return buffer.readShort();
- }
-
- @Override
- public float getFloat() {
- return buffer.readFloat();
- }
-
- @Override
- public double getDouble() {
- return buffer.readDouble();
- }
-
- @Override
- public ReadableBuffer get(byte[] target, int offset, int length) {
- buffer.readBytes(target, offset, length);
- return this;
- }
-
- @Override
- public ReadableBuffer get(byte[] target) {
- buffer.readBytes(target);
- return this;
- }
-
- @Override
- public ReadableBuffer get(WritableBuffer target) {
- int start = target.position();
-
- if (buffer.hasArray()) {
- target.put(buffer.array(), buffer.arrayOffset() + buffer.readerIndex(), buffer.readableBytes());
- } else {
- target.put(buffer.nioBuffer());
- }
-
- int written = target.position() - start;
-
- buffer.readerIndex(buffer.readerIndex() + written);
-
- return this;
- }
-
- @Override
- public ReadableBuffer slice() {
- return new NettyReadableBuffer(buffer.slice());
- }
-
- @Override
- public ReadableBuffer flip() {
- buffer.setIndex(0, buffer.readerIndex());
- return this;
- }
-
- @Override
- public ReadableBuffer limit(int limit) {
- buffer.writerIndex(limit);
- return this;
- }
-
- @Override
- public int limit() {
- return buffer.writerIndex();
- }
-
- @Override
- public ReadableBuffer position(int position) {
- buffer.readerIndex(position);
- return this;
- }
-
- @Override
- public int position() {
- return buffer.readerIndex();
- }
-
- @Override
- public ReadableBuffer mark() {
- buffer.markReaderIndex();
- return this;
- }
-
- @Override
- public ReadableBuffer reset() {
- buffer.resetReaderIndex();
- return this;
- }
-
- @Override
- public ReadableBuffer rewind() {
- buffer.readerIndex(0);
- return this;
- }
-
- @Override
- public ReadableBuffer clear() {
- buffer.setIndex(0, buffer.capacity());
- return this;
- }
-
- @Override
- public int remaining() {
- return buffer.readableBytes();
- }
-
- @Override
- public boolean hasRemaining() {
- return buffer.isReadable();
- }
-
- @Override
- public ReadableBuffer duplicate() {
- return new NettyReadableBuffer(buffer.duplicate());
- }
-
- @Override
- public ByteBuffer byteBuffer() {
- return buffer.nioBuffer();
- }
-
- @Override
- public String readUTF8() throws CharacterCodingException {
- return buffer.toString(StandardCharsets.UTF_8);
- }
-
- @Override
- public String readString(CharsetDecoder decoder) throws CharacterCodingException {
- return buffer.toString(StandardCharsets.UTF_8);
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyWritableBuffer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyWritableBuffer.java
deleted file mode 100644
index b7f3ec8e..00000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/NettyWritableBuffer.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.buffer;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-
-/**
- * Writable Buffer implementation based on a Netty ByteBuf
- */
-public class NettyWritableBuffer implements WritableBuffer {
-
- public static final int INITIAL_CAPACITY = 1024;
-
- public ByteBuf nettyBuffer;
-
- public NettyWritableBuffer() {
- nettyBuffer = Unpooled.buffer(INITIAL_CAPACITY);
- }
-
- public NettyWritableBuffer(ByteBuf buffer) {
- nettyBuffer = buffer;
- }
-
- public ByteBuf getBuffer() {
- return nettyBuffer;
- }
-
- @Override
- public void put(byte b) {
- nettyBuffer.writeByte(b);
- }
-
- @Override
- public void putFloat(float f) {
- nettyBuffer.writeFloat(f);
- }
-
- @Override
- public void putDouble(double d) {
- nettyBuffer.writeDouble(d);
- }
-
- @Override
- public void put(byte[] src, int offset, int length) {
- nettyBuffer.writeBytes(src, offset, length);
- }
-
- @Override
- public void put(ByteBuffer payload) {
- nettyBuffer.writeBytes(payload);
- }
-
- public void put(ByteBuf payload) {
- nettyBuffer.writeBytes(payload);
- }
-
- @Override
- public void putShort(short s) {
- nettyBuffer.writeShort(s);
- }
-
- @Override
- public void putInt(int i) {
- nettyBuffer.writeInt(i);
- }
-
- @Override
- public void putLong(long l) {
- nettyBuffer.writeLong(l);
- }
-
- @Override
- public void put(String value) {
- nettyBuffer.writeCharSequence(value, StandardCharsets.UTF_8);
- }
-
- @Override
- public boolean hasRemaining() {
- return nettyBuffer.writerIndex() < nettyBuffer.maxCapacity();
- }
-
- @Override
- public int remaining() {
- return nettyBuffer.maxCapacity() - nettyBuffer.writerIndex();
- }
-
- @Override
- public void ensureRemaining(int remaining) {
- nettyBuffer.ensureWritable(remaining);
- }
-
- @Override
- public int position() {
- return nettyBuffer.writerIndex();
- }
-
- @Override
- public void position(int position) {
- nettyBuffer.writerIndex(position);
- }
-
- @Override
- public int limit() {
- return nettyBuffer.capacity();
- }
-
- @Override
- public void put(ReadableBuffer buffer) {
- buffer.get(this);
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/ReadableBuffer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/ReadableBuffer.java
deleted file mode 100644
index 49da1cfe..00000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/ReadableBuffer.java
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * 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.buffer;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.InvalidMarkException;
-import java.nio.ReadOnlyBufferException;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Interface to abstract a buffer, similar to {@link WritableBuffer}
- */
-public interface ReadableBuffer {
-
- /**
- * Returns the capacity of the backing buffer of this ReadableBuffer
- * @return the capacity of the backing buffer of this ReadableBuffer
- */
- int capacity();
-
- /**
- * Returns true if this ReadableBuffer is backed by an array which can be
- * accessed by the {@link #array()} and {@link #arrayOffset()} methods.
- *
- * @return true if the buffer is backed by a primitive array.
- */
- boolean hasArray();
-
- /**
- * Returns the primitive array that backs this buffer if one exists and the
- * buffer is not read-only. The caller should have checked the {@link #hasArray()}
- * method before calling this method.
- *
- * @return the array that backs this buffer is available.
- *
- * @throws UnsupportedOperationException if this {@link ReadableBuffer} doesn't support array access.
- * @throws ReadOnlyBufferException if the ReadableBuffer is read-only.
- */
- byte[] array();
-
- /**
- * Returns the offset into the backing array of the first element in the buffer. The caller
- * should have checked the {@link #hasArray()} method before calling this method.
- *
- * @return the offset into the backing array of the first element in the buffer.
- *
- * @throws UnsupportedOperationException if this {@link ReadableBuffer} doesn't support array access.
- * @throws ReadOnlyBufferException if the ReadableBuffer is read-only.
- */
- int arrayOffset();
-
- /**
- * Compact the backing storage of this ReadableBuffer, possibly freeing previously-read
- * portions of pooled data or reducing the number of backing arrays if present.
- * <p>
- * This is an optional operation and care should be taken in its implementation.
- *
- * @return a reference to this buffer
- */
- ReadableBuffer reclaimRead();
-
- /**
- * Reads the byte at the current position and advances the position by 1.
- *
- * @return the byte at the current position.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- byte get();
-
- /**
- * Reads the byte at the given index, the buffer position is not affected.
- *
- * @param index
- * The index in the buffer from which to read the byte.
- *
- * @return the byte value stored at the target index.
- *
- * @throws IndexOutOfBoundsException if the index is not in range for this buffer.
- */
- byte get(int index);
-
- /**
- * Reads four bytes from the buffer and returns them as an integer value. The
- * buffer position is advanced by four byes.
- *
- * @return and integer value composed of bytes read from the buffer.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- int getInt();
-
- /**
- * Reads eight bytes from the buffer and returns them as an long value. The
- * buffer position is advanced by eight byes.
- *
- * @return and long value composed of bytes read from the buffer.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- long getLong();
-
- /**
- * Reads two bytes from the buffer and returns them as an short value. The
- * buffer position is advanced by two byes.
- *
- * @return and short value composed of bytes read from the buffer.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- short getShort();
-
- /**
- * Reads four bytes from the buffer and returns them as an float value. The
- * buffer position is advanced by four byes.
- *
- * @return and float value composed of bytes read from the buffer.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- float getFloat();
-
- /**
- * Reads eight bytes from the buffer and returns them as an double value. The
- * buffer position is advanced by eight byes.
- *
- * @return and double value composed of bytes read from the buffer.
- *
- * @throws BufferUnderflowException if the buffer position has reached the limit.
- */
- double getDouble();
-
- /**
- * A bulk read method that copies bytes from this buffer into the target byte array.
- *
- * @param target
- * The byte array to copy bytes read from this buffer.
- * @param offset
- * The offset into the given array where the copy starts.
- * @param length
- * The number of bytes to copy into the target array.
- *
- * @return a reference to this ReadableBuffer instance.
- *
- * @throws BufferUnderflowException if the are less readable bytes than the array length.
- * @throws IndexOutOfBoundsException if the offset or length values are invalid.
- */
- ReadableBuffer get(final byte[] target, final int offset, final int length);
-
- /**
- * A bulk read method that copies bytes from this buffer into the target byte array.
- *
- * @param target
- * The byte array to copy bytes read from this buffer.
- *
- * @return a reference to this ReadableBuffer instance.
- *
- * @throws BufferUnderflowException if the are less readable bytes than the array length.
- */
- ReadableBuffer get(final byte[] target);
-
- /**
- * Copy data from this buffer to the target buffer starting from the current
- * position and continuing until either this buffer's remaining bytes are
- * consumed or the target is full.
- *
- * @param target
- * The WritableBuffer to transfer this buffer's data to.
- *
- * @return a reference to this ReadableBuffer instance.
- */
- ReadableBuffer get(WritableBuffer target);
-
- /**
- * Creates a new ReadableBuffer instance that is a view of the readable portion of
- * this buffer. The position will be set to zero and the limit and the reported capacity
- * will match the value returned by this buffer's {@link #remaining()} method, the mark
- * will be undefined.
- *
- * @return a new ReadableBuffer that is a view of the readable portion of this buffer.
- */
- ReadableBuffer slice();
-
- /**
- * Sets the buffer limit to the current position and the position is set to zero, the
- * mark value reset to undefined.
- *
- * @return a reference to this {@link ReadableBuffer}.
- */
- ReadableBuffer flip();
-
- /**
- * Sets the current read limit of this buffer to the given value. If the buffer mark
- * value is defined and is larger than the limit the mark will be discarded. If the
- * position is larger than the new limit it will be reset to the new limit.
- *
- * @param limit
- * The new read limit to set for this buffer.
- *
- * @return a reference to this {@link ReadableBuffer}.
- *
- * @throws IllegalArgumentException if the limit value is negative or greater than the capacity.
- */
- ReadableBuffer limit(int limit);
-
- /**
- * @return the current value of this buffer's limit.
- */
- int limit();
-
- /**
- * Sets the current position of this buffer to the given value. If the buffer mark
- * value is defined and is larger than the newly set position is must be discarded.
- *
- * @param position
- * The new position to set for this buffer.
- *
- * @return a reference to this {@link ReadableBuffer}.
- *
- * @throws IllegalArgumentException if the position value is negative or greater than the limit.
- */
- ReadableBuffer position(int position);
-
- /**
- * @return the current position from which the next read operation will start.
- */
- int position();
-
- /**
- * Mark the current position of this buffer which can be returned to after a
- * read operation by calling {@link #reset()}.
- *
- * @return a reference to this {@link ReadableBuffer}.
- */
- ReadableBuffer mark();
-
- /**
- * Reset the buffer's position to a previously marked value, the mark should remain
- * set after calling this method.
- *
- * @return a reference to this {@link ReadableBuffer}.
- *
- * @throws InvalidMarkException if the mark value is undefined.
- */
- ReadableBuffer reset();
-
- /**
- * Resets the buffer position to zero and clears and previously set mark.
- *
- * @return a reference to this {@link ReadableBuffer}.
- */
- ReadableBuffer rewind();
-
- /**
- * Resets the buffer position to zero and sets the limit to the buffer capacity,
- * the mark value is discarded if set.
- *
- * @return a reference to this {@link ReadableBuffer}.
- */
- ReadableBuffer clear();
-
- /**
- * @return the remaining number of readable bytes in this buffer.
- */
- int remaining();
-
- /**
- * @return true if there are readable bytes still remaining in this buffer.
- */
- boolean hasRemaining();
-
- /**
- * Creates a duplicate {@link ReadableBuffer} to this instance.
- * <p>
- * The duplicated buffer will have the same position, limit and mark as this
- * buffer. The two buffers share the same backing data.
- *
- * @return a duplicate of this {@link ReadableBuffer}.
- */
- ReadableBuffer duplicate();
-
- /**
- * @return a ByteBuffer view of the current readable portion of this buffer.
- */
- ByteBuffer byteBuffer();
-
- /**
- * Reads a UTF-8 encoded String from the buffer starting the decode at the
- * current position and reading until the limit is reached. The position
- * is advanced to the limit once this method returns. If there is no bytes
- * remaining in the buffer when this method is called a null is returned.
- *
- * @return a string decoded from the remaining bytes in this buffer.
- *
- * @throws CharacterCodingException if the encoding is invalid for any reason.
- */
- String readUTF8() throws CharacterCodingException;
-
- /**
- * Decodes a String from the buffer using the provided {@link CharsetDecoder}
- * starting the decode at the current position and reading until the limit is
- * reached. The position is advanced to the limit once this method returns.
- * If there is no bytes remaining in the buffer when this method is called a
- * null is returned.
- *
- * @param decoder
- * The {@link CharsetDecoder} to use when reading the string value.
- *
- * @return a string decoded from the remaining bytes in this buffer.
- *
- * @throws CharacterCodingException if the encoding is invalid for any reason.
- */
- String readString(CharsetDecoder decoder) throws CharacterCodingException;
-
- final class ByteBufferReader implements ReadableBuffer {
-
- private ByteBuffer buffer;
-
- public static ByteBufferReader allocate(int size) {
- ByteBuffer allocated = ByteBuffer.allocate(size);
- return new ByteBufferReader(allocated);
- }
-
- public static ByteBufferReader wrap(ByteBuffer buffer) {
- return new ByteBufferReader(buffer);
- }
-
- public static ByteBufferReader wrap(byte[] array) {
- return new ByteBufferReader(ByteBuffer.wrap(array));
- }
-
- public ByteBufferReader(ByteBuffer buffer) {
- this.buffer = buffer;
- }
-
- @Override
- public int capacity() {
- return buffer.capacity();
- }
-
- @Override
- public byte get() {
- return buffer.get();
- }
-
- @Override
- public byte get(int index) {
- return buffer.get(index);
- }
-
- @Override
- public int getInt() {
- return buffer.getInt();
- }
-
- @Override
- public long getLong() {
- return buffer.getLong();
- }
-
- @Override
- public short getShort() {
- return buffer.getShort();
- }
-
- @Override
- public float getFloat() {
- return buffer.getFloat();
- }
-
- @Override
- public double getDouble() {
- return buffer.getDouble();
- }
-
- @Override
- public int limit() {
- return buffer.limit();
- }
-
- @Override
- public ReadableBuffer get(byte[] data, int offset, int length) {
- buffer.get(data, offset, length);
- return this;
- }
-
- @Override
- public ReadableBuffer get(byte[] data) {
- buffer.get(data);
- return this;
- }
-
- @Override
- public ReadableBuffer flip() {
- buffer.flip();
- return this;
- }
-
- @Override
- public ReadableBuffer position(int position) {
- buffer.position(position);
- return this;
- }
-
- @Override
- public ReadableBuffer slice() {
- return new ByteBufferReader(buffer.slice());
- }
-
- @Override
- public ReadableBuffer limit(int limit) {
- buffer.limit(limit);
- return this;
- }
-
- @Override
- public int remaining() {
- return buffer.remaining();
- }
-
- @Override
- public int position() {
- return buffer.position();
- }
-
- @Override
- public boolean hasRemaining() {
- return buffer.hasRemaining();
- }
-
- @Override
- public ReadableBuffer duplicate() {
- return new ByteBufferReader(buffer.duplicate());
- }
-
- @Override
- public ByteBuffer byteBuffer() {
- return buffer;
- }
-
- @Override
- public String readUTF8() {
- return StandardCharsets.UTF_8.decode(buffer).toString();
- }
-
- @Override
- public String readString(CharsetDecoder decoder) throws CharacterCodingException {
- return decoder.decode(buffer).toString();
- }
-
- @Override
- public boolean hasArray() {
- return buffer.hasArray();
- }
-
- @Override
- public byte[] array() {
- return buffer.array();
- }
-
- @Override
- public int arrayOffset() {
- return buffer.arrayOffset();
- }
-
- @Override
- public ReadableBuffer reclaimRead() {
- // Don't compact ByteBuffer due to the expense of the copy
- return this;
- }
-
- @Override
- public ReadableBuffer mark() {
- buffer.mark();
- return this;
- }
-
- @Override
- public ReadableBuffer reset() {
- buffer.reset();
- return this;
- }
-
- @Override
- public ReadableBuffer rewind() {
- buffer.rewind();
- return this;
- }
-
- @Override
- public ReadableBuffer clear() {
- buffer.clear();
- return this;
- }
-
- @Override
- public ReadableBuffer get(WritableBuffer target) {
- target.put(buffer);
- return this;
- }
-
- @Override
- public String toString() {
- return buffer.toString();
- }
-
- @Override
- public int hashCode() {
- return buffer.hashCode();
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
-
- if (!(other instanceof ReadableBuffer)) {
- return false;
- }
-
- ReadableBuffer readable = (ReadableBuffer) other;
- if (this.remaining() != readable.remaining()) {
- return false;
- }
-
- return buffer.equals(readable.byteBuffer());
- }
- }
-}
\ No newline at end of file
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/WritableBuffer.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/WritableBuffer.java
deleted file mode 100644
index c0558e73..00000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/buffer/WritableBuffer.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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.buffer;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-
-public interface WritableBuffer {
-
- void put(byte b);
-
- void putFloat(float f);
-
- void putDouble(double d);
-
- void put(byte[] src, int offset, int length);
-
- void putShort(short s);
-
- void putInt(int i);
-
- void putLong(long l);
-
- boolean hasRemaining();
-
- default void ensureRemaining(int requiredRemaining) {
- // No-op to allow for drop in updates
- }
-
- int remaining();
-
- int position();
-
- void position(int position);
-
- void put(ByteBuffer payload);
-
- void put(ReadableBuffer payload);
-
- default void put(final String value) {
- final int length = value.length();
-
- for (int i = 0; i < length; i++) {
- int c = value.charAt(i);
- if ((c & 0xFF80) == 0) {
- // U+0000..U+007F
- put((byte) c);
- } else if ((c & 0xF800) == 0) {
- // U+0080..U+07FF
- put((byte) (0xC0 | ((c >> 6) & 0x1F)));
- put((byte) (0x80 | (c & 0x3F)));
- } else if ((c & 0xD800) != 0xD800 || (c > 0xDBFF)) {
- // U+0800..U+FFFF - excluding surrogate pairs
- put((byte) (0xE0 | ((c >> 12) & 0x0F)));
- put((byte) (0x80 | ((c >> 6) & 0x3F)));
- put((byte) (0x80 | (c & 0x3F)));
- } else {
- int low;
-
- if ((++i == length) || ((low = value.charAt(i)) & 0xDC00) != 0xDC00) {
- throw new IllegalArgumentException("String contains invalid Unicode code points");
- }
-
- c = 0x010000 + ((c & 0x03FF) << 10) + (low & 0x03FF);
-
- put((byte) (0xF0 | ((c >> 18) & 0x07)));
- put((byte) (0x80 | ((c >> 12) & 0x3F)));
- put((byte) (0x80 | ((c >> 6) & 0x3F)));
- put((byte) (0x80 | (c & 0x3F)));
- }
- }
- }
-
- int limit();
-
- class ByteBufferWrapper implements WritableBuffer {
- private final ByteBuffer _buf;
-
- public ByteBufferWrapper(ByteBuffer buf) {
- _buf = buf;
- }
-
- @Override
- public void put(byte b) {
- _buf.put(b);
- }
-
- @Override
- public void putFloat(float f) {
- _buf.putFloat(f);
- }
-
- @Override
- public void putDouble(double d) {
- _buf.putDouble(d);
- }
-
- @Override
- public void put(byte[] src, int offset, int length) {
- _buf.put(src, offset, length);
- }
-
- @Override
- public void putShort(short s) {
- _buf.putShort(s);
- }
-
- @Override
- public void putInt(int i) {
- _buf.putInt(i);
- }
-
- @Override
- public void putLong(long l) {
- _buf.putLong(l);
- }
-
- @Override
- public boolean hasRemaining() {
- return _buf.hasRemaining();
- }
-
- @Override
- public void ensureRemaining(int remaining) {
- if (remaining < 0) {
- throw new IllegalArgumentException("Required remaining bytes cannot be negative");
- }
-
- if (_buf.remaining() < remaining) {
- IndexOutOfBoundsException cause = new IndexOutOfBoundsException(String.format(
- "Requested min remaining bytes(%d) exceeds remaining(%d) in underlying ByteBuffer: %s",
- remaining, _buf.remaining(), _buf));
-
- throw (BufferOverflowException) new BufferOverflowException().initCause(cause);
- }
- }
-
- @Override
- public int remaining() {
- return _buf.remaining();
- }
-
- @Override
- public int position() {
- return _buf.position();
- }
-
- @Override
- public void position(int position) {
- _buf.position(position);
- }
-
- @Override
- public void put(ByteBuffer src) {
- _buf.put(src);
- }
-
- @Override
- public void put(ReadableBuffer src) {
- src.get(this);
- }
-
- @Override
- public void put(final String value) {
- final int length = value.length();
-
- int pos = _buf.position();
-
- for (int i = 0; i < length; i++) {
- int c = value.charAt(i);
- try {
- if ((c & 0xFF80) == 0) {
- // U+0000..U+007F
- put(pos++, (byte) c);
- } else if ((c & 0xF800) == 0) {
- // U+0080..U+07FF
- put(pos++, (byte) (0xC0 | ((c >> 6) & 0x1F)));
- put(pos++, (byte) (0x80 | (c & 0x3F)));
- } else if ((c & 0xD800) != 0xD800 || (c > 0xDBFF)) {
- // U+0800..U+FFFF - excluding surrogate pairs
- put(pos++, (byte) (0xE0 | ((c >> 12) & 0x0F)));
- put(pos++, (byte) (0x80 | ((c >> 6) & 0x3F)));
- put(pos++, (byte) (0x80 | (c & 0x3F)));
- } else {
- int low;
-
- if ((++i == length) || ((low = value.charAt(i)) & 0xDC00) != 0xDC00) {
- throw new IllegalArgumentException("String contains invalid Unicode code points");
- }
-
- c = 0x010000 + ((c & 0x03FF) << 10) + (low & 0x03FF);
-
- put(pos++, (byte) (0xF0 | ((c >> 18) & 0x07)));
- put(pos++, (byte) (0x80 | ((c >> 12) & 0x3F)));
- put(pos++, (byte) (0x80 | ((c >> 6) & 0x3F)));
- put(pos++, (byte) (0x80 | (c & 0x3F)));
- }
- }
- catch(IndexOutOfBoundsException ioobe) {
- throw new BufferOverflowException();
- }
- }
-
- // Now move the buffer position to reflect the work done here
- _buf.position(pos);
- }
-
- @Override
- public int limit() {
- return _buf.limit();
- }
-
- public ByteBuffer byteBuffer() {
- return _buf;
- }
-
- public ReadableBuffer toReadableBuffer() {
- return ReadableBuffer.ByteBufferReader.wrap((ByteBuffer) _buf.duplicate().flip());
- }
-
- @Override
- public String toString() {
- return String.format("[pos: %d, limit: %d, remaining:%d]", _buf.position(), _buf.limit(), _buf.remaining());
- }
-
- public static ByteBufferWrapper allocate(int size) {
- ByteBuffer allocated = ByteBuffer.allocate(size);
- return new ByteBufferWrapper(allocated);
- }
-
- public static ByteBufferWrapper wrap(ByteBuffer buffer) {
- return new ByteBufferWrapper(buffer);
- }
-
- public static ByteBufferWrapper wrap(byte[] bytes) {
- return new ByteBufferWrapper(ByteBuffer.wrap(bytes));
- }
-
- private void put(int index, byte value) {
- if (_buf.hasArray()) {
- _buf.array()[_buf.arrayOffset() + index] = value;
- } else {
- _buf.put(index, value);
- }
- }
- }
-}
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 a2a3e887..c705fdda 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
@@ -19,7 +19,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class ArrayElement extends AbstractElement<Object[]> {
@@ -151,12 +151,12 @@ class ArrayElement extends AbstractElement<Object[]> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
final int count = (int) count();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
if (!isElementOfArray()) {
if (size > 257 || count > 255) {
buffer.writeByte((byte) 0xf0);
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 07559af2..1d883227 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class BinaryElement extends AtomicElement<Binary> {
@@ -68,9 +68,9 @@ class BinaryElement extends AtomicElement<Binary> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() < size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
return 0;
}
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 2aaed6d8..93adb3dd 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class BooleanElement extends AtomicElement<Boolean> {
@@ -46,8 +46,8 @@ class BooleanElement extends AtomicElement<Boolean> {
}
@Override
- public int encode(ByteBuf buffer) {
- if (buffer.isWritable()) {
+ public int encode(Buffer buffer) {
+ if (buffer.writableBytes() > 0) {
if (isElementOfArray()) {
buffer.writeByte(value ? (byte) 1 : (byte) 0);
} else {
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 59d6c431..2cfe9b9d 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class ByteElement extends AtomicElement<Byte> {
@@ -43,14 +43,14 @@ class ByteElement extends AtomicElement<Byte> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
if (isElementOfArray()) {
- if (buffer.isWritable()) {
+ if (buffer.writableBytes() > 0) {
buffer.writeByte(value);
return 1;
}
} else {
- if (buffer.maxWritableBytes() >= 2) {
+ if ((buffer.implicitCapacityLimit() - buffer.capacity()) >= 2) {
buffer.writeByte((byte) 0x51);
buffer.writeByte(value);
return 2;
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 036b96a6..51e0a1c4 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class CharElement extends AtomicElement<Integer> {
@@ -43,9 +43,9 @@ class CharElement extends AtomicElement<Integer> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
final int size = size();
- if (size <= buffer.maxWritableBytes()) {
+ if (size <= buffer.implicitCapacityLimit() - buffer.capacity()) {
if (size == 5) {
buffer.writeByte((byte) 0x73);
}
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 b44d2e4b..c6055302 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
@@ -32,7 +32,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public interface Codec {
@@ -91,9 +91,9 @@ public interface Codec {
long encodedSize();
- long encode(ByteBuf buffer);
+ long encode(Buffer buffer);
- long decode(ByteBuf buffer);
+ long decode(Buffer buffer);
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 f1b358fb..0eabbc03 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
@@ -32,7 +32,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class CodecImpl implements Codec {
@@ -124,12 +124,12 @@ public class CodecImpl implements Codec {
}
@Override
- public long encode(ByteBuf buffer) {
+ public long encode(Buffer buffer) {
Element<?> elt = first;
int size = 0;
while (elt != null) {
final int eltSize = elt.size();
- if (eltSize <= buffer.maxWritableBytes()) {
+ if (eltSize <= buffer.implicitCapacityLimit()) {
size += elt.encode(buffer);
} else {
size += eltSize;
@@ -140,7 +140,7 @@ public class CodecImpl implements Codec {
}
@Override
- public long decode(ByteBuf buffer) {
+ public long decode(Buffer buffer) {
return TypeDecoder.decode(buffer, this);
}
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 b2818ce5..608a0adf 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal128;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class Decimal128Element extends AtomicElement<Decimal128> {
@@ -45,9 +45,9 @@ class Decimal128Element extends AtomicElement<Decimal128> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
if (size == 17) {
buffer.writeByte((byte) 0x94);
}
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 9e2dd5ab..887d0c6f 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal32;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class Decimal32Element extends AtomicElement<Decimal32> {
@@ -45,9 +45,9 @@ class Decimal32Element extends AtomicElement<Decimal32> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
if (size == 5) {
buffer.writeByte((byte) 0x74);
}
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 0de83755..a0eda734 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Decimal64;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class Decimal64Element extends AtomicElement<Decimal64> {
@@ -45,9 +45,9 @@ class Decimal64Element extends AtomicElement<Decimal64> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
if (size == 9) {
buffer.writeByte((byte) 0x84);
}
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 847b6eb5..a94c4364 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class DescribedTypeElement extends AbstractElement<DescribedType> {
@@ -68,10 +68,10 @@ class DescribedTypeElement extends AbstractElement<DescribedType> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int encodedSize = size();
- if (encodedSize > buffer.maxWritableBytes()) {
+ if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
} else {
buffer.writeByte((byte) 0);
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 8fce6898..3ae02139 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class DoubleElement extends AtomicElement<Double> {
@@ -43,9 +43,9 @@ class DoubleElement extends AtomicElement<Double> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= size) {
if (size == 9) {
buffer.writeByte((byte) 0x82);
}
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 b2b7f03b..c94c3489 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
interface Element<T> {
@@ -26,7 +26,7 @@ interface Element<T> {
Codec.DataType getDataType();
- int encode(ByteBuf buffer);
+ int encode(Buffer buffer);
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 36a61eaf..2ca919af 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class FloatElement extends AtomicElement<Float> {
@@ -43,9 +43,9 @@ class FloatElement extends AtomicElement<Float> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() >= size) {
if (size == 5) {
buffer.writeByte((byte) 0x72);
}
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 36295436..ae657946 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class IntegerElement extends AtomicElement<Integer> {
@@ -57,9 +57,9 @@ class IntegerElement extends AtomicElement<Integer> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (size <= buffer.maxWritableBytes()) {
+ if (size <= buffer.implicitCapacityLimit() - buffer.capacity()) {
switch (size) {
case 2:
buffer.writeByte((byte) 0x54);
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 5a0eea7f..2e1a4870 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
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class ListElement extends AbstractElement<List<Object>> {
@@ -99,7 +99,7 @@ class ListElement extends AbstractElement<List<Object>> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int encodedSize = size();
int count = 0;
@@ -111,7 +111,7 @@ class ListElement extends AbstractElement<List<Object>> {
elt = elt.next();
}
- if (encodedSize > buffer.maxWritableBytes()) {
+ if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
} else {
if (isElementOfArray()) {
@@ -138,7 +138,6 @@ class ListElement extends AbstractElement<List<Object>> {
buffer.writeInt((size + 4));
buffer.writeInt(count);
}
-
}
elt = first;
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 563854ef..6349c820 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class LongElement extends AtomicElement<Long> {
@@ -59,9 +59,9 @@ class LongElement extends AtomicElement<Long> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (size > buffer.maxWritableBytes()) {
+ if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
}
switch (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 0f5db681..e3f4fbe8 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
@@ -20,7 +20,7 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class MapElement extends AbstractElement<Map<Object, Object>> {
@@ -100,7 +100,7 @@ class MapElement extends AbstractElement<Map<Object, Object>> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int encodedSize = size();
int count = 0;
@@ -112,7 +112,7 @@ class MapElement extends AbstractElement<Map<Object, Object>> {
elt = elt.next();
}
- if (encodedSize > buffer.maxWritableBytes()) {
+ if (encodedSize > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
} else {
if (isElementOfArray()) {
@@ -139,7 +139,6 @@ class MapElement extends AbstractElement<Map<Object, Object>> {
buffer.writeInt((size + 4));
buffer.writeInt(count);
}
-
}
elt = first;
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 557a3fde..675c9da4 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class NullElement extends AtomicElement<Void> {
@@ -40,8 +40,8 @@ class NullElement extends AtomicElement<Void> {
}
@Override
- public int encode(ByteBuf buffer) {
- if (buffer.isWritable() && !isElementOfArray()) {
+ public int encode(Buffer buffer) {
+ if (buffer.writableBytes() > 0 && !isElementOfArray()) {
buffer.writeByte((byte) 0x40);
return 1;
}
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 eb27af65..58680420 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,7 @@
*/
package org.apache.qpid.protonj2.test.driver.codec;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class ShortElement extends AtomicElement<Short> {
@@ -43,14 +43,14 @@ class ShortElement extends AtomicElement<Short> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
if (isElementOfArray()) {
- if (buffer.maxWritableBytes() >= 2) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
buffer.writeShort(value);
return 2;
}
} else {
- if (buffer.maxWritableBytes() >= 3) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= 3) {
buffer.writeByte((byte) 0x61);
buffer.writeShort(value);
return 3;
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 41f4ffe1..895b279e 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import java.nio.charset.Charset;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class StringElement extends AtomicElement<String> {
@@ -71,12 +71,12 @@ class StringElement extends AtomicElement<String> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
final byte[] bytes = value.getBytes(UTF_8);
final int length = bytes.length;
int size = size(length);
- if (buffer.maxWritableBytes() < size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
return 0;
}
if (isElementOfArray()) {
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 9f914fb6..7fb28766 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
@@ -20,7 +20,7 @@ import java.nio.charset.Charset;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class SymbolElement extends AtomicElement<Symbol> {
@@ -69,9 +69,9 @@ class SymbolElement extends AtomicElement<Symbol> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() < size) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() < size) {
return 0;
}
if (isElementOfArray()) {
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 604ce4ff..abdd51c7 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import java.util.Date;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class TimestampElement extends AtomicElement<Date> {
@@ -45,9 +45,9 @@ class TimestampElement extends AtomicElement<Date> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (size > buffer.maxWritableBytes()) {
+ if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
}
if (size == 9) {
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 86eb1e6d..e532ddc7 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
@@ -29,7 +29,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class TypeDecoder {
@@ -96,31 +96,31 @@ class TypeDecoder {
Codec.DataType getType();
- int size(ByteBuf buffer);
+ int size(Buffer buffer);
- void parse(ByteBuf buffer, Codec data);
+ void parse(Buffer buffer, Codec data);
}
- static int decode(ByteBuf buffer, Codec data) {
- if (buffer.isReadable()) {
- int position = buffer.readerIndex();
- TypeConstructor c = readConstructor(buffer);
+ 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.readerIndex(position);
+ buffer.readerOffset(position);
return -4;
}
}
return 0;
}
- private static TypeConstructor readConstructor(ByteBuf buffer) {
- int index = buffer.readByte() & 0xff;
- TypeConstructor tc = constructors[index];
+ private static TypeConstructor readConstructor(Buffer buffer) {
+ final int index = buffer.readByte() & 0xff;
+ final TypeConstructor tc = constructors[index];
if (tc == null) {
throw new IllegalArgumentException("No constructor for type " + index);
}
@@ -135,12 +135,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putNull();
}
}
@@ -153,12 +153,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putBoolean(true);
}
}
@@ -171,12 +171,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putBoolean(false);
}
}
@@ -189,12 +189,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedInteger(UnsignedInteger.ZERO);
}
}
@@ -207,12 +207,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedLong(UnsignedLong.ZERO);
}
}
@@ -225,12 +225,12 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 0;
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putList();
}
}
@@ -239,7 +239,7 @@ class TypeDecoder {
private static abstract class Fixed0SizeConstructor implements TypeConstructor {
@Override
- public final int size(ByteBuf buffer) {
+ public final int size(Buffer buffer) {
return 0;
}
}
@@ -247,7 +247,7 @@ class TypeDecoder {
private static abstract class Fixed1SizeConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 1;
}
}
@@ -255,7 +255,7 @@ class TypeDecoder {
private static abstract class Fixed2SizeConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 2;
}
}
@@ -263,7 +263,7 @@ class TypeDecoder {
private static abstract class Fixed4SizeConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 4;
}
}
@@ -271,7 +271,7 @@ class TypeDecoder {
private static abstract class Fixed8SizeConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 8;
}
}
@@ -279,7 +279,7 @@ class TypeDecoder {
private static abstract class Fixed16SizeConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
+ public int size(Buffer buffer) {
return 16;
}
}
@@ -292,7 +292,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedByte(UnsignedByte.valueOf(buffer.readByte()));
}
}
@@ -305,7 +305,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putByte(buffer.readByte());
}
}
@@ -318,7 +318,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedInteger(UnsignedInteger.valueOf((buffer.readByte()) & 0xff));
}
}
@@ -331,7 +331,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putInt(buffer.readByte());
}
}
@@ -344,7 +344,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedLong(UnsignedLong.valueOf((buffer.readByte()) & 0xff));
}
}
@@ -357,7 +357,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putLong(buffer.readByte());
}
}
@@ -370,8 +370,8 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int i = buffer.readByte();
+ public void parse(Buffer buffer, Codec data) {
+ final int i = buffer.readByte();
if (i != 0 && i != 1) {
throw new IllegalArgumentException("Illegal value " + i + " for boolean");
}
@@ -387,7 +387,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedShort(UnsignedShort.valueOf(buffer.readShort()));
}
}
@@ -400,7 +400,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putShort(buffer.readShort());
}
}
@@ -413,7 +413,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedInteger(UnsignedInteger.valueOf(buffer.readInt()));
}
}
@@ -426,7 +426,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putInt(buffer.readInt());
}
}
@@ -439,7 +439,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putFloat(buffer.readFloat());
}
}
@@ -452,7 +452,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putChar(buffer.readInt());
}
}
@@ -465,7 +465,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putDecimal32(new Decimal32(buffer.readInt()));
}
}
@@ -478,7 +478,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUnsignedLong(UnsignedLong.valueOf(buffer.readLong()));
}
}
@@ -491,7 +491,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putLong(buffer.readLong());
}
}
@@ -504,7 +504,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putDouble(buffer.readDouble());
}
}
@@ -517,7 +517,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putTimestamp(new Date(buffer.readLong()));
}
}
@@ -530,7 +530,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putDecimal64(new Decimal64(buffer.readLong()));
}
}
@@ -543,7 +543,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putDecimal128(new Decimal128(buffer.readLong(), buffer.readLong()));
}
}
@@ -556,7 +556,7 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putUUID(new UUID(buffer.readLong(), buffer.readLong()));
}
}
@@ -564,11 +564,11 @@ class TypeDecoder {
private static abstract class SmallVariableConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
- int position = buffer.readerIndex();
- if (buffer.isReadable()) {
- int size = buffer.readByte() & 0xff;
- buffer.readerIndex(position);
+ public int size(Buffer buffer) {
+ final int position = buffer.readerOffset();
+ if (buffer.readableBytes() > 0) {
+ final int size = buffer.readByte() & 0xff;
+ buffer.readerOffset(position);
return size + 1;
} else {
@@ -581,11 +581,11 @@ class TypeDecoder {
private static abstract class VariableConstructor implements TypeConstructor {
@Override
- public int size(ByteBuf buffer) {
- int position = buffer.readerIndex();
+ public int size(Buffer buffer) {
+ final int position = buffer.readerOffset();
if (buffer.readableBytes() >= 4) {
- int size = buffer.readInt();
- buffer.readerIndex(position);
+ final int size = buffer.readInt();
+ buffer.readerOffset(position);
return size + 4;
} else {
@@ -603,10 +603,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readByte() & 0xff;
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readByte() & 0xff;
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putBinary(bytes);
}
}
@@ -619,10 +619,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readByte() & 0xff;
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readByte() & 0xff;
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putSymbol(Symbol.valueOf(new String(bytes, ASCII)));
}
}
@@ -635,10 +635,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readByte() & 0xff;
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readByte() & 0xff;
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putString(new String(bytes, UTF_8));
}
}
@@ -651,10 +651,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readInt();
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readInt();
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putBinary(bytes);
}
}
@@ -667,10 +667,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readInt();
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readInt();
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putSymbol(Symbol.valueOf(new String(bytes, ASCII)));
}
}
@@ -683,10 +683,10 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
- int size = buffer.readInt();
- byte[] bytes = new byte[size];
- buffer.readBytes(bytes);
+ public void parse(Buffer buffer, Codec data) {
+ final int size = buffer.readInt();
+ final byte[] bytes = new byte[size];
+ buffer.readBytes(bytes, 0, bytes.length);
data.putString(new String(bytes, UTF_8));
}
}
@@ -699,13 +699,14 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
int size = buffer.readByte() & 0xff;
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readByte() & 0xff;
- data.putList();
- parseChildren(data, buf, count);
+ try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
+ buffer.skipReadableBytes(size);
+ final int count = buf.readByte() & 0xff;
+ data.putList();
+ parseChildren(data, buf, count);
+ }
}
}
@@ -717,13 +718,14 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
int size = buffer.readByte() & 0xff;
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readByte() & 0xff;
- data.putMap();
- parseChildren(data, buf, count);
+ try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
+ buffer.skipReadableBytes(size);
+ final int count = buf.readByte() & 0xff;
+ data.putMap();
+ parseChildren(data, buf, count);
+ }
}
}
@@ -735,13 +737,14 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
int size = buffer.readInt();
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readInt();
- data.putList();
- parseChildren(data, buf, count);
+ try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
+ buffer.skipReadableBytes(size);
+ final int count = buf.readInt();
+ data.putList();
+ parseChildren(data, buf, count);
+ }
}
}
@@ -753,20 +756,21 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
int size = buffer.readInt();
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readInt();
- data.putMap();
- parseChildren(data, buf, count);
+ try (Buffer buf = buffer.copy(buffer.readerOffset(), size, true)) {
+ buffer.skipReadableBytes(size);
+ final int count = buf.readInt();
+ data.putMap();
+ parseChildren(data, buf, count);
+ }
}
}
- private static void parseChildren(Codec data, ByteBuf buf, int count) {
+ private static void parseChildren(Codec data, Buffer buf, int count) {
data.enter();
for (int i = 0; i < count; i++) {
- TypeConstructor c = readConstructor(buf);
+ final TypeConstructor c = readConstructor(buf);
final int size = c.size(buf);
final int getReadableBytes = buf.readableBytes();
if (size <= getReadableBytes) {
@@ -787,25 +791,26 @@ class TypeDecoder {
}
@Override
- public int size(ByteBuf buffer) {
- ByteBuf buf = buffer.slice();
- if (buf.isReadable()) {
- TypeConstructor c = readConstructor(buf);
- int size = c.size(buf);
- if (buf.readableBytes() > size) {
- buf.readerIndex(size + 1);
- c = readConstructor(buf);
- return size + 2 + c.size(buf);
+ 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 size + 2;
+ return 1;
}
- } else {
- return 1;
}
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
+ public void parse(Buffer buffer, Codec data) {
data.putDescribed();
data.enter();
TypeConstructor c = readConstructor(buffer);
@@ -824,13 +829,13 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
-
- int size = buffer.readByte() & 0xff;
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readByte() & 0xff;
- parseArray(data, buf, count);
+ 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);
+ }
}
}
@@ -842,23 +847,23 @@ class TypeDecoder {
}
@Override
- public void parse(ByteBuf buffer, Codec data) {
-
- int size = buffer.readInt();
- ByteBuf buf = buffer.slice(buffer.readerIndex(), size);
- buffer.skipBytes(size);
- int count = buf.readInt();
- parseArray(data, buf, count);
+ 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);
+ }
}
}
- private static void parseArray(Codec data, ByteBuf buffer, int count) {
+ private static void parseArray(Codec data, Buffer buffer, int count) {
byte type = buffer.readByte();
boolean isDescribed = type == (byte) 0x00;
- int descriptorPosition = buffer.readerIndex();
+ final int descriptorPosition = buffer.readerOffset();
if (isDescribed) {
- TypeConstructor descriptorTc = readConstructor(buffer);
- buffer.skipBytes(descriptorTc.size(buffer));
+ final TypeConstructor descriptorTc = readConstructor(buffer);
+ buffer.skipReadableBytes(descriptorTc.size(buffer));
type = buffer.readByte();
if (type == (byte) 0x00) {
throw new IllegalArgumentException("Malformed array data");
@@ -870,11 +875,11 @@ class TypeDecoder {
data.putArray(isDescribed, tc.getType());
data.enter();
if (isDescribed) {
- int position = buffer.readerIndex();
- buffer.readerIndex(descriptorPosition);
- TypeConstructor descriptorTc = readConstructor(buffer);
+ final int position = buffer.readerOffset();
+ buffer.readerOffset(descriptorPosition);
+ final TypeConstructor descriptorTc = readConstructor(buffer);
descriptorTc.parse(buffer, data);
- buffer.readerIndex(position);
+ buffer.readerOffset(position);
}
for (int i = 0; i < count; i++) {
tc.parse(buffer, data);
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 62a0cbc6..5c86ceac 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import java.util.UUID;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class UUIDElement extends AtomicElement<UUID> {
@@ -45,9 +45,9 @@ class UUIDElement extends AtomicElement<UUID> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (buffer.maxWritableBytes() >= size) {
+ if (buffer.implicitCapacityLimit() >= size) {
if (size == 17) {
buffer.writeByte((byte) 0x98);
}
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 6dff1fb7..cad775f3 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class UnsignedByteElement extends AtomicElement<UnsignedByte> {
@@ -45,14 +45,14 @@ class UnsignedByteElement extends AtomicElement<UnsignedByte> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
if (isElementOfArray()) {
- if (buffer.isWritable()) {
+ if (buffer.writableBytes() > 0) {
buffer.writeByte(value.byteValue());
return 1;
}
} else {
- if (buffer.maxWritableBytes() >= 2) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
buffer.writeByte((byte) 0x50);
buffer.writeByte(value.byteValue());
return 2;
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 0ee71374..ff7750c2 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class UnsignedIntegerElement extends AtomicElement<UnsignedInteger> {
@@ -68,9 +68,9 @@ class UnsignedIntegerElement extends AtomicElement<UnsignedInteger> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (size > buffer.maxWritableBytes()) {
+ if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
}
switch (size) {
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 cf04e5d4..89a31790 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class UnsignedLongElement extends AtomicElement<UnsignedLong> {
@@ -68,9 +68,9 @@ class UnsignedLongElement extends AtomicElement<UnsignedLong> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
int size = size();
- if (size > buffer.maxWritableBytes()) {
+ if (size > buffer.implicitCapacityLimit() - buffer.capacity()) {
return 0;
}
switch (size) {
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 9967cfd8..8fd67eca 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
@@ -18,7 +18,7 @@ package org.apache.qpid.protonj2.test.driver.codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort;
-import io.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
class UnsignedShortElement extends AtomicElement<UnsignedShort> {
@@ -45,14 +45,14 @@ class UnsignedShortElement extends AtomicElement<UnsignedShort> {
}
@Override
- public int encode(ByteBuf buffer) {
+ public int encode(Buffer buffer) {
if (isElementOfArray()) {
- if (buffer.maxWritableBytes() >= 2) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= 2) {
buffer.writeShort(value.shortValue());
return 2;
}
} else {
- if (buffer.maxWritableBytes() >= 3) {
+ if (buffer.implicitCapacityLimit() - buffer.capacity() >= 3) {
buffer.writeByte((byte) 0x60);
buffer.writeShort(value.shortValue());
return 3;
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 cd3ea643..112ea4c0 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
@@ -30,7 +30,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Attach extends PerformativeDescribedType {
@@ -252,7 +252,7 @@ public class Attach extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 84624d53..6ed6a274 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
@@ -25,7 +25,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Begin extends PerformativeDescribedType {
@@ -143,7 +143,7 @@ public class Begin extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 b4f0ab28..a0085163 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
@@ -21,7 +21,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Close extends PerformativeDescribedType {
@@ -68,7 +68,7 @@ public class Close extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 50958f34..fb88391e 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
@@ -22,7 +22,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Detach extends PerformativeDescribedType {
@@ -89,7 +89,7 @@ public class Detach extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 ec4a79cc..aadfa5be 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
@@ -23,7 +23,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Disposition extends PerformativeDescribedType {
@@ -120,7 +120,7 @@ public class Disposition extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 38544184..82712f56 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
@@ -21,7 +21,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class End extends PerformativeDescribedType {
@@ -68,7 +68,7 @@ public class End extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 2bbd4d91..11f8e71f 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
@@ -23,7 +23,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Flow extends PerformativeDescribedType {
@@ -171,7 +171,7 @@ public class Flow extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 13cfd579..1d024f62 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
/**
* 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, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 f69a0321..82c28d57 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
@@ -25,7 +25,7 @@ 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.netty.buffer.ByteBuf;
+import io.netty5.buffer.Buffer;
public class Open extends PerformativeDescribedType {
@@ -163,7 +163,7 @@ public class Open extends PerformativeDescribedType {
}
@Override
- public <E> void invoke(PerformativeHandler<E> handler, int frameSize, ByteBuf payload, int channel, E context) {
+ public <E> void invoke(PerformativeHandler<E> handler, int frameSize, Buffer 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 9c1d5054..48a7cb73 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
@@ -20,7 +20,7 @@ import java.util.List;
import org.apache.qpid.protonj2.test.driver.codec.ListDescribedType;
... 54553 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org