diff --git a/pom.xml b/pom.xml
index f6e51765c..e912a7b83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,6 @@
3.0
4.1.113.Final
0.0.25.Final
- 5.0.0.Alpha5
2.0.66.Final
@@ -64,11 +63,6 @@
linux-x86_64
osx-x86_64
- provided
- linux-x86_64
- linux-x86_64
- osx-x86_64
-
-Xmx2g -enableassertions ${jacoco-config}
@@ -170,44 +164,6 @@
${netty.iouring.version}
${netty-transport-native-io-uring-classifier}
-
-
- io.netty
- netty5-buffer
- ${netty5.version}
-
-
- io.netty
- netty5-common
- ${netty5.version}
-
-
- io.netty
- netty5-handler
- ${netty5.version}
-
-
- io.netty
- netty5-transport
- ${netty5.version}
-
-
- io.netty
- netty5-codec-http
- ${netty5.version}
-
-
- io.netty
- netty5-transport-native-epoll
- ${netty5.version}
- ${netty-transport-native-epoll-classifier}
-
-
- io.netty
- netty5-transport-native-kqueue
- ${netty5.version}
- ${netty-transport-native-kqueue-classifier}
-
io.netty
diff --git a/protonj2-client/pom.xml b/protonj2-client/pom.xml
index cb58e7b00..a3f905205 100644
--- a/protonj2-client/pom.xml
+++ b/protonj2-client/pom.xml
@@ -83,44 +83,6 @@
${netty-transport-native-kqueue-classifier}
${netty-scope}
-
-
- io.netty
- netty5-buffer
- ${netty5-scope}
-
-
- io.netty
- netty5-common
- ${netty5-scope}
-
-
- io.netty
- netty5-handler
- ${netty5-scope}
-
-
- io.netty
- netty5-transport
- ${netty5-scope}
-
-
- io.netty
- netty5-codec-http
- ${netty5-scope}
-
-
- io.netty
- netty5-transport-native-epoll
- ${netty-transport-native-epoll-classifier}
- ${netty5-scope}
-
-
- io.netty
- netty5-transport-native-kqueue
- ${netty5-transport-native-kqueue-classifier}
- ${netty5-scope}
-
org.apache.qpid
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
index 22c9e52ab..c4f725a96 100644
--- 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
@@ -21,8 +21,6 @@
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;
/**
@@ -69,8 +67,6 @@ public interface IOContext {
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");
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java
deleted file mode 100644
index 2b774d925..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/EpollSupport.java
+++ /dev/null
@@ -1,54 +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.client.transport.netty5;
-
-import java.util.concurrent.ThreadFactory;
-
-import org.apache.qpid.protonj2.client.TransportOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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 final class EpollSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(EpollSupport.class);
-
- public static final String NAME = "EPOLL";
-
- public static boolean isAvailable(TransportOptions transportOptions) {
- try {
- return transportOptions.allowNativeIO() && Epoll.isAvailable();
- } catch (NoClassDefFoundError ncdfe) {
- LOG.debug("Unable to check for Epoll support due to missing class definition", ncdfe);
- return false;
- }
- }
-
- public static EventLoopGroup createGroup(int nThreads, ThreadFactory ioThreadFactory) {
- return new MultithreadEventLoopGroup(nThreads, ioThreadFactory, EpollHandler.newFactory());
- }
-
- public static Class extends Channel> getChannelClass() {
- return EpollSocketChannel.class;
- }
-}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java
deleted file mode 100644
index 7a435e14e..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/IOUringSupport.java
+++ /dev/null
@@ -1,52 +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.client.transport.netty5;
-
-import java.util.concurrent.ThreadFactory;
-
-import org.apache.qpid.protonj2.client.TransportOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.channel.Channel;
-import io.netty5.channel.EventLoopGroup;
-
-public class IOUringSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(IOUringSupport.class);
-
- public static final String NAME = "IO_URING";
-
- public static boolean isAvailable(TransportOptions transportOptions) {
- try {
- 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;
- }
- }
-
- public static EventLoopGroup createGroup(int nThreads, ThreadFactory 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;
- 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/netty5/KQueueSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/KQueueSupport.java
deleted file mode 100644
index 7c4fd76e2..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/KQueueSupport.java
+++ /dev/null
@@ -1,54 +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.client.transport.netty5;
-
-import java.util.concurrent.ThreadFactory;
-
-import org.apache.qpid.protonj2.client.TransportOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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 final class KQueueSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(KQueueSupport.class);
-
- public static final String NAME = "KQUEUE";
-
- public static boolean isAvailable(TransportOptions transportOptions) {
- try {
- return transportOptions.allowNativeIO() && KQueue.isAvailable();
- } catch (NoClassDefFoundError ncdfe) {
- LOG.debug("Unable to check for KQueue support due to missing class definition", ncdfe);
- return false;
- }
- }
-
- public static EventLoopGroup createGroup(int nThreads, ThreadFactory ioThreadFactory) {
- return new MultithreadEventLoopGroup(nThreads, ioThreadFactory, KQueueHandler.newFactory());
- }
-
- public static Class extends Channel> getChannelClass() {
- return KQueueSocketChannel.class;
- }
-}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java
deleted file mode 100644
index cffa21873..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5IOContext.java
+++ /dev/null
@@ -1,195 +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.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.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 Netty5IOContext implements IOContext {
-
- 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 Netty5IOContext(TransportOptions options, SslOptions ssl, String ioThreadName) {
- Objects.requireNonNull(options, "Transport Options cannot be null");
- Objects.requireNonNull(ssl, "Transport SSL Options cannot be null");
-
- this.options = options;
- this.sslOptions = ssl;
- this.threadFactory = new TrackableThreadFactory(ioThreadName, true);
-
- final String[] nativeIOPreference = options.nativeIOPreference();
-
- EventLoopGroup selectedGroup = null;
- Class extends Channel> selectedChannelClass = null;
-
- if (options.allowNativeIO()) {
- for (String nativeID : nativeIOPreference) {
- if (EpollSupport.NAME.equalsIgnoreCase(nativeID)) {
- if (EpollSupport.isAvailable(options)) {
- LOG.trace("Netty Transports will be using Epoll mode");
- selectedGroup = EpollSupport.createGroup(1, threadFactory);
- selectedChannelClass = EpollSupport.getChannelClass();
- break;
- }
- } else if (IOUringSupport.NAME.equalsIgnoreCase(nativeID)) {
- if (IOUringSupport.isAvailable(options)) {
- LOG.trace("Netty Transports will be using IO-Uring mode");
- selectedGroup = IOUringSupport.createGroup(1, threadFactory);
- selectedChannelClass = IOUringSupport.getChannelClass();
- break;
- }
- } else if (KQueueSupport.NAME.equalsIgnoreCase(nativeID)) {
- if (KQueueSupport.isAvailable(options)) {
- LOG.trace("Netty Transports will be using KQueue mode");
- selectedGroup = KQueueSupport.createGroup(1, threadFactory);
- selectedChannelClass = KQueueSupport.getChannelClass();
- break;
- }
- } else {
- throw new IllegalArgumentException(
- String.format("Provided preferred native transport type name: %s, is not supported.", nativeID));
- }
- }
- }
-
- if (selectedGroup == null) {
- LOG.trace("Netty Transports will be using NIO mode");
- selectedGroup = new MultithreadEventLoopGroup(1, threadFactory, NioHandler.newFactory());
- selectedChannelClass = NioSocketChannel.class;
- }
-
- this.group = selectedGroup;
- this.channelClass = selectedChannelClass;
- }
-
- @Override
- public void shutdown() {
- if (!group.isShutdown()) {
- 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);
- }
- }
-
- @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");
- }
-
- final Bootstrap bootstrap = new Bootstrap().channel(channelClass).group(group);
-
- final TcpTransport transport;
-
- if (options.useWebSockets()) {
- transport = new WebSocketTransport(bootstrap, options, sslOptions);
- } else {
- transport = new TcpTransport(bootstrap, options, sslOptions);
- }
-
- 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 Future schedule(Callable 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-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5Support.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5Support.java
deleted file mode 100644
index 1bb8ac872..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/Netty5Support.java
+++ /dev/null
@@ -1,48 +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.client.transport.netty5;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.buffer.BufferAllocator;
-
-/**
- * Support class used to detect if Netty 5 is available on the class path.
- */
-public final class Netty5Support {
-
- private static final Logger LOG = LoggerFactory.getLogger(Netty5Support.class);
-
- 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;
- }
-
- public static final boolean isAvailable() {
- return UNAVAILABILITY_CAUSE == null;
- }
-}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java
deleted file mode 100644
index 4d1ffe3c3..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/SslSupport.java
+++ /dev/null
@@ -1,474 +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.client.transport.netty5;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.TrustManager;
-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.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 final class SslSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(SslSupport.class);
-
- public static final String FROM_CLASSPATH_PREFIX = "classpath:";
- public static final String FROM_FILE_PREFIX = "file:";
- public static final String FROM_FILE_URL_PREFIX = "file://";
-
- /**
- * Determines if Netty OpenSSL support is available and applicable based on the configuration
- * in the given TransportOptions instance.
- *
- * @param options
- * The configuration of the Transport being created.
- *
- * @return true if OpenSSL support is available and usable given the requested configuration.
- */
- public static boolean isOpenSSLPossible(SslOptions options) {
- boolean result = false;
-
- if (options.allowNativeSSL()) {
- if (!OpenSsl.isAvailable()) {
- LOG.debug("OpenSSL could not be enabled because a suitable implementation could not be found.", OpenSsl.unavailabilityCause());
- } else if (options.sslContextOverride() != null) {
- LOG.debug("OpenSSL could not be enabled due to user SSLContext being supplied.");
- } else if (!OpenSsl.supportsKeyManagerFactory()) {
- LOG.debug("OpenSSL could not be enabled because the version provided does not allow a KeyManagerFactory to be used.");
- } else if (options.keyAlias() != null) {
- LOG.debug("OpenSSL could not be enabled because a keyAlias is set and that feature is not supported for OpenSSL.");
- } else {
- LOG.debug("OpenSSL Enabled: Version {} of OpenSSL will be used", OpenSsl.versionString());
- result = true;
- }
- }
-
- return result;
- }
-
- /**
- * Creates a Netty SslHandler instance for use in Transports that require
- * an SSL encoder / decoder.
- *
- * If the given options contain an SSLContext override, this will be used directly
- * when creating the handler. If they do not, an SSLContext will first be created
- * using the other option values.
- *
- * @param allocator
- * The Netty Buffer Allocator to use when Netty resources need to be created.
- * @param host
- * the host name or IP address that this transport connects to.
- * @param port
- * the port on the given host that this transport connects to.
- * @param options
- * The SSL options object to build the SslHandler instance from.
- *
- * @return a new SslHandler that is configured from the given options.
- *
- * @throws Exception if an error occurs while creating the SslHandler instance.
- */
- public static SslHandler createSslHandler(BufferAllocator allocator, String host, int port, SslOptions options) throws Exception {
- final SSLEngine sslEngine;
-
- if (isOpenSSLPossible(options)) {
- SslContext sslContext = createOpenSslContext(options);
- sslEngine = createOpenSslEngine(allocator, host, port, sslContext, options);
- } else {
- SSLContext sslContext = options.sslContextOverride();
- if (sslContext == null) {
- sslContext = createJdkSslContext(options);
- }
-
- sslEngine = createJdkSslEngine(host, port, sslContext, options);
- }
-
- return new SslHandler(sslEngine);
- }
-
- //----- JDK SSL Support Methods ------------------------------------------//
-
- /**
- * Create a new SSLContext using the options specific in the given TransportOptions
- * instance.
- *
- * @param options
- * the configured options used to create the SSLContext.
- *
- * @return a new SSLContext instance.
- *
- * @throws Exception if an error occurs while creating the context.
- */
- public static SSLContext createJdkSslContext(SslOptions options) throws Exception {
- try {
- String contextProtocol = options.contextProtocol();
- LOG.trace("Getting SSLContext instance using protocol: {}", contextProtocol);
-
- SSLContext context = SSLContext.getInstance(contextProtocol);
-
- KeyManager[] keyMgrs = loadKeyManagers(options);
- TrustManager[] trustManagers = loadTrustManagers(options);
-
- context.init(keyMgrs, trustManagers, new SecureRandom());
- return context;
- } catch (Exception e) {
- LOG.error("Failed to create SSLContext: {}", e, e);
- throw e;
- }
- }
-
- /**
- * Create a new JDK SSLEngine instance in client mode from the given SSLContext and
- * TransportOptions instances.
- *
- * @param host
- * the host name or IP address that this transport connects to.
- * @param port
- * the port on the given host that this transport connects to.
- * @param context
- * the SSLContext to use when creating the engine.
- * @param options
- * the TransportOptions to use to configure the new SSLEngine.
- *
- * @return a new SSLEngine instance in client mode.
- *
- * @throws Exception if an error occurs while creating the new SSLEngine.
- */
- public static SSLEngine createJdkSslEngine(String host, int port, SSLContext context, SslOptions options) throws Exception {
- SSLEngine engine = null;
- if (host == null || host.isEmpty()) {
- engine = context.createSSLEngine();
- } else {
- engine = context.createSSLEngine(host, port);
- }
-
- engine.setEnabledProtocols(buildEnabledProtocols(engine, options));
- engine.setEnabledCipherSuites(buildEnabledCipherSuites(engine, options));
- engine.setUseClientMode(true);
-
- if (options.verifyHost()) {
- SSLParameters sslParameters = engine.getSSLParameters();
- sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
- engine.setSSLParameters(sslParameters);
- }
-
- return engine;
- }
-
- //----- OpenSSL Support Methods ------------------------------------------//
-
- /**
- * Create a new Netty SslContext using the options specific in the given TransportOptions
- * instance.
- *
- * @param options
- * the configured options used to create the SslContext.
- *
- * @return a new SslContext instance.
- *
- * @throws Exception if an error occurs while creating the context.
- */
- public static SslContext createOpenSslContext(SslOptions options) throws Exception {
- try {
- String contextProtocol = options.contextProtocol();
- LOG.trace("Getting SslContext instance using protocol: {}", contextProtocol);
-
- KeyManagerFactory keyManagerFactory = loadKeyManagerFactory(options, SslProvider.OPENSSL);
- TrustManagerFactory trustManagerFactory = loadTrustManagerFactory(options);
- SslContextBuilder builder = SslContextBuilder.forClient().sslProvider(SslProvider.OPENSSL);
-
- // TODO - There is oddly no way in Netty right now to get the set of supported protocols
- // when creating the SslContext or really even when creating the SSLEngine. Seems
- // like an oversight, for now we call it with TLSv1.2 so it looks like we did something.
- if (options.contextProtocol().equals(SslOptions.DEFAULT_CONTEXT_PROTOCOL)) {
- builder.protocols("TLSv1.2");
- } else {
- builder.protocols(options.contextProtocol());
- }
- builder.keyManager(keyManagerFactory);
- builder.trustManager(trustManagerFactory);
-
- return builder.build();
- } catch (Exception e) {
- LOG.error("Failed to create SslContext: {}", e, e);
- throw e;
- }
- }
-
- /**
- * Create a new OpenSSL SSLEngine instance in client mode from the given SSLContext and
- * TransportOptions instances.
- *
- * @param allocator
- * 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
- * the port on the given host that this transport connects to.
- * @param context
- * the Netty SslContext to use when creating the engine.
- * @param options
- * the TransportOptions to use to configure the new SSLEngine.
- *
- * @return a new Netty managed SSLEngine instance in client mode.
- *
- * @throws Exception if an error occurs while creating the new SSLEngine.
- */
- public static SSLEngine createOpenSslEngine(BufferAllocator allocator, String host, int port, SslContext context, SslOptions options) throws Exception {
- SSLEngine engine = null;
-
- if (allocator == null) {
- throw new IllegalArgumentException("OpenSSL engine requires a valid ByteBufAllocator to operate");
- }
-
- if (host == null || host.isEmpty()) {
- engine = context.newEngine(allocator);
- } else {
- engine = context.newEngine(allocator, host, port);
- }
-
- engine.setEnabledProtocols(buildEnabledProtocols(engine, options));
- engine.setEnabledCipherSuites(buildEnabledCipherSuites(engine, options));
- engine.setUseClientMode(true);
-
- if (options.verifyHost()) {
- SSLParameters sslParameters = engine.getSSLParameters();
- sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
- engine.setSSLParameters(sslParameters);
- }
-
- return engine;
- }
-
- //----- Internal support methods -----------------------------------------//
-
- private static String[] buildEnabledProtocols(SSLEngine engine, SslOptions options) {
- List enabledProtocols = new ArrayList();
-
- if (options.enabledProtocols() != null) {
- List configuredProtocols = Arrays.asList(options.enabledProtocols());
- LOG.trace("Configured protocols from transport options: {}", configuredProtocols);
- enabledProtocols.addAll(configuredProtocols);
- } else {
- List engineProtocols = Arrays.asList(engine.getEnabledProtocols());
- LOG.trace("Default protocols from the SSLEngine: {}", engineProtocols);
- enabledProtocols.addAll(engineProtocols);
- }
-
- String[] disabledProtocols = options.disabledProtocols();
- if (disabledProtocols != null) {
- List disabled = Arrays.asList(disabledProtocols);
- LOG.trace("Disabled protocols: {}", disabled);
- enabledProtocols.removeAll(disabled);
- }
-
- LOG.trace("Enabled protocols: {}", enabledProtocols);
-
- return enabledProtocols.toArray(new String[0]);
- }
-
- private static String[] buildEnabledCipherSuites(SSLEngine engine, SslOptions options) {
- List enabledCipherSuites = new ArrayList();
-
- if (options.enabledCipherSuites() != null) {
- List configuredCipherSuites = Arrays.asList(options.enabledCipherSuites());
- LOG.trace("Configured cipher suites from transport options: {}", configuredCipherSuites);
- enabledCipherSuites.addAll(configuredCipherSuites);
- } else {
- List engineCipherSuites = Arrays.asList(engine.getEnabledCipherSuites());
- LOG.trace("Default cipher suites from the SSLEngine: {}", engineCipherSuites);
- enabledCipherSuites.addAll(engineCipherSuites);
- }
-
- String[] disabledCipherSuites = options.disabledCipherSuites();
- if (disabledCipherSuites != null) {
- List disabled = Arrays.asList(disabledCipherSuites);
- LOG.trace("Disabled cipher suites: {}", disabled);
- enabledCipherSuites.removeAll(disabled);
- }
-
- LOG.trace("Enabled cipher suites: {}", enabledCipherSuites);
-
- return enabledCipherSuites.toArray(new String[0]);
- }
-
- private static TrustManager[] loadTrustManagers(SslOptions options) throws Exception {
- TrustManagerFactory factory = loadTrustManagerFactory(options);
- if (factory != null) {
- return factory.getTrustManagers();
- } else {
- return null;
- }
- }
-
- private static TrustManagerFactory loadTrustManagerFactory(SslOptions options) throws Exception {
- if (options.trustAll()) {
- return InsecureTrustManagerFactory.INSTANCE;
- }
-
- if (options.trustStoreLocation() == null) {
- return null;
- }
-
- TrustManagerFactory fact = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.trustStoreLocation();
- String storePassword = options.trustStorePassword();
- String storeType = options.trustStoreType();
-
- LOG.trace("Attempt to load TrustStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore trustStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(trustStore);
-
- return fact;
- }
-
- private static KeyManager[] loadKeyManagers(SslOptions options) throws Exception {
- if (options.keyStoreLocation() == null) {
- return null;
- }
-
- KeyManagerFactory fact = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.keyStoreLocation();
- String storePassword = options.keyStorePassword();
- String storeType = options.keyStoreType();
- String alias = options.keyAlias();
-
- LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore keyStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(keyStore, storePassword != null ? storePassword.toCharArray() : null);
-
- if (alias == null) {
- return fact.getKeyManagers();
- } else {
- validateAlias(keyStore, alias);
- return wrapKeyManagers(alias, fact.getKeyManagers());
- }
- }
-
- private static KeyManagerFactory loadKeyManagerFactory(SslOptions options, SslProvider provider) throws Exception {
- if (options.keyStoreLocation() == null) {
- return null;
- }
-
- final KeyManagerFactory factory;
- if (provider.equals(SslProvider.JDK)) {
- factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- } else {
- factory = new OpenSslX509KeyManagerFactory();
- }
-
- String storeLocation = options.keyStoreLocation();
- String storePassword = options.keyStorePassword();
- String storeType = options.keyStoreType();
-
- LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore keyStore = loadStore(storeLocation, storePassword, storeType);
- factory.init(keyStore, storePassword != null ? storePassword.toCharArray() : null);
-
- return factory;
- }
-
- private static KeyManager[] wrapKeyManagers(String alias, KeyManager[] origKeyManagers) {
- KeyManager[] keyManagers = new KeyManager[origKeyManagers.length];
- for (int i = 0; i < origKeyManagers.length; i++) {
- KeyManager km = origKeyManagers[i];
- if (km instanceof X509ExtendedKeyManager) {
- km = new X509AliasKeyManager(alias, (X509ExtendedKeyManager) km);
- }
-
- keyManagers[i] = km;
- }
-
- return keyManagers;
- }
-
- private static void validateAlias(KeyStore store, String alias) throws IllegalArgumentException, KeyStoreException {
- if (!store.containsAlias(alias)) {
- throw new IllegalArgumentException("The alias '" + alias + "' doesn't exist in the key store");
- }
-
- if (!store.isKeyEntry(alias)) {
- throw new IllegalArgumentException("The alias '" + alias + "' in the keystore doesn't represent a key entry");
- }
- }
-
- private static KeyStore loadStore(String storePath, final String password, String storeType) throws Exception {
- KeyStore store = KeyStore.getInstance(storeType);
- try (InputStream in = openStoreAtLocation(storePath)) {
- store.load(in, password != null ? password.toCharArray() : null);
- } catch (Exception ex) {
- LOG.trace("Caught Error loading store: {}", ex.getMessage(), ex);
- throw ex;
- }
-
- return store;
- }
-
- private static InputStream openStoreAtLocation(final String storePath) throws IOException {
- final InputStream stream;
-
- if (storePath.startsWith(FROM_CLASSPATH_PREFIX)) {
- stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(storePath.substring(FROM_CLASSPATH_PREFIX.length()));
- } else if (storePath.startsWith(FROM_FILE_URL_PREFIX)) {
- stream = new FileInputStream(storePath.substring(FROM_FILE_URL_PREFIX.length()));
- } else if (storePath.startsWith(FROM_FILE_PREFIX)) {
- stream = new FileInputStream(storePath.substring(FROM_FILE_PREFIX.length()));
- } else {
- stream = new FileInputStream(storePath);
- }
-
- if (stream == null) {
- throw new IOException("Could no locate KeyStore at location: " + storePath);
- }
-
- return stream;
- }
-}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java
deleted file mode 100644
index 5fba50b6b..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/TcpTransport.java
+++ /dev/null
@@ -1,536 +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.client.transport.netty5;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.Principal;
-import java.util.concurrent.CountDownLatch;
-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.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.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.
- */
-public class TcpTransport implements Transport {
-
- private static final Logger LOG = LoggerFactory.getLogger(TcpTransport.class);
-
- protected final AtomicBoolean connected = new AtomicBoolean();
- protected final AtomicBoolean closed = new AtomicBoolean();
- protected final CountDownLatch connectedLatch = new CountDownLatch(1);
- protected final TransportOptions options;
- protected final SslOptions sslOptions;
- protected final Bootstrap bootstrap;
-
- protected Channel channel;
- protected volatile IOException failureCause;
- protected String host;
- protected int port;
- protected TransportListener listener;
- protected Netty5ProtonBufferAllocator nettyAllocator;
-
- /**
- * Create a new {@link TcpTransport} instance with the given configuration.
- *
- * @param bootstrap
- * the Netty {@link Bootstrap} that this transport's IO layer is bound to.
- * @param options
- * the {@link TransportOptions} used to configure the socket connection.
- * @param sslOptions
- * the {@link SslOptions} to use if the options indicate SSL is enabled.
- */
- public TcpTransport(Bootstrap bootstrap, TransportOptions options, SslOptions sslOptions) {
- if (options == null) {
- throw new IllegalArgumentException("Transport Options cannot be null");
- }
-
- if (sslOptions == null) {
- throw new IllegalArgumentException("Transport SSL Options cannot be null");
- }
-
- if (bootstrap == null) {
- throw new IllegalArgumentException("A transport must have an assigned Bootstrap before connect.");
- }
-
- this.sslOptions = sslOptions;
- this.options = options;
- this.bootstrap = bootstrap;
- }
-
- @Override
- public TcpTransport connect(String host, int port, TransportListener listener) throws IOException {
- if (closed.get()) {
- throw new IllegalStateException("Transport has already been closed");
- }
-
- if (listener == null) {
- throw new IllegalArgumentException("A transport listener must be set before connection attempts.");
- }
-
- if (host == null || host.isEmpty()) {
- throw new IllegalArgumentException("Transport host value cannot be null");
- }
-
- if (port < 0 && options.defaultTcpPort() < 0 && (sslOptions.sslEnabled() && sslOptions.defaultSslPort() < 0)) {
- throw new IllegalArgumentException("Transport port value must be a non-negative int value or a default port configured");
- }
-
- this.host = host;
- this.listener = listener;
-
- if (port > 0) {
- this.port = port;
- } else {
- if (sslOptions.sslEnabled()) {
- this.port = sslOptions.defaultSslPort();
- } else {
- this.port = options.defaultTcpPort();
- }
- }
-
- bootstrap.handler(new ChannelInitializer<>() {
- @Override
- public void initChannel(Channel transportChannel) throws Exception {
- channel = transportChannel;
- nettyAllocator = new Netty5ProtonBufferAllocator(channel.bufferAllocator());
-
- configureChannel(transportChannel);
- try {
- listener.transportInitialized(TcpTransport.this);
- } catch (Throwable initError) {
- LOG.warn("Error during initialization of channel from Transport Listener");
- handleTransportFailure(transportChannel, IOExceptionSupport.create(initError));
- throw initError;
- }
- }
- });
-
- configureNetty(bootstrap, options);
-
- bootstrap.connect(getHost(), getPort()).addListener(new FutureListener() {
-
- @Override
- public void operationComplete(Future extends Channel> future) throws Exception {
- if (future.isFailed()) {
- bootstrap.config().group().execute(() -> handleTransportFailure(channel, future.cause()));
- }
- }
- });
-
- return this;
- }
-
- @Override
- public void awaitConnect() throws InterruptedException, IOException {
- connectedLatch.await();
- if (!connected.get()) {
- if (failureCause != null) {
- throw failureCause;
- } else {
- throw new IOException("Transport was closed before a connection was established.");
- }
- }
- }
-
- @Override
- public boolean isConnected() {
- return connected.get();
- }
-
- @Override
- public boolean isSecure() {
- return sslOptions.sslEnabled();
- }
-
- @Override
- public String getHost() {
- return host;
- }
-
- @Override
- public int getPort() {
- return port;
- }
-
- @Override
- public void close() throws IOException {
- if (closed.compareAndSet(false, true)) {
- connected.set(false);
- connectedLatch.countDown();
- if (channel != null) {
- try {
- channel.close().asStage().await();
- } catch (InterruptedException e) {
- Thread.interrupted();
- }
- }
- }
- }
-
- @Override
- public ProtonBufferAllocator getBufferAllocator() {
- return nettyAllocator;
- }
-
- @Override
- public TcpTransport write(ProtonBuffer output) throws IOException {
- return write(output, null);
- }
-
- @Override
- public TcpTransport write(ProtonBuffer output, Runnable onComplete) throws IOException {
- checkConnected(output);
- LOG.trace("Attempted write of buffer: {}", output);
- return writeOutputBuffer(output, false, onComplete);
- }
-
- @Override
- public TcpTransport writeAndFlush(ProtonBuffer output) throws IOException {
- return writeAndFlush(output, null);
- }
-
- @Override
- public TcpTransport writeAndFlush(ProtonBuffer output, Runnable onComplete) throws IOException {
- checkConnected(output);
- LOG.trace("Attempted write and flush of buffer: {}", output);
- return writeOutputBuffer(output, true, onComplete);
- }
-
- @Override
- public TcpTransport flush() throws IOException {
- checkConnected();
- LOG.trace("Attempted flush of pending writes");
- channel.flush();
- return this;
- }
-
- @Override
- public TransportListener getTransportListener() {
- return listener;
- }
-
- @Override
- public TransportOptions getTransportOptions() {
- return options.clone();
- }
-
- @Override
- public SslOptions getSslOptions() {
- return sslOptions.clone();
- }
-
- @Override
- public Principal getLocalPrincipal() {
- Principal result = null;
-
- if (isSecure()) {
- SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
- result = sslHandler.engine().getSession().getLocalPrincipal();
- }
-
- return result;
- }
-
- private TcpTransport writeOutputBuffer(final ProtonBuffer buffer, boolean flush, Runnable onComplete) {
- int writeCount = buffer.componentCount();
- Future 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 writeFuture = null;
-
- final Buffer nettyBuf = new ProtonBufferToNetty5Adapter(buffer.transfer());
-
- if (flush) {
- writeFuture = channel.writeAndFlush(nettyBuf);
- } else {
- writeFuture = channel.write(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 -----//
-
- protected void addAdditionalHandlers(ChannelPipeline pipeline) {
-
- }
-
- protected ChannelHandler createChannelHandler() {
- return new NettyTcpTransportHandler();
- }
-
- //----- Event Handlers which can be overridden in subclasses -------------//
-
- protected void handleConnected(Channel connectedChannel) throws Exception {
- LOG.trace("Channel has become active! Channel is {}", connectedChannel);
- channel = connectedChannel;
- connected.set(true);
- listener.transportConnected(this);
- connectedLatch.countDown();
- }
-
- protected void handleTransportFailure(Channel failedChannel, Throwable cause) {
- if (!closed.get()) {
- LOG.trace("Transport indicates connection failure! Channel is {}", failedChannel);
- failureCause = IOExceptionSupport.create(cause);
- channel = failedChannel;
- connected.set(false);
- connectedLatch.countDown();
-
- LOG.trace("Firing onTransportError listener");
- if (channel.executor().inEventLoop()) {
- listener.transportError(failureCause);
- } else {
- channel.executor().execute(() -> {
- listener.transportError(failureCause);
- });
- }
- } else {
- LOG.trace("Closed Transport signalled that the channel ended: {}", channel);
- }
- }
-
- //----- State change handlers and checks ---------------------------------//
-
- protected final void checkConnected() throws IOException {
- if (!connected.get() || !channel.isActive()) {
- throw new IOException("Cannot send to a non-connected transport.", failureCause);
- }
- }
-
- private void checkConnected(ProtonBuffer output) throws IOException {
- if (!connected.get() || !channel.isActive()) {
- output.close();
- throw new IOException("Cannot send to a non-connected transport.", failureCause);
- }
- }
-
- private void configureNetty(Bootstrap bootstrap, TransportOptions options) {
- bootstrap.option(ChannelOption.TCP_NODELAY, options.tcpNoDelay());
- bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.connectTimeout());
- bootstrap.option(ChannelOption.SO_KEEPALIVE, options.tcpKeepAlive());
- bootstrap.option(ChannelOption.SO_LINGER, options.soLinger());
-
- if (options.sendBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_SNDBUF, options.sendBufferSize());
- }
-
- if (options.receiveBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_RCVBUF, options.receiveBufferSize());
- }
-
- if (options.trafficClass() != -1) {
- bootstrap.option(ChannelOption.IP_TOS, options.trafficClass());
- }
-
- if (options.localAddress() != null || options.localPort() != 0) {
- if (options.localAddress() != null) {
- bootstrap.localAddress(options.localAddress(), options.localPort());
- } else {
- bootstrap.localAddress(options.localPort());
- }
- }
- }
-
- private void configureChannel(final Channel channel) throws Exception {
- if (isSecure()) {
- final SslHandler sslHandler;
- try {
- 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));
- throw IOExceptionSupport.create(ex);
- }
-
- channel.pipeline().addLast("ssl", sslHandler);
- }
-
- if (options.traceBytes()) {
- channel.pipeline().addLast("logger", new LoggingHandler(getClass()));
- }
-
- addAdditionalHandlers(channel.pipeline());
-
- channel.pipeline().addLast(createChannelHandler());
- }
-
- //----- Default implementation of Netty handler --------------------------//
-
- protected abstract class NettyDefaultHandler extends SimpleChannelInboundHandler {
-
- public NettyDefaultHandler() {
- super(false); // We will release buffer references manually.
- }
-
- @Override
- public final void channelRegistered(ChannelHandlerContext context) throws Exception {
- channel = context.channel();
- }
-
- @Override
- public void channelActive(ChannelHandlerContext context) throws Exception {
- // In the Secure case we need to let the handshake complete before we
- // trigger the connected event.
- if (!isSecure()) {
- handleConnected(context.channel());
- } else {
- SslHandler sslHandler = context.pipeline().get(SslHandler.class);
- sslHandler.handshakeFuture().addListener(new FutureListener() {
- @Override
- public void operationComplete(Future extends Channel> future) throws Exception {
- if (future.isSuccess()) {
- LOG.trace("SSL Handshake has completed: {}", channel);
- handleConnected(channel);
- } else {
- LOG.trace("SSL Handshake has failed: {}", channel);
- handleTransportFailure(channel, future.cause());
- }
- }
- });
- }
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- ctx.flush();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext context) throws Exception {
- handleTransportFailure(context.channel(), new IOException("Remote closed connection unexpectedly"));
- }
-
- @Override
- public void channelExceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
- handleTransportFailure(context.channel(), cause);
- }
-
- protected void dispatchReadBuffer(Buffer 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 -----------------------//
-
- protected class NettyTcpTransportHandler extends NettyDefaultHandler {
-
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Buffer buffer) throws Exception {
- dispatchReadBuffer(buffer);
- }
- }
-
- @Override
- public URI getRemoteURI() {
- if (host != null) {
- try {
- return new URI(getScheme(), null, host, port, null, null, null);
- } catch (URISyntaxException e) {
- }
- }
-
- return null;
- }
-
- protected String getScheme() {
- return isSecure() ? "ssl" : "tcp";
- }
-}
diff --git a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java b/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java
deleted file mode 100644
index 62c0097de..000000000
--- a/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/transport/netty5/WebSocketTransport.java
+++ /dev/null
@@ -1,222 +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.client.transport.netty5;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.qpid.protonj2.client.SslOptions;
-import org.apache.qpid.protonj2.client.TransportOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
-
-/**
- * Netty based WebSockets Transport that wraps and extends the TCP Transport.
- */
-public class WebSocketTransport extends TcpTransport {
-
- private static final Logger LOG = LoggerFactory.getLogger(WebSocketTransport.class);
-
- private static final String AMQP_SUB_PROTOCOL = "amqp";
-
- private Future handshakeTimeoutFuture;
-
- /**
- * Create a new {@link WebSocketTransport} instance with the given configuration.
- *
- * @param bootstrap
- * the {@link Bootstrap} that this transport's IO is bound to.
- * @param options
- * the {@link TransportOptions} used to configure the socket connection.
- * @param sslOptions
- * the {@link SslOptions} to use if the options indicate SSL is enabled.
- */
- public WebSocketTransport(Bootstrap bootstrap, TransportOptions options, SslOptions sslOptions) {
- super(bootstrap, options, sslOptions);
- }
-
- @Override
- public URI getRemoteURI() {
- if (host != null) {
- try {
- return new URI(getScheme(), null, host, port, options.webSocketPath(), null, null);
- } catch (URISyntaxException e) {
- }
- }
-
- return null;
- }
-
- @Override
- protected ChannelHandler createChannelHandler() {
- return new NettyWebSocketTransportHandler();
- }
-
- @Override
- protected void addAdditionalHandlers(ChannelPipeline pipeline) {
- pipeline.addLast(new HttpClientCodec());
- pipeline.addLast(new HttpObjectAggregator(8192));
- if (options.webSocketCompression()) {
- pipeline.addLast(WebSocketClientCompressionHandler.INSTANCE);
- }
- }
-
- @Override
- protected void handleConnected(Channel channel) throws Exception {
- LOG.trace("Channel has become active, awaiting WebSocket handshake! Channel is {}", channel);
- }
-
- @Override
- protected String getScheme() {
- return isSecure() ? "wss" : "ws";
- }
-
- //----- Handle connection events -----------------------------------------//
-
- private class OutputBufferToBinaryFrameHandler extends ChannelHandlerAdapter {
-
- @Override
- public Future write(ChannelHandlerContext ctx, Object msg) {
- return ctx.write(new BinaryWebSocketFrame((Buffer) msg));
- }
- }
-
- private class NettyWebSocketTransportHandler extends NettyDefaultHandler
-
-
- io.netty
- netty5-buffer
- ${netty5-scope}
-
-
- io.netty
- netty5-common
- ${netty5-scope}
-
-
- io.netty
- netty5-handler
- ${netty5-scope}
-
-
- io.netty
- netty5-transport
- ${netty5-scope}
-
-
- io.netty
- netty5-codec-http
- ${netty5-scope}
-
org.slf4j
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java
index 39d77db9d..29e306d05 100644
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java
+++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/NettyIOBuilder.java
@@ -25,9 +25,6 @@
import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Client;
import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Server;
import org.apache.qpid.protonj2.test.driver.netty.netty4.Netty4Support;
-import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Client;
-import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Server;
-import org.apache.qpid.protonj2.test.driver.netty.netty5.Netty5Support;
/**
* An I/O context used to abstract the implementation of the IO layer in use.
@@ -49,8 +46,6 @@ public interface NettyIOBuilder {
public static NettyClient createClient(ProtonTestClientOptions options, Runnable connectedHandler, Consumer inputHandler) {
if (Netty4Support.isAvailable()) {
return new Netty4Client(options, connectedHandler, inputHandler);
- } else if (Netty5Support.isAvailable()) {
- return new Netty5Client(options, connectedHandler, inputHandler);
}
throw new UnsupportedOperationException("Netty not available on the class path");
@@ -73,8 +68,6 @@ public static NettyClient createClient(ProtonTestClientOptions options, Runnable
public static NettyServer createServer(ProtonTestServerOptions options, Runnable connectedHandler, Runnable disconnectedHandler, Consumer inputHandler) {
if (Netty4Support.isAvailable()) {
return new Netty4Server(options, connectedHandler, disconnectedHandler, inputHandler);
- } else if (Netty5Support.isAvailable()) {
- return new Netty5Server(options, connectedHandler, disconnectedHandler, inputHandler);
}
throw new UnsupportedOperationException("Netty not available on the class path");
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java
deleted file mode 100644
index b17209e27..000000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Client.java
+++ /dev/null
@@ -1,564 +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.netty.netty5;
-
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
-import org.apache.qpid.protonj2.test.driver.netty.NettyClient;
-import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.bootstrap.Bootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoop;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.SimpleChannelInboundHandler;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioSocketChannel;
-import io.netty5.handler.codec.http.DefaultHttpContent;
-import io.netty5.handler.codec.http.FullHttpRequest;
-import io.netty5.handler.codec.http.FullHttpResponse;
-import io.netty5.handler.codec.http.HttpClientCodec;
-import io.netty5.handler.codec.http.HttpObjectAggregator;
-import io.netty5.handler.codec.http.headers.HttpHeaders;
-import io.netty5.handler.codec.http.websocketx.BinaryWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.ContinuationWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PingWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.PongWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.TextWebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshaker;
-import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
-import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty5.handler.codec.http.websocketx.WebSocketVersion;
-import io.netty5.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
-
-/**
- * Self contained Netty client implementation that provides a base for more
- * complex client implementations to use as the IO layer.
- */
-public final class Netty5Client implements NettyClient {
-
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private static final String AMQP_SUB_PROTOCOL = "amqp";
- private static final int SHUTDOWN_TIMEOUT = 50;
-
- private Netty5EventLoop eventLoop;
- private Bootstrap bootstrap;
- private EventLoopGroup group;
- private Channel channel;
- private String host;
- private int port;
- private boolean wsCompressionRequest;
- private boolean wsCompressionResponse;
- protected volatile IOException failureCause;
- private final ProtonTestClientOptions options;
- private volatile SslHandler sslHandler;
- protected final AtomicBoolean connected = new AtomicBoolean();
- protected final AtomicBoolean closed = new AtomicBoolean();
- protected final CountDownLatch connectedLatch = new CountDownLatch(1);
-
- private final Consumer inputConsumer;
- private final Runnable connectedRunnable;
-
- public Netty5Client(ProtonTestClientOptions options, Runnable connectedRunnable, Consumer inputConsumer) {
- Objects.requireNonNull(options);
- Objects.requireNonNull(inputConsumer);
- Objects.requireNonNull(connectedRunnable);
-
- this.options = options;
- this.connectedRunnable = connectedRunnable;
- this.inputConsumer = inputConsumer;
- }
-
- @Override
- public void close() throws Exception {
- if (closed.compareAndSet(false, true)) {
- connected.set(false);
- connectedLatch.countDown();
- if (channel != null) {
- try {
- if (!channel.close().asStage().await(10, TimeUnit.SECONDS)) {
- LOG.info("Channel close timed out waiting for result");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Close of channel interrupted while awaiting result");
- }
- }
-
- if (group != null && !group.isShutdown()) {
- group.shutdownGracefully(0, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
- try {
- if (eventLoop != null && eventLoop.inEventLoop()) {
- // If scripted close we might be inside the event loop and
- // we cannot wait in that case.
- return;
- }
-
- if (!group.awaitTermination(2 * SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
- LOG.trace("Connection IO Event Loop shutdown failed to complete in allotted time");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Shutdown of netty event loop interrupted while awaiting result");
- }
- }
- }
- }
-
- @Override
- public void connect(String host, int port) throws IOException {
- if (closed.get()) {
- throw new IllegalStateException("Netty client has already been closed");
- }
-
- if (host == null || host.isEmpty()) {
- throw new IllegalArgumentException("Transport host value cannot be null");
- }
-
- this.host = host;
-
- if (port > 0) {
- this.port = port;
- } else {
- if (options.isSecure()) {
- this.port = ProtonTestClientOptions.DEFAULT_SSL_PORT;
- } else {
- this.port = ProtonTestClientOptions.DEFAULT_TCP_PORT;
- }
- }
-
- group = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
- bootstrap = new Bootstrap().channel(NioSocketChannel.class).group(group);
- bootstrap.handler(new ChannelInitializer() {
- @Override
- public void initChannel(Channel transportChannel) throws Exception {
- channel = transportChannel;
- eventLoop = new Netty5EventLoop(channel.executor());
- configureChannel(transportChannel);
- }
- });
-
- configureNetty(bootstrap, options);
-
- bootstrap.connect(host, port).addListener(channel, ChannelFutureListeners.FIRE_EXCEPTION_ON_FAILURE);
- try {
- connectedLatch.await();
- } catch (InterruptedException e) {
- Thread.interrupted();
- }
-
- if (!connected.get()) {
- if (failureCause != null) {
- throw failureCause;
- } else {
- throw new IOException("Netty client was closed before a connection was established.");
- }
- }
- }
-
- @Override
- public NettyEventLoop eventLoop() {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return eventLoop;
- }
-
- @Override
- public void write(ByteBuffer buffer) {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- channel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(buffer).makeReadOnly());
- }
-
- @Override
- public boolean isConnected() {
- return connected.get();
- }
-
- @Override
- public boolean isSecure() {
- return options.isSecure();
- }
-
- @Override
- public boolean isWSCompressionActive() {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return wsCompressionRequest && wsCompressionResponse;
- }
-
- @Override
- public URI getRemoteURI() {
- if (host != null) {
- try {
- if (options.isUseWebSockets()) {
- return new URI(options.isSecure() ? "wss" : "ws", null, host, port, options.getWebSocketPath(), null, null);
- } else {
- return new URI(options.isSecure() ? "ssl" : "tcp", null, host, port, null, null, null);
- }
- } catch (URISyntaxException e) {
- }
- }
-
- return null;
- }
-
- //----- Default implementation of Netty handler
-
- protected class NettyClientInboundHandler implements ChannelHandler {
-
- private final WebSocketClientHandshaker handshaker;
- private Future handshakeTimeoutFuture;
-
- public NettyClientInboundHandler() {
- if (options.isUseWebSockets()) {
- HttpHeaders headers = HttpHeaders.newHeaders();
-
- options.getHttpHeaders().forEach((key, value) -> {
- headers.set(key, value);
- });
-
- handshaker = WebSocketClientHandshakerFactory.newHandshaker(
- getRemoteURI(), WebSocketVersion.V13, AMQP_SUB_PROTOCOL,
- true, headers, options.getWebSocketMaxFrameSize());
- } else {
- handshaker = null;
- }
- }
-
- @Override
- public final void channelRegistered(ChannelHandlerContext context) throws Exception {
- channel = context.channel();
- }
-
- @Override
- public void channelActive(ChannelHandlerContext context) throws Exception {
- if (options.isUseWebSockets()) {
- handshaker.handshake(context.channel());
-
- handshakeTimeoutFuture = context.executor().schedule(()-> {
- LOG.trace("WebSocket handshake timed out! Channel is {}", context.channel());
- if (!handshaker.isHandshakeComplete()) {
- Netty5Client.this.handleTransportFailure(channel, new IOException("WebSocket handshake timed out"));
- }
- }, options.getConnectTimeout(), TimeUnit.MILLISECONDS);
- }
-
- // In the Secure case we need to let the handshake complete before we
- // trigger the connected event.
- if (!isSecure()) {
- if (!options.isUseWebSockets()) {
- handleConnected(context.channel());
- }
- } else {
- SslHandler sslHandler = context.pipeline().get(SslHandler.class);
- sslHandler.handshakeFuture().addListener(new FutureListener() {
- @Override
- public void operationComplete(Future extends Channel> future) throws Exception {
- if (future.isSuccess()) {
- LOG.trace("SSL Handshake has completed: {}", channel);
- if (!options.isUseWebSockets()) {
- handleConnected(channel);
- }
- } else {
- LOG.trace("SSL Handshake has failed: {}", channel);
- handleTransportFailure(channel, future.cause());
- }
- }
- });
- }
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext context) throws Exception {
- if (handshakeTimeoutFuture != null) {
- handshakeTimeoutFuture.cancel();
- }
-
- handleTransportFailure(context.channel(), new IOException("Remote closed connection unexpectedly"));
- }
-
- @Override
- public void channelExceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
- handleTransportFailure(context.channel(), cause);
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object message) {
- if (options.isUseWebSockets()) {
- LOG.trace("New data read: incoming: {}", message);
-
- Channel ch = ctx.channel();
- if (!handshaker.isHandshakeComplete()) {
- handshaker.finishHandshake(ch, (FullHttpResponse) message);
- LOG.trace("WebSocket Client connected! {}", ctx.channel());
- // Now trigger super processing as we are really connected.
- if (handshakeTimeoutFuture.cancel()) {
- handleConnected(ch);
- }
-
- return;
- }
-
- // We shouldn't get this since we handle the handshake previously.
- if (message instanceof FullHttpResponse) {
- FullHttpResponse response = (FullHttpResponse) message;
- throw new IllegalStateException(
- "Unexpected FullHttpResponse (getStatus=" + response.status() +
- ", content=" + response.payload().toString(StandardCharsets.UTF_8) + ')');
- }
-
- WebSocketFrame frame = (WebSocketFrame) message;
- if (frame instanceof TextWebSocketFrame) {
- TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
- LOG.warn("WebSocket Client received message: " + textFrame.text());
- ctx.fireChannelExceptionCaught(new IOException("Received invalid frame over WebSocket."));
- } else if (frame instanceof BinaryWebSocketFrame) {
- BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data: {} bytes", binaryFrame.binaryData().readableBytes());
- ctx.fireChannelRead(binaryFrame.binaryData());
- } else if (frame instanceof ContinuationWebSocketFrame) {
- ContinuationWebSocketFrame continuationFrame = (ContinuationWebSocketFrame) frame;
- LOG.trace("WebSocket Client received data continuation: {} bytes", continuationFrame.binaryData().readableBytes());
- ctx.fireChannelRead(continuationFrame.binaryData());
- } else if (frame instanceof PingWebSocketFrame) {
- LOG.trace("WebSocket Client received ping, response with pong");
- ch.write(new PongWebSocketFrame(frame.binaryData()));
- } else if (frame instanceof CloseWebSocketFrame) {
- LOG.trace("WebSocket Client received closing");
- ch.close();
- }
- } else {
- ctx.fireChannelRead(message);
- }
- }
- }
-
- private class NettyClientOutboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public Future write(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (options.isUseWebSockets() && msg instanceof Buffer) {
- if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
- int split = orig.readableBytes()/2;
-
- Buffer part1 = orig.copy(origIndex, split);
- LOG.trace("NettyClientOutboundHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
- LOG.trace("NettyClientOutboundHandler: Part2: {}", orig);
-
- BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
- ctx.writeAndFlush(frame1);
- ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
- } else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
- }
- } else {
- return ctx.write(msg);
- }
- }
- }
-
- private class ClientWSCompressionObserverHandler extends ChannelHandlerAdapter {
-
- final String WS_EXTENSIONS_SECTION = "sec-websocket-extensions";
- final String WS_PERMESSAGE_DEFLATE = "permessage-deflate";
- final String WS_UPGRADE = "upgrade";
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object message) {
- if (message instanceof FullHttpResponse) {
- FullHttpResponse response = (FullHttpResponse) message;
- HttpHeaders headers = response.headers();
-
- if (headers.contains(WS_UPGRADE) && headers.contains(WS_EXTENSIONS_SECTION)) {
- wsCompressionRequest = headers.get(WS_EXTENSIONS_SECTION).toString().contains(WS_PERMESSAGE_DEFLATE);
- }
- }
-
- ctx.fireChannelRead(message);
- }
-
- @Override
- public Future write(ChannelHandlerContext context, Object message) {
- if (message instanceof FullHttpRequest) {
- FullHttpRequest request = (FullHttpRequest) message;
- HttpHeaders headers = request.headers();
-
- if (headers.contains(WS_UPGRADE) && headers.contains(WS_EXTENSIONS_SECTION)) {
- wsCompressionRequest = headers.get(WS_EXTENSIONS_SECTION).toString().contains(WS_PERMESSAGE_DEFLATE);
- }
- }
-
- return context.write(message);
- }
- }
-
- //----- Internal Client implementation API
-
- protected ChannelHandler getClientHandler() {
- return new SimpleChannelInboundHandler() {
-
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
- LOG.trace("AMQP Test Client Channel read: {}", input);
-
- // Driver processes new data and may produce output based on this.
- try {
- final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
- input.readBytes(copy);
- inputConsumer.accept(copy.flip().asReadOnlyBuffer());
- } catch (Throwable e) {
- LOG.error("Closed AMQP Test client channel due to error: ", e);
- ctx.channel().close();
- }
- }
- };
- }
-
- protected EventLoop getEventLoop() {
- if (channel == null || !channel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return channel.executor();
- }
-
- protected SslHandler getSslHandler() {
- return sslHandler;
- }
-
- private void configureChannel(final Channel channel) throws Exception {
- if (isSecure()) {
- final SslHandler sslHandler;
- try {
- sslHandler = SslSupport.createClientSslHandler(getRemoteURI(), options);
- } catch (Exception ex) {
- LOG.warn("Error during initialization of channel from SSL Handler creation:");
- handleTransportFailure(channel, ex);
- throw new IOException(ex);
- }
-
- channel.pipeline().addLast("ssl", sslHandler);
- }
-
- if (options.isTraceBytes()) {
- channel.pipeline().addLast("logger", new LoggingHandler(getClass()));
- }
-
- if (options.isUseWebSockets()) {
- channel.pipeline().addLast(new HttpClientCodec());
- channel.pipeline().addLast(new HttpObjectAggregator(8192));
- if (options.isWebSocketCompression()) {
- channel.pipeline().addLast(new ClientWSCompressionObserverHandler());
- channel.pipeline().addLast(WebSocketClientCompressionHandler.INSTANCE);
- }
- }
-
- channel.pipeline().addLast(new NettyClientOutboundHandler());
- channel.pipeline().addLast(new NettyClientInboundHandler());
- channel.pipeline().addLast(getClientHandler());
- }
-
- private void configureNetty(Bootstrap bootstrap, ProtonTestClientOptions options) {
- bootstrap.option(ChannelOption.TCP_NODELAY, options.isTcpNoDelay());
- bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeout());
- bootstrap.option(ChannelOption.SO_KEEPALIVE, options.isTcpKeepAlive());
- bootstrap.option(ChannelOption.SO_LINGER, options.getSoLinger());
-
- if (options.getSendBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_SNDBUF, options.getSendBufferSize());
- }
-
- if (options.getReceiveBufferSize() != -1) {
- bootstrap.option(ChannelOption.SO_RCVBUF, options.getReceiveBufferSize());
- }
-
- if (options.getTrafficClass() != -1) {
- bootstrap.option(ChannelOption.IP_TOS, options.getTrafficClass());
- }
-
- if (options.getLocalAddress() != null || options.getLocalPort() != 0) {
- if (options.getLocalAddress() != null) {
- bootstrap.localAddress(options.getLocalAddress(), options.getLocalPort());
- } else {
- bootstrap.localAddress(options.getLocalPort());
- }
- }
- }
-
- //----- Event Handlers which can be overridden in subclasses -------------//
-
- protected void handleConnected(Channel connectedChannel) {
- LOG.trace("Channel has become active! Channel is {}", connectedChannel);
- channel = connectedChannel;
- connected.set(true);
- connectedLatch.countDown();
- connectedRunnable.run();
- }
-
- protected void handleTransportFailure(Channel failedChannel, Throwable cause) {
- if (!closed.get()) {
- LOG.trace("Channel indicates connection failure! Channel is {}", failedChannel);
- failureCause = new IOException(cause);
- channel = failedChannel;
- connected.set(false);
- connectedLatch.countDown();
- } else {
- LOG.trace("Closed Channel signalled that the channel ended: {}", channel);
- }
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java
deleted file mode 100644
index 16056003c..000000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5EventLoop.java
+++ /dev/null
@@ -1,48 +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.netty.netty5;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
-
-import io.netty5.channel.EventLoop;
-
-public final class Netty5EventLoop implements NettyEventLoop {
-
- private final EventLoop loop;
-
- public Netty5EventLoop(EventLoop loop) {
- this.loop = loop;
- }
-
- @Override
- public boolean inEventLoop() {
- return loop.inEventLoop();
- }
-
- @Override
- public void execute(Runnable runnable) {
- loop.execute(runnable);
- }
-
- @Override
- public void schedule(Runnable runnable, int delay, TimeUnit unit) {
- loop.schedule(runnable, delay, unit);
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java
deleted file mode 100644
index 4e08ba491..000000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Server.java
+++ /dev/null
@@ -1,580 +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.netty.netty5;
-
-import java.lang.invoke.MethodHandles;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLPeerUnverifiedException;
-
-import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
-import org.apache.qpid.protonj2.test.driver.netty.NettyEventLoop;
-import org.apache.qpid.protonj2.test.driver.netty.NettyServer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.bootstrap.ServerBootstrap;
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.DefaultBufferAllocators;
-import io.netty5.channel.Channel;
-import io.netty5.channel.ChannelFutureListeners;
-import io.netty5.channel.ChannelHandler;
-import io.netty5.channel.ChannelHandlerAdapter;
-import io.netty5.channel.ChannelHandlerContext;
-import io.netty5.channel.ChannelInitializer;
-import io.netty5.channel.ChannelOption;
-import io.netty5.channel.EventLoopGroup;
-import io.netty5.channel.MultithreadEventLoopGroup;
-import io.netty5.channel.SimpleChannelInboundHandler;
-import io.netty5.channel.nio.NioHandler;
-import io.netty5.channel.socket.nio.NioServerSocketChannel;
-import io.netty5.handler.codec.http.DefaultFullHttpResponse;
-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.headers.HttpHeaders;
-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.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
-import io.netty5.handler.logging.LogLevel;
-import io.netty5.handler.logging.LoggingHandler;
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.util.concurrent.Future;
-import io.netty5.util.concurrent.FutureListener;
-
-/**
- * Base Server implementation used to create Netty based server implementations for
- * unit testing aspects of the client code.
- */
-public final class Netty5Server implements NettyServer {
-
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- static final int PORT = Integer.parseInt(System.getProperty("port", "5672"));
- static final String WEBSOCKET_PATH = "/";
- static final int DEFAULT_MAX_FRAME_SIZE = 65535;
-
- private Netty5EventLoop eventLoop;
- private EventLoopGroup bossGroup;
- private EventLoopGroup workerGroup;
- private Channel serverChannel;
- private Channel clientChannel;
- private final ProtonTestServerOptions options;
- private int maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
- private String webSocketPath = WEBSOCKET_PATH;
- private boolean wsCompressionRequest;
- private boolean wsCompressionResponse;
- private volatile SslHandler sslHandler;
- private volatile WebSocketServerHandshakeCompletionEvent handshakeComplete;
- private final CountDownLatch handshakeCompletion = new CountDownLatch(1);
-
- private final AtomicBoolean started = new AtomicBoolean();
-
- private final Consumer inputConsumer;
- private final Runnable connectedRunnable;
- private final Runnable disconnectedRunnable;
-
- public Netty5Server(ProtonTestServerOptions options, Runnable connectedRunnable, Runnable disconnectedRunnable, Consumer inputConsumer) {
- Objects.requireNonNull(options);
- Objects.requireNonNull(inputConsumer);
- Objects.requireNonNull(connectedRunnable);
-
- this.options = options;
- this.connectedRunnable = connectedRunnable;
- this.disconnectedRunnable = disconnectedRunnable;
- this.inputConsumer = inputConsumer;
- }
-
- @Override
- public boolean isSecureServer() {
- return options.isSecure();
- }
-
- @Override
- public boolean isAcceptingConnections() {
- return serverChannel != null && serverChannel.isOpen();
- }
-
- @Override
- public boolean hasSecureConnection() {
- return sslHandler != null;
- }
-
- @Override
- public boolean hasClientConnection() {
- return clientChannel != null && clientChannel.isOpen();
- }
-
- @Override
- public int getClientPort() {
- Objects.requireNonNull(clientChannel);
- return (((InetSocketAddress) clientChannel.remoteAddress()).getPort());
- }
-
- @Override
- public boolean isWSCompressionActive() {
- Objects.requireNonNull(clientChannel);
- return wsCompressionRequest && wsCompressionResponse;
- }
-
- @Override
- public boolean isPeerVerified() {
- try {
- if (hasSecureConnection()) {
- return sslHandler.engine().getSession().getPeerPrincipal() != null;
- } else {
- return false;
- }
- } catch (SSLPeerUnverifiedException unverified) {
- return false;
- }
- }
-
- @Override
- public SSLEngine getConnectionSSLEngine() {
- if (hasSecureConnection()) {
- return sslHandler.engine();
- } else {
- return null;
- }
- }
-
- @Override
- public boolean isWebSocketServer() {
- return options.isUseWebSockets();
- }
-
- @Override
- public String getWebSocketPath() {
- return webSocketPath;
- }
-
- @Override
- public void setWebSocketPath(String webSocketPath) {
- this.webSocketPath = webSocketPath;
- }
-
- @Override
- public int getMaxFrameSize() {
- return maxFrameSize;
- }
-
- @Override
- public void setMaxFrameSize(int maxFrameSize) {
- this.maxFrameSize = maxFrameSize;
- }
-
- public boolean awaitHandshakeCompletion(long delayMs) throws InterruptedException {
- return handshakeCompletion.await(delayMs, TimeUnit.MILLISECONDS);
- }
-
- public WebSocketServerHandshakeCompletionEvent getHandshakeComplete() {
- return handshakeComplete;
- }
-
- @Override
- public URI getConnectionURI(String queryString) throws Exception {
- if (!started.get()) {
- throw new IllegalStateException("Cannot get URI of non-started server");
- }
-
- int port = getServerPort();
-
- String scheme;
- String path;
-
- if (isWebSocketServer()) {
- if (isSecureServer()) {
- scheme = "amqpwss";
- } else {
- scheme = "amqpws";
- }
- } else {
- if (isSecureServer()) {
- scheme = "amqps";
- } else {
- scheme = "amqp";
- }
- }
-
- if (isWebSocketServer()) {
- path = getWebSocketPath();
- } else {
- path = null;
- }
-
- if (queryString != null && queryString.startsWith("?")) {
- queryString = queryString.substring(1);
- }
-
- return new URI(scheme, null, "localhost", port, path, queryString, null);
- }
-
- @Override
- public void start() throws Exception {
- if (started.compareAndSet(false, true)) {
- // Configure the server to basic NIO type channels
- bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
- workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
-
- ServerBootstrap server = new ServerBootstrap();
- server.group(bossGroup, workerGroup);
- server.channel(NioServerSocketChannel.class);
- server.option(ChannelOption.SO_BACKLOG, 100);
- server.handler(new LoggingHandler(LogLevel.INFO));
- server.childHandler(new ChannelInitializer() {
-
- @Override
- public void initChannel(Channel ch) throws Exception {
- // Don't accept any new connections.
- serverChannel.close();
- // Now we know who the client is
- clientChannel = ch;
- eventLoop = new Netty5EventLoop(ch.executor());
-
- if (isSecureServer()) {
- ch.pipeline().addLast(sslHandler = SslSupport.createServerSslHandler(null, options));
- }
-
- if (options.isUseWebSockets()) {
- ch.pipeline().addLast(new HttpServerCodec());
- ch.pipeline().addLast(new HttpObjectAggregator(65536));
- if (options.isWebSocketCompression()) {
- ch.pipeline().addLast(new ServerWSCompressionObserverHandler());
- ch.pipeline().addLast(new WebSocketServerCompressionHandler());
- }
- ch.pipeline().addLast(new WebSocketServerProtocolHandler(getWebSocketPath(), "amqp", true, maxFrameSize));
- }
-
- ch.pipeline().addLast(new NettyServerOutboundHandler());
- ch.pipeline().addLast(new NettyServerInboundHandler());
- ch.pipeline().addLast(getServerHandler());
- }
- });
-
- // Start the server and then update the server port in case the configuration
- // was such that the server chose a free port.
- serverChannel = server.bind(options.getServerPort()).asStage().get();
- options.setServerPort(((InetSocketAddress) serverChannel.localAddress()).getPort());
- }
- }
-
- protected ChannelHandler getServerHandler() {
- return new SimpleChannelInboundHandler() {
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- connectedRunnable.run();
- ctx.fireChannelActive();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- disconnectedRunnable.run();
- ctx.fireChannelInactive();
- }
-
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Buffer input) throws Exception {
- LOG.trace("AMQP Test Server Channel read: {}", input);
-
- // Driver processes new data and may produce output based on this.
- try {
- final ByteBuffer copy = ByteBuffer.allocate(input.readableBytes());
- input.readBytes(copy);
- inputConsumer.accept(copy.flip().asReadOnlyBuffer());
- } catch (Throwable e) {
- LOG.error("Closed AMQP Test server channel due to error: ", e);
- ctx.channel().close();
- }
- }
- };
- }
-
- @Override
- public void write(ByteBuffer frame) {
- if (clientChannel == null || !clientChannel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- clientChannel.writeAndFlush(BufferAllocator.onHeapUnpooled().copyOf(frame).makeReadOnly());
- }
-
- @Override
- public NettyEventLoop eventLoop() {
- if (clientChannel == null || !clientChannel.isActive()) {
- throw new IllegalStateException("Channel is not connected or has closed");
- }
-
- return eventLoop;
- }
-
- @Override
- public void stop() throws InterruptedException {
- if (started.compareAndSet(true, false)) {
- LOG.info("Syncing channel close");
- serverChannel.close().asStage().sync();
-
- if (clientChannel != null) {
- try {
- if (!clientChannel.close().asStage().await(10, TimeUnit.SECONDS)) {
- LOG.info("Connected Client channel close timed out waiting for result");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Close of connected client channel interrupted while awaiting result");
- }
- }
-
- // Shut down all event loops to terminate all threads.
- int timeout = 100;
- LOG.trace("Shutting down boss group");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
- LOG.trace("Boss group shut down");
-
- LOG.trace("Shutting down worker group");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS).asStage().await(timeout, TimeUnit.MILLISECONDS);
- LOG.trace("Worker group shut down");
- }
- }
-
- @Override
- public void stopAsync() throws InterruptedException {
- if (started.compareAndSet(true, false)) {
- LOG.info("Closing channel asynchronously");
- serverChannel.close().asStage().sync();
-
- if (clientChannel != null) {
- clientChannel.close();
- }
-
- // Shut down all event loops to terminate all threads.
- int timeout = 100;
- LOG.trace("Shutting down boss group asynchronously");
- bossGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
-
- LOG.trace("Shutting down worker group asynchronously");
- workerGroup.shutdownGracefully(0, timeout, TimeUnit.MILLISECONDS);
- }
- }
-
- @Override
- public void close() throws InterruptedException {
- stop();
- }
-
- @Override
- public void disconnectClient() throws Exception {
- if (!started.get() || !serverChannel.isOpen()) {
- throw new IllegalStateException("Server must be currently active in order to reset");
- }
-
- if (clientChannel != null) {
- try {
- if (!clientChannel.close().asStage().await(10, TimeUnit.SECONDS)) {
- LOG.info("Connected Client channel close timed out waiting for result");
- }
- } catch (InterruptedException e) {
- Thread.interrupted();
- LOG.debug("Close of connected client channel interrupted while awaiting result");
- } finally {
- clientChannel = null;
- }
- }
- }
-
- @Override
- public int getServerPort() {
- if (!started.get()) {
- throw new IllegalStateException("Cannot get server port of non-started server");
- }
-
- return options.getServerPort();
- }
-
- private class NettyServerOutboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public Future write(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel write: {}", msg);
- if (isWebSocketServer() && msg instanceof Buffer) {
- if (options.isFragmentWrites()) {
- Buffer orig = (Buffer) msg;
- int origIndex = orig.readerOffset();
- int split = orig.readableBytes()/2;
-
- Buffer part1 = orig.copy(origIndex, split);
- LOG.trace("NettyServerHandler: Part1: {}", part1);
- orig.readerOffset(origIndex + split);
- LOG.trace("NettyServerHandler: Part2: {}", orig);
-
- BinaryWebSocketFrame frame1 = new BinaryWebSocketFrame(false, 0, part1);
- ctx.writeAndFlush(frame1);
- ContinuationWebSocketFrame frame2 = new ContinuationWebSocketFrame(true, 0, orig);
- return ctx.write(frame2);
- } else {
- BinaryWebSocketFrame frame = new BinaryWebSocketFrame((Buffer) msg);
- return ctx.write(frame);
- }
- } else {
- return ctx.write(msg);
- }
- }
- }
-
- private class NettyServerInboundHandler extends ChannelHandlerAdapter {
-
- @Override
- public void channelInboundEvent(ChannelHandlerContext context, Object payload) {
- if (payload instanceof WebSocketServerHandshakeCompletionEvent) {
- handshakeComplete = (WebSocketServerHandshakeCompletionEvent) payload;
- handshakeCompletion.countDown();
- }
- }
-
- @Override
- public void channelActive(final ChannelHandlerContext ctx) {
- LOG.info("NettyServerHandler -> New active channel: {}", ctx.channel());
- SslHandler handler = ctx.pipeline().get(SslHandler.class);
- if (handler != null) {
- handler.handshakeFuture().addListener(new FutureListener() {
- @Override
- public void operationComplete(Future extends Channel> future) throws Exception {
- LOG.info("Server -> SSL handshake completed. Succeeded: {}", future.isSuccess());
- if (!future.isSuccess()) {
- ctx.close();
- }
- }
- });
- }
-
- ctx.fireChannelActive();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- LOG.info("NettyServerHandler: channel has gone inactive: {}", ctx.channel());
- ctx.close();
- ctx.fireChannelInactive();
- Netty5Server.this.clientChannel = null;
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("NettyServerHandler: Channel read: {}", msg);
- if (msg instanceof WebSocketFrame) {
- WebSocketFrame frame = (WebSocketFrame) msg;
- ctx.fireChannelRead(frame.binaryData());
- } else if (msg instanceof FullHttpRequest) {
- // Reject anything not on the WebSocket path
- FullHttpRequest request = (FullHttpRequest) msg;
-
- sendHttpResponse(ctx, request,
- new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST, DefaultBufferAllocators.onHeapAllocator().allocate(0)));
- } else {
- // Forward anything else along to the next handler.
- ctx.fireChannelRead(msg);
- }
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- ctx.flush();
- }
-
- @Override
- public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- LOG.info("NettyServerHandler: NettyServerHandlerException caught on channel: {}", ctx.channel());
- // Close the connection when an exception is raised.
- cause.printStackTrace();
- ctx.close();
- }
- }
-
- private class ServerWSCompressionObserverHandler extends ChannelHandlerAdapter {
-
- final String WS_EXTENSIONS_SECTION = "sec-websocket-extensions";
- final String WS_PERMESSAGE_DEFLATE = "permessage-deflate";
- final String WS_UPGRADE = "upgrade";
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object message) {
- if (message instanceof FullHttpRequest) {
- FullHttpRequest request = (FullHttpRequest) message;
- HttpHeaders headers = request.headers();
-
- if (headers.contains(WS_UPGRADE) && headers.contains(WS_EXTENSIONS_SECTION)) {
- wsCompressionRequest = headers.get(WS_EXTENSIONS_SECTION).toString().contains(WS_PERMESSAGE_DEFLATE);
- }
- }
-
- ctx.fireChannelRead(message);
- }
-
- @Override
- public Future write(ChannelHandlerContext context, Object message) {
- if (message instanceof FullHttpResponse) {
- FullHttpResponse response = (FullHttpResponse) message;
- HttpHeaders headers = response.headers();
-
- if (headers.contains(WS_UPGRADE) && headers.contains(WS_EXTENSIONS_SECTION)) {
- wsCompressionResponse = headers.get(WS_EXTENSIONS_SECTION).toString().contains(WS_PERMESSAGE_DEFLATE);
- }
- }
-
- return context.write(message);
- }
- }
-
- private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {
- // Generate an error page if response getStatus code is not OK (200).
- if (response.status().code() != 200) {
- byte[] status = response.status().toString().getBytes(StandardCharsets.UTF_8);
- response.payload().writeBytes(status);
- HttpUtil.setContentLength(response, response.payload().readableBytes());
- }
-
- // Send the response and close the connection if necessary.
- Future f = ctx.channel().writeAndFlush(response);
- if (!HttpUtil.isKeepAlive(request) || response.status().code() != 200) {
- f.addListener(ctx.channel(), ChannelFutureListeners.CLOSE);
- }
- }
-
- protected SslHandler getSslHandler() {
- return sslHandler;
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java
deleted file mode 100644
index 776744fd2..000000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/Netty5Support.java
+++ /dev/null
@@ -1,48 +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.netty.netty5;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.buffer.BufferAllocator;
-
-/**
- * Support class used to detect if Netty 5 is available on the class path.
- */
-public final class Netty5Support {
-
- private static final Logger LOG = LoggerFactory.getLogger(Netty5Support.class);
-
- 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;
- }
-
- public static final boolean isAvailable() {
- return UNAVAILABILITY_CAUSE == null;
- }
-}
diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java
deleted file mode 100644
index 5fbdcae2c..000000000
--- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/netty/netty5/SslSupport.java
+++ /dev/null
@@ -1,498 +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.netty.netty5;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509ExtendedKeyManager;
-
-import org.apache.qpid.protonj2.test.driver.ProtonTestClientOptions;
-import org.apache.qpid.protonj2.test.driver.ProtonTestServerOptions;
-import org.apache.qpid.protonj2.test.driver.netty.X509AliasKeyManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.netty5.handler.ssl.SslHandler;
-import io.netty5.handler.ssl.util.InsecureTrustManagerFactory;
-
-/**
- * Static class that provides various utility methods used by Transport implementations.
- */
-public class SslSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- /**
- * Creates a Netty SslHandler instance for use in client instances that require
- * an SSL encoder / decoder.
- *
- * If the given options contain an SSLContext override, this will be used directly
- * when creating the handler. If they do not, an SSLContext will first be created
- * using the other option values.
- *
- * @param remote
- * The URI of the remote peer that the SslHandler will be used against.
- * @param options
- * The SSL options object to build the SslHandler instance from.
- *
- * @return a new SslHandler that is configured from the given options.
- *
- * @throws Exception if an error occurs while creating the SslHandler instance.
- */
- public static SslHandler createClientSslHandler(URI remote, ProtonTestClientOptions options) throws Exception {
- final SSLEngine sslEngine;
-
- SSLContext sslContext = options.getSslContextOverride();
- if (sslContext == null) {
- sslContext = createClientJdkSslContext(options);
- }
-
- sslEngine = createClientJdkSslEngine(remote, sslContext, options);
-
- return new SslHandler(sslEngine);
- }
-
- /**
- * Creates a Netty SslHandler instance for use in server instances that require
- * an SSL encoder / decoder.
- *
- * If the given options contain an SSLContext override, this will be used directly
- * when creating the handler. If they do not, an SSLContext will first be created
- * using the other option values.
- *
- * @param remote
- * The URI of the remote peer that the SslHandler will be used against.
- * @param options
- * The SSL options object to build the SslHandler instance from.
- *
- * @return a new SslHandler that is configured from the given options.
- *
- * @throws Exception if an error occurs while creating the SslHandler instance.
- */
- public static SslHandler createServerSslHandler(URI remote, ProtonTestServerOptions options) throws Exception {
- final SSLEngine sslEngine;
-
- SSLContext sslContext = options.getSslContextOverride();
- if (sslContext == null) {
- sslContext = createServerJdkSslContext(options);
- }
-
- sslEngine = createServerJdkSslEngine(remote, sslContext, options);
-
- return new SslHandler(sslEngine);
- }
-
- //----- JDK SSL Support Methods ------------------------------------------//
-
- /**
- * Create a new SSLContext using the options specific in the given TransportOptions
- * instance.
- *
- * @param options
- * the configured options used to create the SSLContext.
- *
- * @return a new SSLContext instance.
- *
- * @throws Exception if an error occurs while creating the context.
- */
- public static SSLContext createClientJdkSslContext(ProtonTestClientOptions options) throws Exception {
- try {
- String contextProtocol = options.getContextProtocol();
- LOG.trace("Getting SSLContext instance using protocol: {}", contextProtocol);
-
- SSLContext context = SSLContext.getInstance(contextProtocol);
-
- KeyManager[] keyMgrs = loadKeyManagers(options);
- TrustManager[] trustManagers = loadTrustManagers(options);
-
- context.init(keyMgrs, trustManagers, new SecureRandom());
- return context;
- } catch (Exception e) {
- LOG.error("Failed to create SSLContext: {}", e, e);
- throw e;
- }
- }
-
- /**
- * Create a new SSLContext using the options specific in the given TransportOptions
- * instance.
- *
- * @param options
- * the configured options used to create the SSLContext.
- *
- * @return a new SSLContext instance.
- *
- * @throws Exception if an error occurs while creating the context.
- */
- public static SSLContext createServerJdkSslContext(ProtonTestServerOptions options) throws Exception {
- try {
- String contextProtocol = options.getContextProtocol();
- LOG.trace("Getting SSLContext instance using protocol: {}", contextProtocol);
-
- SSLContext context = SSLContext.getInstance(contextProtocol);
-
- KeyManager[] keyMgrs = loadKeyManagers(options);
- TrustManager[] trustManagers = loadTrustManagers(options);
-
- context.init(keyMgrs, trustManagers, new SecureRandom());
- return context;
- } catch (Exception e) {
- LOG.error("Failed to create SSLContext: {}", e, e);
- throw e;
- }
- }
-
- /**
- * Create a new JDK SSLEngine instance in client mode from the given SSLContext and
- * TransportOptions instances.
- *
- * @param remote
- * the URI of the remote peer that will be used to initialize the engine, may be null if none should.
- * @param context
- * the SSLContext to use when creating the engine.
- * @param options
- * the TransportOptions to use to configure the new SSLEngine.
- *
- * @return a new SSLEngine instance in client mode.
- *
- * @throws Exception if an error occurs while creating the new SSLEngine.
- */
- public static SSLEngine createClientJdkSslEngine(URI remote, SSLContext context, ProtonTestClientOptions options) throws Exception {
- SSLEngine engine = null;
- if (remote == null) {
- engine = context.createSSLEngine();
- } else {
- engine = context.createSSLEngine(remote.getHost(), remote.getPort());
- }
-
- engine.setEnabledProtocols(buildEnabledProtocols(engine, options));
- engine.setEnabledCipherSuites(buildEnabledCipherSuites(engine, options));
- engine.setUseClientMode(true);
- engine.setNeedClientAuth(options.isNeedClientAuth());
-
- if (options.isVerifyHost()) {
- SSLParameters sslParameters = engine.getSSLParameters();
- sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
- engine.setSSLParameters(sslParameters);
- }
-
- return engine;
- }
-
- /**
- * Create a new JDK SSLEngine instance in client mode from the given SSLContext and
- * TransportOptions instances.
- *
- * @param remote
- * the URI of the remote peer that will be used to initialize the engine, may be null if none should.
- * @param context
- * the SSLContext to use when creating the engine.
- * @param options
- * the TransportOptions to use to configure the new SSLEngine.
- *
- * @return a new SSLEngine instance in client mode.
- *
- * @throws Exception if an error occurs while creating the new SSLEngine.
- */
- public static SSLEngine createServerJdkSslEngine(URI remote, SSLContext context, ProtonTestServerOptions options) throws Exception {
- SSLEngine engine = null;
- if (remote == null) {
- engine = context.createSSLEngine();
- } else {
- engine = context.createSSLEngine(remote.getHost(), remote.getPort());
- }
-
- engine.setEnabledProtocols(buildEnabledProtocols(engine, options));
- engine.setEnabledCipherSuites(buildEnabledCipherSuites(engine, options));
- engine.setUseClientMode(false);
- engine.setNeedClientAuth(options.isNeedClientAuth());
-
- if (options.isVerifyHost()) {
- SSLParameters sslParameters = engine.getSSLParameters();
- sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
- engine.setSSLParameters(sslParameters);
- }
-
- return engine;
- }
-
- //----- Internal support methods -----------------------------------------//
-
- private static String[] buildEnabledProtocols(SSLEngine engine, ProtonTestClientOptions options) {
- List enabledProtocols = new ArrayList<>();
-
- if (options.getEnabledProtocols() != null) {
- List configuredProtocols = Arrays.asList(options.getEnabledProtocols());
- LOG.trace("Configured protocols from transport options: {}", configuredProtocols);
- enabledProtocols.addAll(configuredProtocols);
- } else {
- List engineProtocols = Arrays.asList(engine.getEnabledProtocols());
- LOG.trace("Default protocols from the SSLEngine: {}", engineProtocols);
- enabledProtocols.addAll(engineProtocols);
- }
-
- String[] disabledProtocols = options.getDisabledProtocols();
- if (disabledProtocols != null) {
- List disabled = Arrays.asList(disabledProtocols);
- LOG.trace("Disabled protocols: {}", disabled);
- enabledProtocols.removeAll(disabled);
- }
-
- LOG.trace("Enabled protocols: {}", enabledProtocols);
-
- return enabledProtocols.toArray(new String[0]);
- }
-
- private static String[] buildEnabledProtocols(SSLEngine engine, ProtonTestServerOptions options) {
- List enabledProtocols = new ArrayList<>();
-
- if (options.getEnabledProtocols() != null) {
- List configuredProtocols = Arrays.asList(options.getEnabledProtocols());
- LOG.trace("Configured protocols from transport options: {}", configuredProtocols);
- enabledProtocols.addAll(configuredProtocols);
- } else {
- List engineProtocols = Arrays.asList(engine.getEnabledProtocols());
- LOG.trace("Default protocols from the SSLEngine: {}", engineProtocols);
- enabledProtocols.addAll(engineProtocols);
- }
-
- String[] disabledProtocols = options.getDisabledProtocols();
- if (disabledProtocols != null) {
- List disabled = Arrays.asList(disabledProtocols);
- LOG.trace("Disabled protocols: {}", disabled);
- enabledProtocols.removeAll(disabled);
- }
-
- LOG.trace("Enabled protocols: {}", enabledProtocols);
-
- return enabledProtocols.toArray(new String[0]);
- }
-
- private static String[] buildEnabledCipherSuites(SSLEngine engine, ProtonTestServerOptions options) {
- List enabledCipherSuites = new ArrayList<>();
-
- if (options.getEnabledCipherSuites() != null) {
- List configuredCipherSuites = Arrays.asList(options.getEnabledCipherSuites());
- LOG.trace("Configured cipher suites from transport options: {}", configuredCipherSuites);
- enabledCipherSuites.addAll(configuredCipherSuites);
- } else {
- List engineCipherSuites = Arrays.asList(engine.getEnabledCipherSuites());
- LOG.trace("Default cipher suites from the SSLEngine: {}", engineCipherSuites);
- enabledCipherSuites.addAll(engineCipherSuites);
- }
-
- String[] disabledCipherSuites = options.getDisabledCipherSuites();
- if (disabledCipherSuites != null) {
- List disabled = Arrays.asList(disabledCipherSuites);
- LOG.trace("Disabled cipher suites: {}", disabled);
- enabledCipherSuites.removeAll(disabled);
- }
-
- LOG.trace("Enabled cipher suites: {}", enabledCipherSuites);
-
- return enabledCipherSuites.toArray(new String[0]);
- }
-
- private static String[] buildEnabledCipherSuites(SSLEngine engine, ProtonTestClientOptions options) {
- List enabledCipherSuites = new ArrayList<>();
-
- if (options.getEnabledCipherSuites() != null) {
- List configuredCipherSuites = Arrays.asList(options.getEnabledCipherSuites());
- LOG.trace("Configured cipher suites from transport options: {}", configuredCipherSuites);
- enabledCipherSuites.addAll(configuredCipherSuites);
- } else {
- List engineCipherSuites = Arrays.asList(engine.getEnabledCipherSuites());
- LOG.trace("Default cipher suites from the SSLEngine: {}", engineCipherSuites);
- enabledCipherSuites.addAll(engineCipherSuites);
- }
-
- String[] disabledCipherSuites = options.getDisabledCipherSuites();
- if (disabledCipherSuites != null) {
- List disabled = Arrays.asList(disabledCipherSuites);
- LOG.trace("Disabled cipher suites: {}", disabled);
- enabledCipherSuites.removeAll(disabled);
- }
-
- LOG.trace("Enabled cipher suites: {}", enabledCipherSuites);
-
- return enabledCipherSuites.toArray(new String[0]);
- }
-
- private static TrustManager[] loadTrustManagers(ProtonTestClientOptions options) throws Exception {
- TrustManagerFactory factory = loadTrustManagerFactory(options);
- if (factory != null) {
- return factory.getTrustManagers();
- } else {
- return null;
- }
- }
-
- private static TrustManager[] loadTrustManagers(ProtonTestServerOptions options) throws Exception {
- TrustManagerFactory factory = loadTrustManagerFactory(options);
- if (factory != null) {
- return factory.getTrustManagers();
- } else {
- return null;
- }
- }
-
- private static TrustManagerFactory loadTrustManagerFactory(ProtonTestClientOptions options) throws Exception {
- if (options.isTrustAll()) {
- return InsecureTrustManagerFactory.INSTANCE;
- }
-
- if (options.getTrustStoreLocation() == null) {
- return null;
- }
-
- TrustManagerFactory fact = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.getTrustStoreLocation();
- String storePassword = options.getTrustStorePassword();
- String storeType = options.getTrustStoreType();
-
- LOG.trace("Attempt to load TrustStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore trustStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(trustStore);
-
- return fact;
- }
-
- private static TrustManagerFactory loadTrustManagerFactory(ProtonTestServerOptions options) throws Exception {
- if (options.isTrustAll()) {
- return InsecureTrustManagerFactory.INSTANCE;
- }
-
- if (options.getTrustStoreLocation() == null) {
- return null;
- }
-
- TrustManagerFactory fact = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.getTrustStoreLocation();
- String storePassword = options.getTrustStorePassword();
- String storeType = options.getTrustStoreType();
-
- LOG.trace("Attempt to load TrustStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore trustStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(trustStore);
-
- return fact;
- }
-
- private static KeyManager[] loadKeyManagers(ProtonTestClientOptions options) throws Exception {
- if (options.getKeyStoreLocation() == null) {
- return null;
- }
-
- KeyManagerFactory fact = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.getKeyStoreLocation();
- String storePassword = options.getKeyStorePassword();
- String storeType = options.getKeyStoreType();
- String alias = options.getKeyAlias();
-
- LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore keyStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(keyStore, storePassword != null ? storePassword.toCharArray() : null);
-
- if (alias == null) {
- return fact.getKeyManagers();
- } else {
- validateAlias(keyStore, alias);
- return wrapKeyManagers(alias, fact.getKeyManagers());
- }
- }
-
- private static KeyManager[] loadKeyManagers(ProtonTestServerOptions options) throws Exception {
- if (options.getKeyStoreLocation() == null) {
- return null;
- }
-
- KeyManagerFactory fact = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-
- String storeLocation = options.getKeyStoreLocation();
- String storePassword = options.getKeyStorePassword();
- String storeType = options.getKeyStoreType();
- String alias = options.getKeyAlias();
-
- LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType);
-
- KeyStore keyStore = loadStore(storeLocation, storePassword, storeType);
- fact.init(keyStore, storePassword != null ? storePassword.toCharArray() : null);
-
- if (alias == null) {
- return fact.getKeyManagers();
- } else {
- validateAlias(keyStore, alias);
- return wrapKeyManagers(alias, fact.getKeyManagers());
- }
- }
-
- private static KeyManager[] wrapKeyManagers(String alias, KeyManager[] origKeyManagers) {
- KeyManager[] keyManagers = new KeyManager[origKeyManagers.length];
- for (int i = 0; i < origKeyManagers.length; i++) {
- KeyManager km = origKeyManagers[i];
- if (km instanceof X509ExtendedKeyManager) {
- km = new X509AliasKeyManager(alias, (X509ExtendedKeyManager) km);
- }
-
- keyManagers[i] = km;
- }
-
- return keyManagers;
- }
-
- private static void validateAlias(KeyStore store, String alias) throws IllegalArgumentException, KeyStoreException {
- if (!store.containsAlias(alias)) {
- throw new IllegalArgumentException("The alias '" + alias + "' doesn't exist in the key store");
- }
-
- if (!store.isKeyEntry(alias)) {
- throw new IllegalArgumentException("The alias '" + alias + "' in the keystore doesn't represent a key entry");
- }
- }
-
- private static KeyStore loadStore(String storePath, final String password, String storeType) throws Exception {
- KeyStore store = KeyStore.getInstance(storeType);
- try (InputStream in = new FileInputStream(new File(storePath));) {
- store.load(in, password != null ? password.toCharArray() : null);
- }
-
- return store;
- }
-}
diff --git a/protonj2/pom.xml b/protonj2/pom.xml
index 59d7c0c6c..c919c19d4 100644
--- a/protonj2/pom.xml
+++ b/protonj2/pom.xml
@@ -39,11 +39,6 @@
netty-buffer
provided
-
- io.netty
- netty5-buffer
- provided
-
org.apache.qpid
proton-j
diff --git a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAllocator.java b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAllocator.java
deleted file mode 100644
index bb3d972b5..000000000
--- a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAllocator.java
+++ /dev/null
@@ -1,139 +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.buffer.netty;
-
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
-
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
-/**
- * Proton managed Netty 5 {@link BufferAllocator} wrapper.
- */
-public final class Netty5ProtonBufferAllocator implements ProtonBufferAllocator {
-
- public static int DEFAULT_CAPACITY = 1024;
-
- public static ProtonBufferAllocator POOLED = new Netty5ProtonBufferAllocator(BufferAllocator.onHeapPooled());
-
- public static ProtonBufferAllocator UNPOOLED = new Netty5ProtonBufferAllocator(BufferAllocator.onHeapUnpooled());
-
- private boolean closed;
-
- private final BufferAllocator allocator;
-
- public Netty5ProtonBufferAllocator(BufferAllocator allocator) {
- this.allocator = allocator;
- }
-
- public BufferAllocator allocator() {
- return allocator;
- }
-
- @Override
- public void close() {
- closed = true;
- }
-
- /**
- * Creates a {@link ProtonBuffer} wrapper around the given Netty 5 based
- * Buffer instance. The method wraps a Buffer and assumes ownership of it
- * which means that once the wrapper buffer is closed it will release the
- * {@link Buffer} which if there are no other references will render the
- * wrapped buffer closed and recyclable if pooled. Care should be take
- * when supplying the buffer to add a reference depending on the source of
- * the buffer.
- *
- * @param buffer
- * The buffer instance to wrap.
- *
- * @return A ProtonBuffer instance that wraps the given netty buffer.
- */
- public Netty5ToProtonBufferAdapter wrap(Buffer buffer) {
- checkClosed();
- return new Netty5ToProtonBufferAdapter(this, buffer);
- }
-
- @Override
- public Netty5ToProtonBufferAdapter outputBuffer(int initialCapacity) {
- return allocate(initialCapacity);
- }
-
- @Override
- public Netty5ToProtonBufferAdapter allocate() {
- return allocate(DEFAULT_CAPACITY);
- }
-
- @Override
- public Netty5ToProtonBufferAdapter allocate(int initialCapacity) {
- checkClosed();
- return new Netty5ToProtonBufferAdapter(this, allocator.allocate(initialCapacity));
- }
-
- @Override
- public Netty5ToProtonBufferAdapter allocateHeapBuffer() {
- return allocateHeapBuffer(DEFAULT_CAPACITY);
- }
-
- @Override
- public Netty5ToProtonBufferAdapter allocateHeapBuffer(int initialCapacity) {
- checkClosed();
- return new Netty5ToProtonBufferAdapter(this, BufferAllocator.onHeapUnpooled().allocate(initialCapacity));
- }
-
- @Override
- public Netty5ToProtonBufferAdapter copy(byte[] array) {
- checkClosed();
- return new Netty5ToProtonBufferAdapter(this, allocator.copyOf(array));
- }
-
- @Override
- public Netty5ToProtonBufferAdapter copy(byte[] array, int offset, int length) {
- checkClosed();
- return new Netty5ToProtonBufferAdapter(this, allocator.copyOf(ByteBuffer.wrap(array, offset, length)));
- }
-
- @Override
- public ProtonCompositeBuffer composite() {
- checkClosed();
- return ProtonCompositeBuffer.create(this);
- }
-
- @Override
- public ProtonCompositeBuffer composite(ProtonBuffer buffer) {
- checkClosed();
- return ProtonCompositeBuffer.create(this, buffer);
- }
-
- @Override
- public ProtonCompositeBuffer composite(ProtonBuffer[] buffers) {
- checkClosed();
- return ProtonCompositeBuffer.create(this, buffers);
- }
-
- private void checkClosed() {
- if (closed) {
- throw new IllegalStateException("This allocator instance is closed");
- }
- }
-}
-
diff --git a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ToProtonBufferAdapter.java b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ToProtonBufferAdapter.java
deleted file mode 100644
index 96dd8c990..000000000
--- a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/Netty5ToProtonBufferAdapter.java
+++ /dev/null
@@ -1,985 +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.buffer.netty;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.nio.charset.Charset;
-import java.util.NoSuchElementException;
-
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonBufferClosedException;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponent;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
-import org.apache.qpid.protonj2.buffer.ProtonBufferIterator;
-import org.apache.qpid.protonj2.buffer.ProtonBufferUtils;
-import org.apache.qpid.protonj2.resource.SharedResource;
-
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.BufferClosedException;
-import io.netty5.buffer.BufferComponent;
-import io.netty5.buffer.BufferReadOnlyException;
-import io.netty5.buffer.ByteCursor;
-import io.netty5.buffer.ComponentIterator;
-import io.netty5.buffer.ComponentIterator.Next;
-
-/**
- * Wrapper class for Netty 5 Buffer instances which provides a generic way
- * for proton to interact with Netty 4 buffers.
- */
-public final class Netty5ToProtonBufferAdapter extends SharedResource
- implements ProtonBuffer, ProtonBufferComponentAccessor, ProtonBufferComponent {
-
- private final Netty5ProtonBufferAllocator allocator;
-
- private static final Buffer CLOSED_BUFFER;
-
- static {
- CLOSED_BUFFER = BufferAllocator.onHeapUnpooled().allocate(0);
- CLOSED_BUFFER.close();
- }
-
- private Buffer resource;
- private BufferComponent resourceComponent;
-
- /**
- * Creates a new {@link Netty5ToProtonBufferAdapter} which wraps the given Netty {@link Buffer}.
- *
- * @param allocator
- * The allocator that created this buffer wrapper
- * @param resource
- * The {@link Buffer} resource to wrap.
- */
- public Netty5ToProtonBufferAdapter(Netty5ProtonBufferAllocator allocator, Buffer resource) {
- this.resource = resource;
- this.allocator = allocator;
-
- // To avoid allocation of component iterators we can check that the buffer
- // is a single component buffer and it implements the component interface as
- // Netty optimizes this case to also avoid allocations.
- if (resource.countComponents() == 1 && resource instanceof BufferComponent) {
- resourceComponent = (BufferComponent) resource;
- }
- }
-
- public Netty5ProtonBufferAllocator allocator() {
- return allocator;
- }
-
- /**
- * Unwraps the managed Netty {@link Buffer} and releases it from ownership by this
- * {@link ProtonBuffer} instance. This effectively closes the {@link ProtonBuffer}
- * while also safely handing off the managed Netty resource.
- *
- * @return the managed Netty {@link Buffer}
- */
- public Buffer unwrapAndRelease() {
- if (resource != CLOSED_BUFFER) {
- try {
- return resource;
- } finally {
- resource = CLOSED_BUFFER;
- }
- } else {
- throw new ProtonBufferClosedException("The buffer has already been closed or transferred");
- }
- }
-
- @Override
- public Buffer unwrap() {
- ProtonBufferUtils.checkIsClosed(this);
- return resource;
- }
-
- @Override
- public ProtonBuffer convertToReadOnly() {
- resource.makeReadOnly();
- return this;
- }
-
- @Override
- public boolean isReadOnly() {
- return resource.readOnly();
- }
-
- @Override
- public boolean isComposite() {
- return false;
- }
-
- @Override
- public int componentCount() {
- return resource.countComponents();
- }
-
- @Override
- public int readableComponentCount() {
- return resource.countReadableComponents();
- }
-
- @Override
- public int writableComponentCount() {
- return resource.countWritableComponents();
- }
-
- @Override
- public boolean isDirect() {
- return false; // Buffer components APIs need to allow access to native addresses
- }
-
- @Override
- public int implicitGrowthLimit() {
- return resource.implicitCapacityLimit();
- }
-
- @Override
- public ProtonBuffer implicitGrowthLimit(int limit) {
- resource.implicitCapacityLimit(limit);
- return this;
- }
-
- @Override
- public ProtonBuffer fill(byte value) {
- try {
- resource.fill(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public int capacity() {
- return resource.capacity();
- }
-
- @Override
- public int getReadOffset() {
- return resource.readerOffset();
- }
-
- @Override
- public ProtonBuffer setReadOffset(int value) {
- resource.readerOffset(value);
- return this;
- }
-
- @Override
- public int getWriteOffset() {
- return resource.writerOffset();
- }
-
- @Override
- public ProtonBuffer setWriteOffset(int value) {
- try {
- resource.writerOffset(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer compact() {
- try {
- resource.compact();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public void copyInto(int offset, byte[] destination, int destOffset, int length) {
- try {
- resource.copyInto(offset, destination, destOffset, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public void copyInto(int offset, ByteBuffer destination, int destOffset, int length) {
- try {
- resource.copyInto(offset, destination, destOffset, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public void copyInto(int offset, ProtonBuffer destination, int destOffset, int length) {
- try {
- if (destination.unwrap() instanceof Buffer) {
- resource.copyInto(offset, (Buffer) destination.unwrap(), destOffset, length);
- } else {
- ProtonBufferUtils.checkIsReadOnly(destination);
- ProtonBufferUtils.checkIsClosed(this);
-
- // Try to reduce bounds-checking by using larger primitives when possible.
- for (; length >= Long.BYTES; length -= Long.BYTES, offset += Long.BYTES, destOffset += Long.BYTES) {
- destination.setLong(destOffset, getLong(offset));
- }
- for (; length >= Integer.BYTES; length -= Integer.BYTES, offset += Integer.BYTES, destOffset += Integer.BYTES) {
- destination.setInt(destOffset, getInt(offset));
- }
- for (; length > 0; length--, offset++, destOffset++) {
- destination.setByte(destOffset, getByte(offset));
- }
- }
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public ProtonBuffer writeBytes(byte[] source, int offset, int length) {
- try {
- resource.writeBytes(source, offset, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
-
- return this;
- }
-
- @Override
- public ProtonBuffer writeBytes(ByteBuffer source) {
- try {
- resource.writeBytes(source);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
-
- return this;
- }
-
- @Override
- public ProtonBuffer ensureWritable(int size, int minimumGrowth, boolean allowCompaction) throws IndexOutOfBoundsException, IllegalArgumentException {
- try {
- resource.ensureWritable(size, minimumGrowth, allowCompaction);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
-
- return this;
- }
-
- @Override
- public ProtonBuffer copy(int index, int length, boolean readOnly) throws IllegalArgumentException {
- try {
- return allocator.wrap(resource.copy(index, length, readOnly));
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public ProtonBuffer split(int splitOffset) {
- try {
- return allocator.wrap(resource.split(splitOffset));
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- //----- JDK Overrides
-
- @Override
- public String toString(Charset charset) {
- return resource.toString(charset);
- }
-
- @Override
- public String toString() {
- return "Netty5ToProtonBufferAdapter" +
- "{ read:" + (resource != null ? resource.readerOffset() : null) +
- ", write: " + (resource != null ? resource.writerOffset() : 0) +
- ", capacity: " + (resource != null ? resource.capacity() : 0) + "}";
- }
-
- @Override
- public int compareTo(ProtonBuffer buffer) {
- return ProtonBufferUtils.compare(this, buffer);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ProtonBuffer) {
- return ProtonBufferUtils.equals(this, (ProtonBuffer) other);
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return ProtonBufferUtils.hashCode(this);
- }
-
- //----- Primitive Get API
-
- @Override
- public byte getByte(int index) {
- try {
- return resource.getByte(index);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public char getChar(int index) {
- try {
- return resource.getChar(index);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public short getShort(int index) {
- try {
- return resource.getShort(index);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public int getInt(int index) {
- try {
- return resource.getInt(index);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public long getLong(int index) {
- try {
- return resource.getLong(index);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- //----- Primitive Set API
-
- @Override
- public ProtonBuffer setByte(int index, byte value) {
- try {
- resource.setByte(index, value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer setChar(int index, char value) {
- try {
- resource.setChar(index, value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer setShort(int index, short value) {
- try {
- resource.setShort(index, value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer setInt(int index, int value) {
- try {
- resource.setInt(index, value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer setLong(int index, long value) {
- try {
- resource.setLong(index, value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- //----- Primitive Read API
-
- @Override
- public byte readByte() {
- try {
- return resource.readByte();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public char readChar() {
- try {
- return resource.readChar();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public short readShort() {
- try {
- return resource.readShort();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public int readInt() {
- try {
- return resource.readInt();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public long readLong() {
- try {
- return resource.readLong();
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- //----- Primitive Write API
-
- @Override
- public ProtonBuffer writeByte(byte value) {
- try {
- resource.writeByte(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer writeChar(char value) {
- try {
- resource.writeChar(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer writeShort(short value) {
- try {
- resource.writeShort(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer writeInt(int value) {
- try {
- resource.writeInt(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- @Override
- public ProtonBuffer writeLong(long value) {
- try {
- resource.writeLong(value);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- return this;
- }
-
- //----- IO Handlers
-
- @Override
- public int transferTo(WritableByteChannel channel, int length) throws IOException {
- try {
- return resource.transferTo(channel, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public int transferFrom(ReadableByteChannel channel, int length) throws IOException {
- try {
- return resource.transferFrom(channel, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- @Override
- public int transferFrom(FileChannel channel, long position, int length) throws IOException {
- try {
- return resource.transferFrom(channel, position, length);
- } catch (RuntimeException e) {
- throw translateToProtonException(e);
- }
- }
-
- //----- Buff component access
-
- @Override
- public ProtonBufferComponentAccessor componentAccessor() {
- if (isClosed()) {
- throw ProtonBufferUtils.genericBufferIsClosed(this);
- }
-
- if (resourceComponent != null) {
- return (ProtonBufferComponentAccessor) acquire();
- } else {
- return new ProtonNetty5BufferComponentAccessor((Netty5ToProtonBufferAdapter) acquire(), resource.forEachComponent());
- }
- }
-
- @Override
- public ProtonBufferComponent first() {
- return this;
- }
-
- @Override
- public ProtonBufferComponent next() {
- return null;
- }
-
- //----- Buffer Component API that works only when there is one component in the netty buffer
-
- @Override
- public int getReadableBytes() {
- return resourceComponent.readableBytes();
- }
-
- @Override
- public boolean hasReadbleArray() {
- return resourceComponent.hasReadableArray();
- }
-
- @Override
- public Netty5ToProtonBufferAdapter advanceReadOffset(int amount) {
- return (Netty5ToProtonBufferAdapter) ProtonBuffer.super.advanceReadOffset(amount);
- }
-
- @Override
- public byte[] getReadableArray() {
- return resourceComponent.readableArray();
- }
-
- @Override
- public int getReadableArrayOffset() {
- return resourceComponent.readableArrayOffset();
- }
-
- @Override
- public int getReadableArrayLength() {
- return resourceComponent.readableArrayLength();
- }
-
- @Override
- public ByteBuffer getReadableBuffer() {
- return resourceComponent.readableBuffer();
- }
-
- @Override
- public int getWritableBytes() {
- return resourceComponent.writableBytes();
- }
-
- @Override
- public Netty5ToProtonBufferAdapter advanceWriteOffset(int amount) {
- return (Netty5ToProtonBufferAdapter) ProtonBuffer.super.advanceWriteOffset(amount);
- }
-
- @Override
- public boolean hasWritableArray() {
- return resourceComponent.hasWritableArray();
- }
-
- @Override
- public byte[] getWritableArray() {
- return resourceComponent.writableArray();
- }
-
- @Override
- public int getWritableArrayOffset() {
- return resourceComponent.writableArrayOffset();
- }
-
- @Override
- public int getWritableArrayLength() {
- return resourceComponent.writableArrayLength();
- }
-
- @Override
- public ByteBuffer getWritableBuffer() {
- return resourceComponent.writableBuffer();
- }
-
- @Override
- public long getNativeAddress() {
- return resourceComponent.baseNativeAddress();
- }
-
- @Override
- public long getNativeReadAddress() {
- return resourceComponent.readableNativeAddress();
- }
-
- @Override
- public long getNativeWriteAddress() {
- return resourceComponent.writableNativeAddress();
- }
-
- //----- Buffer Iteration API
-
- @Override
- public ProtonBufferIterator bufferIterator() {
- return bufferIterator(getReadOffset(), getReadableBytes());
- }
-
- @Override
- public ProtonBufferIterator bufferIterator(int offset, int length) {
- ProtonBufferUtils.checkIsClosed(this);
- ProtonBufferUtils.checkIsNotNegative(length, "length");
- ProtonBufferUtils.checkIsNotNegative(offset, "length");
-
- if (offset + length > resource.capacity()) {
- throw new IndexOutOfBoundsException(
- "The iterator cannot read beyond the bounds of the buffer: offset=" + offset + ", length=" + length);
- }
-
- return new Netty5ToProtonBufferReverseIterator(resource.openCursor(offset, length));
- }
-
- @Override
- public ProtonBufferIterator bufferReverseIterator(int offset, int length) {
- ProtonBufferUtils.checkIsClosed(this);
- ProtonBufferUtils.checkIsNotNegative(length, "length");
- ProtonBufferUtils.checkIsNotNegative(offset, "length");
-
- if (offset >= capacity()) {
- throw new IndexOutOfBoundsException(
- "Read offset must be within the bounds of the buffer: offset = " + offset + ", capacity = " + capacity());
- }
-
- if (offset - length < -1) {
- throw new IndexOutOfBoundsException(
- "Cannot read past start of buffer: offset = " + offset + ", length = " + length);
- }
-
- return new Netty5ToProtonBufferReverseIterator(resource.openReverseCursor(offset, length));
- }
-
- private static final class Netty5ToProtonBufferReverseIterator implements ProtonBufferIterator {
-
- private final ByteCursor cursor;
-
- public Netty5ToProtonBufferReverseIterator(ByteCursor cursor) {
- this.cursor = cursor;
- }
-
- @Override
- public boolean hasNext() {
- return cursor.bytesLeft() > 0;
- }
-
- @Override
- public byte next() {
- if (!cursor.readByte()) {
- throw new NoSuchElementException("Cannot read outside the iterator bounds");
- }
-
- return cursor.getByte();
- }
-
- @Override
- public int remaining() {
- return cursor.bytesLeft();
- }
-
- @Override
- public int offset() {
- return cursor.currentOffset();
- }
- }
-
- //----- Buffer search API
-
- @Override
- public int indexOf(byte needle, int offset, int length) {
- ProtonBufferUtils.checkIsClosed(this);
-
- if (offset < getReadOffset() || getWriteOffset() < offset + length) {
- throw new IndexOutOfBoundsException("Cannot search past the readable bounds of this buffer");
- }
-
- final int count = resource.bytesBefore(needle);
- if (count < 0) {
- return count;
- }
-
- final int indexOf = offset + count;
-
- if (offset > indexOf || offset + length < indexOf) {
- return -1;
- }
-
- return indexOf;
- }
-
- //----- Shared resource API
-
- @Override
- protected void releaseResourceOwnership() {
- if (resource != null && resource.isAccessible()) {
- resource.close();
- resource = CLOSED_BUFFER;
- }
- }
-
- @Override
- protected ProtonBuffer transferTheResource() {
- final Buffer transferred = resource;
- resource = CLOSED_BUFFER;
-
- return new Netty5ToProtonBufferAdapter(allocator, transferred);
- }
-
- @Override
- protected RuntimeException resourceIsClosedException() {
- return ProtonBufferUtils.genericBufferIsClosed(this);
- }
-
- //----- Support API for the buffer wrapper
-
- private RuntimeException translateToProtonException(RuntimeException e) {
- RuntimeException result = e;
-
- if (e instanceof BufferReadOnlyException) {
- result = ProtonBufferUtils.genericBufferIsReadOnly(this);
- result.addSuppressed(e);
- } else if (e instanceof BufferClosedException) {
- result = ProtonBufferUtils.genericBufferIsClosed(this);
- result.addSuppressed(e);
- }
-
- return result;
- }
-
- @SuppressWarnings("rawtypes")
- private static final class ProtonNetty5BufferComponentAccessor implements ProtonBufferComponentAccessor, ProtonBufferComponent {
-
- private final Netty5ToProtonBufferAdapter adapter;
-
- private final ComponentIterator resourceIterator;
-
- private Next current;
- private BufferComponent currentComponent;
-
- public ProtonNetty5BufferComponentAccessor(Netty5ToProtonBufferAdapter adapter, ComponentIterator iterator) {
- this.adapter = adapter;
- this.resourceIterator = iterator;
- }
-
- @Override
- public void close() {
- current = null;
- currentComponent = null;
-
- resourceIterator.close();
- adapter.close();
- }
-
- @Override
- public ProtonBufferComponent first() {
- current = resourceIterator.first();
- currentComponent = (BufferComponent) current;
-
- return this;
- }
-
- @Override
- public ProtonBufferComponent next() {
- if (current != null) {
- current = current.next();
- currentComponent = (BufferComponent) current;
- }
-
- return current != null ? this : null;
- }
-
- @Override
- public Object unwrap() {
- return adapter.resource;
- }
-
- @Override
- public int getReadableBytes() {
- return currentComponent.readableBytes();
- }
-
- @Override
- public boolean hasReadbleArray() {
- return currentComponent.hasReadableArray();
- }
-
- @Override
- public ProtonBufferComponent advanceReadOffset(int amount) {
- currentComponent.skipReadableBytes(amount);
- return this;
- }
-
- @Override
- public byte[] getReadableArray() {
- return currentComponent.readableArray();
- }
-
- @Override
- public int getReadableArrayOffset() {
- return currentComponent.readableArrayOffset();
- }
-
- @Override
- public int getReadableArrayLength() {
- return currentComponent.readableArrayLength();
- }
-
- @Override
- public ByteBuffer getReadableBuffer() {
- return currentComponent.readableBuffer();
- }
-
- @Override
- public int getWritableBytes() {
- return currentComponent.writableBytes();
- }
-
- @Override
- public ProtonBufferComponent advanceWriteOffset(int amount) {
- currentComponent.skipWritableBytes(amount);
- return this;
- }
-
- @Override
- public boolean hasWritableArray() {
- return currentComponent.hasWritableArray();
- }
-
- @Override
- public byte[] getWritableArray() {
- return currentComponent.writableArray();
- }
-
- @Override
- public int getWritableArrayOffset() {
- return currentComponent.writableArrayOffset();
- }
-
- @Override
- public int getWritableArrayLength() {
- return currentComponent.writableArrayLength();
- }
-
- @Override
- public ByteBuffer getWritableBuffer() {
- return currentComponent.writableBuffer();
- }
-
- @Override
- public long getNativeAddress() {
- return currentComponent.baseNativeAddress();
- }
-
- @Override
- public long getNativeReadAddress() {
- return currentComponent.readableNativeAddress();
- }
-
- @Override
- public long getNativeWriteAddress() {
- return currentComponent.writableNativeAddress();
- }
-
- @Override
- public ProtonBufferIterator bufferIterator() {
- return new Netty5ToProtonBufferIterator(currentComponent.openCursor());
- }
-
- private final class Netty5ToProtonBufferIterator implements ProtonBufferIterator {
-
- private final ByteCursor cursor;
-
- public Netty5ToProtonBufferIterator(ByteCursor cursor) {
- this.cursor = cursor;
- }
-
- @Override
- public boolean hasNext() {
- return cursor.bytesLeft() > 0;
- }
-
- @Override
- public byte next() {
- if (cursor.readByte()) {
- throw new NoSuchElementException("Cannot read outside the iterator bounds");
- }
-
- return cursor.getByte();
- }
-
- @Override
- public int remaining() {
- return cursor.bytesLeft();
- }
-
- @Override
- public int offset() {
- return cursor.currentOffset();
- }
- }
- }
-}
diff --git a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5Adapter.java b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5Adapter.java
deleted file mode 100644
index 2125e7a3e..000000000
--- a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5Adapter.java
+++ /dev/null
@@ -1,1107 +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.buffer.netty;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.nio.charset.Charset;
-
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonBufferClosedException;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponent;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
-import org.apache.qpid.protonj2.buffer.ProtonBufferIterator;
-import org.apache.qpid.protonj2.buffer.ProtonBufferReadOnlyException;
-
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferClosedException;
-import io.netty5.buffer.BufferComponent;
-import io.netty5.buffer.BufferReadOnlyException;
-import io.netty5.buffer.ByteCursor;
-import io.netty5.buffer.ComponentIterator;
-import io.netty5.buffer.ComponentIterator.Next;
-import io.netty5.buffer.internal.InternalBufferUtils;
-import io.netty5.util.Send;
-
-/**
- * Adapts a {@link ProtonBuffer} instance to a Netty 5 {@link Buffer}
- */
-public class ProtonBufferToNetty5Adapter implements Buffer {
-
- private ProtonBuffer resource;
-
- public ProtonBufferToNetty5Adapter(ProtonBuffer resource) {
- this.resource = resource;
- }
-
- @Override
- public void close() {
- resource.close();
- }
-
- @Override
- public Send send() {
- try {
- final ProtonBuffer transferred = resource.transfer();
-
- return new Send() {
-
- @Override
- public Buffer receive() {
- return new ProtonBufferToNetty5Adapter(transferred);
- }
-
- @Override
- public void close() {
- transferred.close();
- }
-
- @Override
- public boolean referentIsInstanceOf(Class> cls) {
- return cls.isAssignableFrom(ProtonBufferToNetty5Adapter.class);
- }
- };
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public boolean isAccessible() {
- return !resource.isClosed();
- }
-
- @Override
- public Buffer compact() {
- try {
- resource.compact();
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public Buffer makeReadOnly() {
- try {
- resource.convertToReadOnly();
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public boolean readOnly() {
- return resource.isReadOnly();
- }
-
- @Override
- public Buffer fill(byte value) {
- try {
- resource.fill(value);
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public boolean isDirect() {
- return false; // NOTE: resource.isDirect(); is only reasonable if we also expose the native address
- }
-
- @Override
- public int capacity() {
- return resource.capacity();
- }
-
- @Override
- public Buffer implicitCapacityLimit(int limit) {
- try {
- resource.implicitGrowthLimit(limit);
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int implicitCapacityLimit() {
- return resource.implicitGrowthLimit();
- }
-
- @Override
- public int readerOffset() {
- return resource.getReadOffset();
- }
-
- @Override
- public Buffer readerOffset(int offset) {
- try {
- resource.setReadOffset(offset);
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int writerOffset() {
- return resource.getWriteOffset();
- }
-
- @Override
- public Buffer writerOffset(int offset) {
- try {
- resource.setWriteOffset(offset);
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public Buffer ensureWritable(int size, int minimumGrowth, boolean allowCompaction) {
- try {
- resource.ensureWritable(size, minimumGrowth, allowCompaction);
- return this;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public void copyInto(int srcPos, byte[] dest, int destPos, int length) {
- try {
- resource.copyInto(srcPos, dest, destPos, length);
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public void copyInto(int srcPos, ByteBuffer dest, int destPos, int length) {
- try {
- resource.copyInto(srcPos, dest, destPos, length);
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public void copyInto(int srcPos, Buffer destination, int destPos, int length) {
- if (!destination.isAccessible()) {
- throw new BufferClosedException("Destination buffer is closed");
- }
- if (destination.readOnly()) {
- throw new BufferReadOnlyException("Destination buffer is read only");
- }
-
- checkCopyIntoArgs(srcPos, length, destPos, destination.capacity());
-
- try {
- // Try to reduce bounds-checking by using larger primitives when possible.
- for (; length >= Long.BYTES; length -= Long.BYTES, srcPos += Long.BYTES, destPos += Long.BYTES) {
- destination.setLong(destPos, getLong(srcPos));
- }
- for (; length >= Integer.BYTES; length -= Integer.BYTES, srcPos += Integer.BYTES, destPos += Integer.BYTES) {
- destination.setInt(destPos, getInt(srcPos));
- }
- for (; length > 0; length--, srcPos++, destPos++) {
- destination.setByte(destPos, getByte(srcPos));
- }
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public Buffer copy(int offset, int length, boolean readOnly) {
- try {
- return new ProtonBufferToNetty5Adapter(resource.copy(offset, length));
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public Buffer split(int splitOffset) {
- try {
- return new ProtonBufferToNetty5Adapter(resource.split(splitOffset));
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int bytesBefore(byte needle) {
- try {
- final int indexOf = resource.indexOf(needle);
- if (indexOf >= 0) {
- return indexOf - resource.getReadOffset();
- }
-
- return -1;
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int bytesBefore(Buffer needle) {
- return InternalBufferUtils.bytesBefore(this, null, needle, null);
- }
-
- //----- Buffer input and output APIs
-
- @Override
- public int transferTo(WritableByteChannel channel, int length) throws IOException {
- try {
- return resource.transferTo(channel, length);
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int transferFrom(FileChannel channel, long position, int length) throws IOException {
- try {
- return resource.transferFrom(channel, position, length);
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public int transferFrom(ReadableByteChannel channel, int length) throws IOException {
- try {
- return resource.transferFrom(channel, length);
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- //----- Buffer cursors API
-
- @Override
- public ByteCursor openCursor() {
- return openCursor(readerOffset(), readableBytes());
- }
-
- @Override
- public ByteCursor openCursor(int fromOffset, int length) {
- try {
- return new ProtonBufferToNetty5ByteCursor(resource.bufferIterator(fromOffset, length));
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- @Override
- public ByteCursor openReverseCursor(int fromOffset, int length) {
- try {
- return new ProtonBufferToNetty5ByteCursor(resource.bufferReverseIterator(fromOffset, length));
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- private final class ProtonBufferToNetty5ByteCursor implements ByteCursor {
-
- private final ProtonBufferIterator iterator;
-
- private byte lastReadByte = -1;
-
- public ProtonBufferToNetty5ByteCursor(ProtonBufferIterator iterator) {
- this.iterator = iterator;
- }
-
- @Override
- public boolean readByte() {
- if (iterator.hasNext()) {
- lastReadByte = iterator.next();
- return true;
- }
-
- return false;
- }
-
- @Override
- public byte getByte() {
- return lastReadByte;
- }
-
- @Override
- public int currentOffset() {
- return iterator.offset();
- }
-
- @Override
- public int bytesLeft() {
- return iterator.remaining();
- }
- }
-
- //----- Buffer components API
-
- @Override
- public int countComponents() {
- return resource.componentCount();
- }
-
- @Override
- public int countReadableComponents() {
- return resource.readableComponentCount();
- }
-
- @Override
- public int countWritableComponents() {
- return resource.writableComponentCount();
- }
-
- @Override
- public ComponentIterator forEachComponent() {
- try {
- return new ProtonBufferComponentIterator<>(resource.componentAccessor());
- } catch (RuntimeException e) {
- throw translateToNettyException(e);
- }
- }
-
- //----- Primitive indexed set API
-
- @Override
- public Buffer setByte(int woff, byte value) {
- try {
- resource.setByte(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setUnsignedByte(int woff, int value) {
- try {
- resource.setByte(woff, (byte)(value & 0xFF));
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setChar(int woff, char value) {
- try {
- resource.setChar(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setShort(int woff, short value) {
- try {
- resource.setShort(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setUnsignedShort(int woff, int value) {
- try {
- resource.setUnsignedShort(woff, (short)(value & 0x0000FFFF));
- return null;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setMedium(int woff, int value) {
- try {
- resource.setByte(woff, (byte) (value >>> 16));
- resource.setByte(woff + 1, (byte) (value >>> 8));
- resource.setByte(woff + 2, (byte) (value >>> 0));
-
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setUnsignedMedium(int woff, int value) {
- try {
- resource.setByte(woff, (byte) (value >>> 16));
- resource.setByte(woff + 1, (byte) (value >>> 8));
- resource.setByte(woff + 2, (byte) (value >>> 0));
-
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setInt(int woff, int value) {
- try {
- resource.setInt(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setUnsignedInt(int woff, long value) {
- try {
- resource.setUnsignedInt(woff, (int)(value & 0x00000000FFFFFFFFl));
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setLong(int woff, long value) {
- try {
- resource.setLong(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setFloat(int woff, float value) {
- try {
- resource.setFloat(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer setDouble(int woff, double value) {
- try {
- resource.setDouble(woff, value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- //----- Primitive relative write API
-
- @Override
- public Buffer writeByte(byte value) {
- try {
- resource.writeByte(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeUnsignedByte(int value) {
- try {
- resource.writeByte((byte) (value & 0xFF));
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeShort(short value) {
- try {
- resource.writeShort(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeUnsignedShort(int value) {
- try {
- resource.writeShort((short) (value & 0x00FF));
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeChar(char value) {
- try {
- resource.writeChar(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeMedium(int value) {
- try {
- resource.writeByte((byte) (value >>> 16));
- resource.writeByte((byte) (value >>> 8));
- resource.writeByte((byte) (value >>> 0));
-
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeUnsignedMedium(int value) {
- try {
- resource.writeByte((byte) (value >>> 16));
- resource.writeByte((byte) (value >>> 8));
- resource.writeByte((byte) (value >>> 0));
-
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeInt(int value) {
- try {
- resource.writeInt(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeUnsignedInt(long value) {
- try {
- resource.writeInt((int)(value & 0x00000000FFFFFFFFl));
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeLong(long value) {
- try {
- resource.writeLong(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeFloat(float value) {
- try {
- resource.writeFloat(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeDouble(double value) {
- try {
- resource.writeDouble(value);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public Buffer writeCharSequence(CharSequence source, Charset charset) {
- try {
- resource.writeCharSequence(source, charset);
- return this;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- //----- Primitive indexed get API
-
- @Override
- public byte getByte(int index) {
- try {
- return resource.getByte(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public char getChar(int index) {
- try {
- return resource.getChar(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int getUnsignedByte(int index) {
- try {
- return resource.getUnsignedByte(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int getUnsignedShort(int index) {
- try {
- return resource.getUnsignedShort(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public short getShort(int index) {
- try {
- return resource.getShort(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int getMedium(int index) {
- try {
- return (getByte(index)) << 16 |
- (getByte(index + 1) & 0xFF) << 8 |
- (getByte(index + 2) & 0xFF) << 0;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int getUnsignedMedium(int index) {
- try {
- return ((getByte(index)) << 16 |
- (getByte(index + 1) & 0xFF) << 8 |
- (getByte(index + 2) & 0xFF) << 0) & 0xFFFFFF;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int getInt(int index) {
- try {
- return resource.getInt(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public long getUnsignedInt(int index) {
- try {
- return resource.getUnsignedInt(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public long getLong(int index) {
- try {
- return resource.getLong(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public float getFloat(int index) {
- try {
- return resource.getFloat(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public double getDouble(int index) {
- try {
- return resource.getDouble(index);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- //----- Primitive relative read API
-
- @Override
- public byte readByte() {
- try {
- return resource.readByte();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int readUnsignedByte() {
- try {
- return resource.readUnsignedByte();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public char readChar() {
- try {
- return resource.readChar();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public short readShort() {
- try {
- return resource.readShort();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int readUnsignedShort() {
- try {
- return readShort() & 0x0000FFFF;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int readMedium() {
- try {
- return readByte() << 16 |
- (readByte() & 0xFF) << 8 |
- (readByte() & 0xFF) << 0;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int readUnsignedMedium() {
- try {
- return ((readByte()) << 16 |
- (readByte() & 0xFF) << 8 |
- (readByte() & 0xFF) << 0) & 0xFFFFFF;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public int readInt() {
- try {
- return resource.readInt();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public long readUnsignedInt() {
- try {
- return readInt() & 0x00000000FFFFFFFFl;
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public long readLong() {
- try {
- return resource.readLong();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public float readFloat() {
- try {
- return resource.readFloat();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public double readDouble() {
- try {
- return resource.readDouble();
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- @Override
- public CharSequence readCharSequence(int length, Charset charset) {
- try {
- return resource.readCharSequence(length, charset);
- } catch (RuntimeException ex) {
- throw translateToNettyException(ex);
- }
- }
-
- //----- Object API overrides
-
- @Override
- public boolean equals(Object o) {
- return o instanceof Buffer && InternalBufferUtils.equals(this, (Buffer) o);
- }
-
- @Override
- public int hashCode() {
- return InternalBufferUtils.hashCode(this);
- }
-
- //----- Internal API for validation of arguments
-
- private void checkCopyIntoArgs(int srcPos, int length, int destPos, int destLength) {
- if (resource.isClosed()) {
- throw new BufferClosedException("The wrapped ProtonBuffer is closed");
- }
- if (srcPos < 0) {
- throw new IndexOutOfBoundsException("The srcPos cannot be negative: " + srcPos + '.');
- }
- if (length < 0) {
- throw new IndexOutOfBoundsException("The length value cannot be negative " + length + ".");
- }
- if (resource.capacity() < srcPos + length) {
- throw new IndexOutOfBoundsException("The srcPos + length is beyond the end of the buffer: " +
- "srcPos = " + srcPos + ", length = " + length + '.');
- }
- if (destPos < 0) {
- throw new IndexOutOfBoundsException("The destPos cannot be negative: " + destPos + '.');
- }
- if (destLength < destPos + length) {
- throw new IndexOutOfBoundsException("The destPos + length is beyond the end of the destination: " +
- "destPos = " + destPos + ", length = " + length + '.');
- }
- }
-
- private RuntimeException translateToNettyException(RuntimeException e) {
- RuntimeException result = e;
-
- if (e instanceof ProtonBufferReadOnlyException) {
- result = new BufferReadOnlyException("Buffer is read-only");
- result.addSuppressed(e);
- } else if (e instanceof ProtonBufferClosedException) {
- result = new BufferClosedException("Buffer is closed");
- result.addSuppressed(e);
- }
-
- return result;
- }
-
- //----- Wrappers needed to adapt to the Netty 5 BufferCompoent and ComponentIterator API
-
- private static class ProtonBufferComponentIterator implements Next, BufferComponent, ComponentIterator {
-
- private ProtonBufferComponentAccessor accessor;
-
- private ProtonBufferComponent current;
-
- public ProtonBufferComponentIterator(ProtonBufferComponentAccessor accessor) {
- this.accessor = accessor;
- }
-
- @Override
- public void close() {
- current = null;
-
- accessor.close();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public T first() {
- return (current = accessor.first()) != null ? (T) this : null;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public T next() {
- if (current != null) {
- current = accessor.next();
- }
-
- return current != null ? (T) this : null;
- }
-
- @Override
- public boolean hasReadableArray() {
- return current.hasReadbleArray();
- }
-
- @Override
- public boolean hasWritableArray() {
- return current.hasWritableArray();
- }
-
- @Override
- public byte[] readableArray() {
- return current.getReadableArray();
- }
-
- @Override
- public byte[] writableArray() {
- return current.getWritableArray();
- }
-
- @Override
- public int readableArrayOffset() {
- return current.getReadableArrayOffset();
- }
-
- @Override
- public int writableArrayOffset() {
- return current.getWritableArrayOffset();
- }
-
- @Override
- public int readableArrayLength() {
- return current.getReadableArrayLength();
- }
-
- @Override
- public int writableArrayLength() {
- return current.getWritableArrayLength();
- }
-
- @Override
- public long baseNativeAddress() {
- return current.getNativeAddress();
- }
-
- @Override
- public long readableNativeAddress() {
- return current.getNativeReadAddress();
- }
-
- @Override
- public long writableNativeAddress() {
- return current.getNativeWriteAddress();
- }
-
- @Override
- public ByteBuffer readableBuffer() {
- return current.getReadableBuffer();
- }
-
- @Override
- public ByteBuffer writableBuffer() {
- return current.getWritableBuffer();
- }
-
- @Override
- public int readableBytes() {
- return current.getReadableBytes();
- }
-
- @Override
- public int writableBytes() {
- return current.getWritableBytes();
- }
-
- @Override
- public ByteCursor openCursor() {
- return new ProtonByteCursorAdapter(current.bufferIterator());
- }
-
- @Override
- public BufferComponent skipReadableBytes(int byteCount) {
- current.advanceReadOffset(byteCount);
- return this;
- }
-
- @Override
- public BufferComponent skipWritableBytes(int byteCount) {
- current.advanceWriteOffset(byteCount);
- return this;
- }
- }
-
- private final static class ProtonByteCursorAdapter implements ByteCursor {
-
- private final ProtonBufferIterator iterator;
-
- private byte lastByte = -1;
-
- public ProtonByteCursorAdapter(ProtonBufferIterator iterator) {
- this.iterator = iterator;
- }
-
- @Override
- public boolean readByte() {
- if (iterator.hasNext()) {
- lastByte = iterator.next();
- return true;
- }
-
- return false;
- }
-
- @Override
- public byte getByte() {
- return lastByte;
- }
-
- @Override
- public int currentOffset() {
- return iterator.offset();
- }
-
- @Override
- public int bytesLeft() {
- return iterator.remaining();
- }
- }
-}
diff --git a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/ProtonAbstractBufferTest.java b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/ProtonAbstractBufferTest.java
index c390123ea..fc1c7f9b5 100644
--- a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/ProtonAbstractBufferTest.java
+++ b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/ProtonAbstractBufferTest.java
@@ -475,7 +475,6 @@ public void testWriteBytesHeapByteBufferMustExpandCapacityIfBufferIsTooSmall() {
}
}
- @SuppressWarnings("resource")
@Test
public void testWriteBytesHeapByteBufferMustThrowIfCannotBeExpanded() {
// With zero offsets
@@ -530,7 +529,6 @@ public void testWiteBytesDirectByteBufferMustExpandCapacityIfBufferIsTooSmall()
}
}
- @SuppressWarnings("resource")
@Test
public void testWriteBytesDirectByteBufferMustThrowIfCannotBeExpanded() {
// With zero offsets
@@ -583,7 +581,6 @@ public void testWriteBytesByteArrayMustExpandCapacityIfTooSmall() {
}
}
- @SuppressWarnings("resource")
@Test
public void testWriteBytesByteArrayMustThrowIfCannotBeExpanded() {
// Starting at offsets zero.
@@ -634,7 +631,6 @@ public void testWriteBytesByteArrayWithOffsetMustExpandCapacityIfTooSmall() {
}
}
- @SuppressWarnings("resource")
@Test
public void testWriteBytesByteArrayWithOffsetMustThrowIfCannotBeExpanded() {
// Starting at offsets zero.
@@ -687,7 +683,6 @@ public void testWriteBytesBufferMustExpandCapacityIfTooSmall() {
}
}
- @SuppressWarnings("resource")
@Test
public void testWriteBytesBufferMustThrowIfCannotBeExpanded() {
// Starting at offsets zero.
@@ -2068,7 +2063,6 @@ public void testSplitDoesNotReduceImplicitCapacityLimit() {
}
}
- @SuppressWarnings("resource")
@Test
public void testEnsureWritableCanGrowBeyondImplicitCapacityLimit() {
try (ProtonBufferAllocator allocator = createTestCaseAllocator(); ProtonBuffer buf = allocator.allocate(8).implicitGrowthLimit(8)) {
@@ -2084,7 +2078,6 @@ public void testEnsureWritableCanGrowBeyondImplicitCapacityLimit() {
}
}
- @SuppressWarnings("resource")
@Test
public void testWritesMustThrowIfSizeWouldGoBeyondImplicitCapacityLimit() {
try (ProtonBufferAllocator allocator = createTestCaseAllocator()) {
@@ -2545,7 +2538,6 @@ public void testSplitOfReadOnlyBufferMustBeReadOnly() {
}
}
- @SuppressWarnings("resource")
@Test
public void testAllocatingOnClosedAllocatorMustThrow() {
ProtonBufferAllocator allocator = createTestCaseAllocator();
@@ -3018,7 +3010,6 @@ public void testCopyIntoByteBufferOnEmptyBufferFromFullyReadBuffer() {
}
}
- @SuppressWarnings("resource")
@Test
public void testReadOnlyBuffersCannotChangeWriteOffset() {
try (ProtonBufferAllocator allocator = createTestCaseAllocator();
@@ -4934,7 +4925,6 @@ public void testCompositeBufferComponentCountsUpdateWithChangeAfterFlattening()
}
}
- @SuppressWarnings("resource")
@Test
public void testIteratingComponentOnClosedBufferMustThrow() {
try (ProtonBufferAllocator allocator = createTestCaseAllocator()) {
@@ -5558,7 +5548,6 @@ public void testIndexOfByteOnEmptyBufferReturnsNoResult() {
}
}
- @SuppressWarnings("resource")
protected static void verifyInaccessible(ProtonBuffer buf) {
verifyReadInaccessible(buf);
diff --git a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/impl/ProtonCompositeBufferImplTest.java b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/impl/ProtonCompositeBufferImplTest.java
index ad1138359..024226fe5 100644
--- a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/impl/ProtonCompositeBufferImplTest.java
+++ b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/impl/ProtonCompositeBufferImplTest.java
@@ -39,11 +39,11 @@
import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
import org.apache.qpid.protonj2.buffer.ProtonBufferReadOnlyException;
import org.apache.qpid.protonj2.buffer.ProtonCompositeBuffer;
-import org.apache.qpid.protonj2.buffer.netty.Netty5ProtonBufferAllocator;
+import org.apache.qpid.protonj2.buffer.netty.Netty4ProtonBufferAllocator;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import io.netty5.buffer.BufferAllocator;
+import io.netty.buffer.PooledByteBufAllocator;
/**
* Tests for the proton composite buffer implementation.
@@ -598,7 +598,7 @@ public void testAppendingToNonOwnedCompositeBufferMustThrow() {
}
@SuppressWarnings("resource")
- @Test
+ @Test
public void testAppendingCompositeBufferToItselfMustThrow() {
try (ProtonBufferAllocator allocator = createProtonDefaultAllocator()) {
ProtonCompositeBuffer composite;
@@ -1932,7 +1932,7 @@ public void testSplitCompositeOfManyBuffersInsideOFMiddleSegment() {
@Test
public void testBufferExposesNativeAddressValues() {
- try (ProtonBufferAllocator allocator = new Netty5ProtonBufferAllocator(BufferAllocator.offHeapUnpooled());
+ try (ProtonBufferAllocator allocator = new Netty4ProtonBufferAllocator(PooledByteBufAllocator.DEFAULT);
ProtonBuffer buffer = allocator.allocate(16)) {
buffer.writeLong(Long.MAX_VALUE);
@@ -1950,7 +1950,7 @@ public void testBufferExposesNativeAddressValues() {
@Test
public void testBufferExposesNativeAddressValuesForNativeBackedBuffers() {
- try (ProtonBufferAllocator offHeapAllocator = new Netty5ProtonBufferAllocator(BufferAllocator.offHeapUnpooled());
+ try (ProtonBufferAllocator offHeapAllocator = new Netty4ProtonBufferAllocator(PooledByteBufAllocator.DEFAULT);
ProtonBufferAllocator onHeapAllocator = createProtonDefaultAllocator();
ProtonCompositeBuffer buffer = onHeapAllocator.composite()) {
diff --git a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAdapterTest.java b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAdapterTest.java
deleted file mode 100644
index 3d94ce1a4..000000000
--- a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/Netty5ProtonBufferAdapterTest.java
+++ /dev/null
@@ -1,72 +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.buffer.netty;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponent;
-import org.apache.qpid.protonj2.buffer.ProtonBufferComponentAccessor;
-import org.junit.jupiter.api.Test;
-
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-
-/**
- * Test the Netty 5 to {@link ProtonBuffer} adapter
- */
-public class Netty5ProtonBufferAdapterTest extends NettyBufferAdapterTestBase {
-
- @Override
- public ProtonBufferAllocator createTestCaseAllocator() {
- return new Netty5ProtonBufferAllocator(BufferAllocator.onHeapUnpooled());
- }
-
- @Test
- public void testBufferExposesNativeAddressValues() {
- try (ProtonBufferAllocator netty = new Netty5ProtonBufferAllocator(BufferAllocator.offHeapUnpooled());
- ProtonBuffer nettyBuffer = netty.allocate(16)) {
-
- nettyBuffer.writeLong(Long.MAX_VALUE);
- nettyBuffer.readByte();
-
- try (ProtonBufferComponentAccessor accessor = nettyBuffer.componentAccessor()) {
- for (ProtonBufferComponent component : accessor.components()) {
- assertTrue(component.getNativeAddress() != 0);
- assertTrue(component.getNativeReadAddress() != 0);
- assertTrue(component.getNativeWriteAddress() != 0);
- }
- }
- }
- }
-
- @Test
- public void testBufferCloseReleasesBuffer() {
- try (ProtonBufferAllocator netty = createTestCaseAllocator();
- ProtonBuffer nettyBuffer = netty.allocate(16)) {
-
- Buffer buffer = (Buffer) nettyBuffer.unwrap();
-
- assertTrue(buffer.isAccessible());
- nettyBuffer.close();
- assertFalse(buffer.isAccessible());
- }
- }
-}
diff --git a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5AdapterTest.java b/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5AdapterTest.java
deleted file mode 100644
index 4a957bea1..000000000
--- a/protonj2/src/test/java/org/apache/qpid/protonj2/buffer/netty/ProtonBufferToNetty5AdapterTest.java
+++ /dev/null
@@ -1,1596 +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.buffer.netty;
-
-import static java.nio.ByteOrder.BIG_ENDIAN;
-import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE;
-import static java.nio.file.StandardOpenOption.READ;
-import static java.nio.file.StandardOpenOption.WRITE;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.qpid.protonj2.buffer.ProtonBuffer;
-import org.apache.qpid.protonj2.buffer.ProtonBufferAllocator;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.io.TempDir;
-
-import io.netty5.buffer.Buffer;
-import io.netty5.buffer.BufferAllocator;
-import io.netty5.buffer.BufferClosedException;
-import io.netty5.buffer.BufferReadOnlyException;
-import io.netty5.buffer.ByteCursor;
-import io.netty5.buffer.CompositeBuffer;
-import io.netty5.buffer.internal.InternalBufferUtils;
-import io.netty5.util.AsciiString;
-
-/**
- * Test the wrapper that adapts any {@link ProtonBuffer} to a Netty 5 {@link Buffer}
- */
-@Timeout(20)
-public class ProtonBufferToNetty5AdapterTest {
-
- private static FileChannel closedChannel;
- private static FileChannel channel;
-
- @BeforeAll
- static void setUpChannels(@TempDir Path parentDirectory) throws IOException {
- closedChannel = tempFileChannel(parentDirectory);
- closedChannel.close();
- channel = tempFileChannel(parentDirectory);
- }
-
- @AfterAll
- static void tearDownChannels() throws IOException {
- channel.close();
- }
-
- //----- Tests for basic buffer lifecycle APIs
-
- @Test
- public void testBufferShouldNotBeAccessibleAfterClose() {
- try (Buffer buf = createProtonNetty5Buffer(24)) {
- buf.writeLong(42);
- buf.close();
- verifyInaccessible(buf);
- }
- }
-
- //----- Tests for access to buffer bytes by index
-
- @Test
- public void testOffsettedGetOfByteMustBoundsCheckOnNegativeOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteReadOnlyMustBoundsCheckOnNegativeOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteMustNotBoundsCheckWhenReadOffsetAndSizeIsEqualToWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- byte value = 0x01;
- buf.writeByte(value);
- assertEquals(value, buf.getByte(0));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteMustReadWithDefaultEndianByteOrder() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- byte value = 0x01;
- buf.writeByte(value);
- buf.setByte(0, (byte) 0x10);
- assertEquals(0x10, buf.getByte(0));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteMustBoundsCheckWhenReadOffsetAndSizeIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- byte value = 0x01;
- buf.writeByte(value);
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteReadOnlyMustBoundsCheckWhenReadOffsetAndSizeIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- byte value = 0x01;
- buf.writeByte(value);
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteMustNotBoundsCheckWhenReadOffsetIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.getByte(0);
- }
- }
-
- @Test
- public void testOffsettedGetOfByteMustBoundsCheckWhenReadOffsetIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getByte(8));
- }
- }
-
- @Test
- public void testOffsettedGetOfByteReadOnlyMustNotBoundsCheckWhenReadOffsetIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.makeReadOnly().getByte(0);
- }
- }
-
- @Test
- public void testOffsettedGetOfByteReadOnlyMustBoundsCheckWhenReadOffsetIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getByte(8));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustBoundsCheckOnNegativeOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getUnsignedByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteReadOnlyMustBoundsCheckOnNegativeOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getUnsignedByte(-1));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustNotBoundsCheckWhenReadOffsetAndSizeIsEqualToWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- int value = 0x01;
- buf.writeUnsignedByte(value);
- assertEquals(value, buf.getUnsignedByte(0));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustReadWithDefaultEndianByteOrder() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- int value = 0x01;
- buf.writeUnsignedByte(value);
- buf.setByte(0, (byte) 0x10);
- assertEquals(0x10, buf.getUnsignedByte(0));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustNotBoundsCheckWhenReadOffsetAndSizeIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- int value = 0x01;
- buf.writeUnsignedByte(value);
- buf.getUnsignedByte(1);
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustBoundsCheckWhenReadOffsetAndSizeIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getUnsignedByte(8));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteReadOnlyMustNotBoundsCheckWhenReadOffsetAndSizeIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- int value = 0x01;
- buf.writeUnsignedByte(value);
- buf.makeReadOnly().getUnsignedByte(1);
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteReadOnlyMustBoundsCheckWhenReadOffsetAndSizeIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getUnsignedByte(8));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustNotBoundsCheckWhenReadOffsetIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.getUnsignedByte(0);
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteMustBoundsCheckWhenReadOffsetIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.getUnsignedByte(8));
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteReadOnlyMustNotBoundsCheckWhenReadOffsetIsGreaterThanWriteOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.makeReadOnly().getUnsignedByte(0);
- }
- }
-
- @Test
- public void testOffsettedGetOfUnsignedByteReadOnlyMustBoundsCheckWhenReadOffsetIsGreaterThanCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(IndexOutOfBoundsException.class, () -> buf.makeReadOnly().getUnsignedByte(8));
- }
- }
-
- @SuppressWarnings("resource")
- @Test
- public void testOffsettedSetOfByteMustBoundsCheckWhenWriteOffsetIsNegative() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- assertEquals(Long.BYTES, buf.capacity());
- byte value = 0x01;
- assertThrows(IndexOutOfBoundsException.class, () -> buf.setByte(-1, value));
- buf.writerOffset(Long.BYTES);
- // Verify contents are unchanged.
- assertEquals(0, buf.readLong());
- }
- }
-
- @SuppressWarnings("resource")
- @Test
- public void testOffsettedSetOfByteMustBoundsCheckWhenWriteOffsetAndSizeIsBeyondCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- assertEquals(Long.BYTES, buf.capacity());
- byte value = 0x01;
- assertThrows(IndexOutOfBoundsException.class, () -> buf.setByte(8, value));
- buf.writerOffset(Long.BYTES);
- // Verify contents are unchanged.
- assertEquals(0, buf.readLong());
- }
- }
-
- @Test
- public void testOffsettedSetOfByteMustHaveDefaultEndianByteOrder() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- byte value = 0x01;
- buf.setByte(0, value);
- buf.writerOffset(Long.BYTES);
- assertEquals((byte) 0x01, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- }
- }
-
- @SuppressWarnings("resource")
- @Test
- public void testOffsettedSetOfUnsignedByteMustBoundsCheckWhenWriteOffsetIsNegative() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- assertEquals(Long.BYTES, buf.capacity());
- int value = 0x01;
- assertThrows(IndexOutOfBoundsException.class, () -> buf.setUnsignedByte(-1, value));
- buf.writerOffset(Long.BYTES);
- // Verify contents are unchanged.
- assertEquals(0, buf.readLong());
- }
- }
-
- @SuppressWarnings("resource")
- @Test
- public void testOffsettedSetOfUnsignedByteMustBoundsCheckWhenWriteOffsetAndSizeIsBeyondCapacity() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- assertEquals(Long.BYTES, buf.capacity());
- int value = 0x01;
- assertThrows(IndexOutOfBoundsException.class, () -> buf.setUnsignedByte(8, value));
- buf.writerOffset(Long.BYTES);
- // Verify contents are unchanged.
- assertEquals(0, buf.readLong());
- }
- }
-
- @Test
- public void testOffsettedSetOfUnsignedByteMustHaveDefaultEndianByteOrder() {
- try (Buffer buf = createProtonNetty5Buffer(8).fill((byte) 0)) {
- int value = 0x01;
- buf.setUnsignedByte(0, value);
- buf.writerOffset(Long.BYTES);
- assertEquals((byte) 0x01, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- assertEquals((byte) 0x00, buf.readByte());
- }
- }
-
- //----- Test char sequence API
-
- @Test
- public void testReadCharSequence() {
- try (Buffer buf = createProtonNetty5Buffer(32)) {
- String data = "Hello World";
- buf.writeBytes(data.getBytes(StandardCharsets.US_ASCII));
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(0, buf.readerOffset());
-
- final CharSequence charSequence = buf.readCharSequence(data.length(), StandardCharsets.US_ASCII);
- assertEquals(data, charSequence.toString());
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(data.length(), buf.readerOffset());
- }
- }
-
- @Test
- public void testWriteCharSequence() {
- try (Buffer buf = createProtonNetty5Buffer(32)) {
- AsciiString data = new AsciiString("Hello world".getBytes(StandardCharsets.US_ASCII));
- buf.writeCharSequence(data, StandardCharsets.US_ASCII);
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(0, buf.readerOffset());
-
- final byte[] read = readByteArray(buf);
- assertEquals(data.toString(), new String(read, StandardCharsets.US_ASCII));
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(data.length(), buf.readerOffset());
- }
- }
-
- @Test
- public void testWriteCharSequenceMustExpandCapacityIfBufferIsTooSmall() {
- try (Buffer buffer = createProtonNetty5Buffer(4)) {
- String string = "Hello World";
- buffer.writeCharSequence(string, StandardCharsets.US_ASCII);
- assertTrue(buffer.capacity() >= string.length());
- }
- }
-
- @Test
- public void testReadAndWriteCharSequence() {
- try (Buffer buf = createProtonNetty5Buffer(32)) {
- AsciiString data = new AsciiString("Hello world".getBytes(StandardCharsets.US_ASCII));
- buf.writeCharSequence(data, StandardCharsets.US_ASCII);
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(0, buf.readerOffset());
-
- final CharSequence read = buf.readCharSequence(data.length(), StandardCharsets.US_ASCII);
- assertEquals(data.toString(), read.toString());
- assertEquals(data.length(), buf.writerOffset());
- assertEquals(data.length(), buf.readerOffset());
- }
- }
-
- //----- Tests for the buffer component iteration API
-
- @Test
- public void testFill() {
- try (Buffer buf = createProtonNetty5Buffer(16)) {
- assertSame(buf, buf.fill((byte) 0xA5));
- buf.writerOffset(16);
- assertEquals(0xA5A5A5A5_A5A5A5A5L, buf.readLong());
- assertEquals(0xA5A5A5A5_A5A5A5A5L, buf.readLong());
- }
- }
-
- @Test
- public void testComponentCountOfNonCompositeBufferMustBeOne() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertEquals(1, buf.countComponents());
- }
- }
-
- @Test
- public void testReadableComponentCountMustBeOneIfThereAreReadableBytes() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertEquals(0, buf.countReadableComponents());
- buf.writeByte((byte) 1);
- assertEquals(1, buf.countReadableComponents());
- }
- }
-
- @Test
- public void testWritableComponentCountMustBeOneIfThereAreWritableBytes() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertEquals(1, buf.countWritableComponents());
- buf.writeLong(1);
- assertEquals(0, buf.countWritableComponents());
- }
- }
-
- @Test
- public void compositeBufferComponentCountMustBeTransitiveSum() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator()) {
- try (ProtonBuffer a = allocator.allocate(8);
- ProtonBuffer b = allocator.allocate(8);
- ProtonBuffer c = allocator.allocate(8);
- ProtonBuffer x = allocator.composite(new ProtonBuffer[] { b, c });
- ProtonBuffer composite = allocator.composite(new ProtonBuffer[] { a, x });
- ProtonBufferToNetty5Adapter buf = new ProtonBufferToNetty5Adapter(composite)) {
-
- assertEquals(3, buf.countComponents());
- assertEquals(0, buf.countReadableComponents());
- assertEquals(3, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(1, buf.countReadableComponents());
- assertEquals(3, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(1, buf.countReadableComponents());
- assertEquals(2, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(2, buf.countReadableComponents());
- assertEquals(2, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(2, buf.countReadableComponents());
- assertEquals(1, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(3, buf.countReadableComponents());
- assertEquals(1, buf.countWritableComponents());
- buf.writeInt(1);
- assertEquals(3, buf.countReadableComponents());
- assertEquals(0, buf.countWritableComponents());
- }
- }
- }
-
- @Test
- public void testForEachComponentMustVisitBuffer() {
- final long value = 0x0102030405060708L;
- try (Buffer bufBERW = createProtonNetty5Buffer(8).writeLong(value);
- Buffer bufBERO = createProtonNetty5Buffer(8).writeLong(value).makeReadOnly()) {
-
- verifyReadingForEachSingleComponent(bufBERW);
- verifyReadingForEachSingleComponent(bufBERO);
- }
- }
-
- @Test
- public void testForEachComponentMustVisitAllReadableConstituentBuffersInOrder() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator();
- ProtonBuffer a = allocator.allocate(4).writeInt(1);
- ProtonBuffer b = allocator.allocate(4).writeInt(2);
- ProtonBuffer c = allocator.allocate(4).writeInt(3);
- ProtonBuffer protonComposite = allocator.composite(new ProtonBuffer[] { a, b, c });
- ProtonBufferToNetty5Adapter composite = new ProtonBufferToNetty5Adapter(protonComposite)) {
-
- LinkedList list = new LinkedList(List.of(1, 2, 3));
- int index = 0;
- try (var iterator = composite.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- var buffer = component.readableBuffer();
- int bufferValue = buffer.getInt();
- int expectedValue = list.pollFirst().intValue();
- assertEquals(expectedValue, bufferValue);
- assertEquals(bufferValue, index + 1);
- assertThrows(ReadOnlyBufferException.class, () -> buffer.put(0, (byte) 0xFF));
- var writableBuffer = InternalBufferUtils.tryGetWritableBufferFromReadableComponent(component);
- if (writableBuffer != null) {
- int pos = writableBuffer.position();
- bufferValue = writableBuffer.getInt();
- assertEquals(expectedValue, bufferValue);
- assertEquals(bufferValue, index + 1);
- writableBuffer.put(pos, (byte) 0xFF);
- assertEquals((byte) 0xFF, writableBuffer.get(pos));
- }
- index++;
- }
- }
- assertEquals(3, index);
- assertTrue(list.isEmpty());
- }
- }
-
- @Test
- public void testForEachComponentOnClosedBufferMustThrow() {
- try (Buffer writableBuffer = createProtonNetty5Buffer(8);
- Buffer readableBuffer = createProtonNetty5Buffer(8)) {
-
- writableBuffer.close();
- assertThrows(BufferClosedException.class, () -> writableBuffer.forEachComponent());
-
- readableBuffer.writeLong(0);
- readableBuffer.close();
- assertThrows(BufferClosedException.class, () -> readableBuffer.forEachComponent());
- }
- }
-
- @Test
- public void testForEachComponentMustAllowCollectingBuffersInArray() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator()) {
- try (ProtonBuffer a = allocator.allocate(4);
- ProtonBuffer b = allocator.allocate(4);
- ProtonBuffer c = allocator.allocate(4);
- ProtonBuffer protonComposite = allocator.composite(new ProtonBuffer[] { a, b, c });
- Buffer composite = new ProtonBufferToNetty5Adapter(protonComposite)) {
-
- int i = 1;
- while (composite.writableBytes() > 0) {
- composite.writeByte((byte) i++);
- }
- ByteBuffer[] buffers = new ByteBuffer[composite.countComponents()];
- try (var iterator = composite.forEachComponent()) {
- int index = 0;
- for (var component = iterator.first(); component != null; component = component.next()) {
- buffers[index] = component.readableBuffer();
- index++;
- }
- }
- i = 1;
- assertTrue(buffers.length >= 1);
- for (ByteBuffer buffer : buffers) {
- while (buffer.hasRemaining()) {
- assertEquals((byte) i++, buffer.get());
- }
- }
- }
-
- try (ProtonBuffer singleBuffer = allocator.allocate(4);
- Buffer single = new ProtonBufferToNetty5Adapter(singleBuffer)) {
- ByteBuffer[] buffers = new ByteBuffer[single.countComponents()];
- try (var iterator = single.forEachComponent()) {
- int index = 0;
- for (var component = iterator.first(); component != null; component = component.next()) {
- buffers[index] = component.writableBuffer();
- index++;
- }
- }
- assertTrue(buffers.length >= 1);
- int i = 1;
- for (ByteBuffer buffer : buffers) {
- while (buffer.hasRemaining()) {
- buffer.put((byte) i++);
- }
- }
- single.writerOffset(single.capacity());
- i = 1;
- while (single.readableBytes() > 0) {
- assertEquals((byte) i++, single.readByte());
- }
- }
- }
- }
-
- @Test
- public void testForEachComponentMustExposeByteCursors() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator();
- ProtonBuffer inner = allocator.allocate(20);
- Buffer buf = new ProtonBufferToNetty5Adapter(inner)) {
-
- buf.writeLong(0x0102030405060708L);
- buf.writeLong(0x1112131415161718L);
- assertEquals(0x01020304, buf.readInt());
- try (ProtonBuffer innerActual = allocator.allocate(buf.readableBytes());
- Buffer actualData = new ProtonBufferToNetty5Adapter(innerActual);
- ProtonBuffer innerExpected = allocator.allocate(12);
- Buffer expectedData = new ProtonBufferToNetty5Adapter(innerExpected)) {
-
- expectedData.writeInt(0x05060708);
- expectedData.writeInt(0x11121314);
- expectedData.writeInt(0x15161718);
-
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteCursor forward = component.openCursor();
- while (forward.readByte()) {
- actualData.writeByte(forward.getByte());
- }
- }
- }
-
- assertEquals(expectedData.readableBytes(), actualData.readableBytes());
- while (expectedData.readableBytes() > 0) {
- assertEquals(expectedData.readByte(), actualData.readByte());
- }
- }
- }
- }
-
- @Test
- public void testForEachComponentMustExposeByteCursorsPartial() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator();
- ProtonBuffer inner = allocator.allocate(32);
- Buffer buf = new ProtonBufferToNetty5Adapter(inner)) {
-
- buf.writeLong(0x0102030405060708L);
- buf.writeLong(0x1112131415161718L);
- assertEquals(0x01020304, buf.readInt());
- try (ProtonBuffer innerActual = allocator.allocate(buf.readableBytes());
- Buffer actualData = new ProtonBufferToNetty5Adapter(innerActual);
- ProtonBuffer innerExpected = allocator.allocate(12);
- Buffer expectedData = new ProtonBufferToNetty5Adapter(innerExpected)) {
-
- expectedData.writeInt(0x05060708);
- expectedData.writeInt(0x11121314);
- expectedData.writeInt(0x15161718);
-
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteCursor forward = component.openCursor();
- while (forward.readByte()) {
- actualData.writeByte(forward.getByte());
- }
- }
- }
-
- assertEquals(expectedData.readableBytes(), actualData.readableBytes());
- while (expectedData.readableBytes() > 0) {
- assertEquals(expectedData.readByte(), actualData.readByte());
- }
- }
- }
- }
-
- @Test
- public void testForEachComponentMustReturnNullFirstWhenNotReadable() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator();
- ProtonBuffer inner = allocator.allocate(0);
- Buffer buf = new ProtonBufferToNetty5Adapter(inner)) {
-
- try (var iterator = buf.forEachComponent()) {
- // First component may or may not be null.
- var component = iterator.first();
- if (component != null) {
- assertEquals(0, component.readableBytes());
- assertEquals(0, component.readableArrayLength());
- ByteBuffer byteBuffer = component.readableBuffer();
- assertEquals(0, byteBuffer.remaining());
- assertEquals(0, byteBuffer.capacity());
- assertNull(component.next());
- }
- }
- try (var iterator = buf.forEachComponent()) {
- // First *readable* component is definitely null.
- assertNull(iterator.firstReadable());
- }
- }
- }
-
- @Test
- public void testForEachWritableMustVisitBuffer() {
- try (Buffer bufBERW = createProtonNetty5Buffer(8)) {
- verifyWritingForEachSingleComponent(bufBERW);
- }
- }
-
- @Test
- public void testForEachComponentMustVisitAllWritableConstituentBuffersInOrder() {
- try (ProtonBufferAllocator allocator = ProtonBufferAllocator.defaultAllocator();
- ProtonBuffer a = allocator.allocate(8);
- ProtonBuffer b = allocator.allocate(8);
- ProtonBuffer c = allocator.allocate(8);
- ProtonBuffer protonComposite = allocator.composite(new ProtonBuffer[] { a, b, c });
- ProtonBufferToNetty5Adapter buf = new ProtonBufferToNetty5Adapter(protonComposite)) {
-
- try (var iterator = buf.forEachComponent()) {
- int index = 0;
- for (var component = iterator.first(); component != null; component = component.next()) {
- component.writableBuffer().putLong(0x0102030405060708L + 0x1010101010101010L * index);
- index++;
- }
- }
- buf.writerOffset(3 * 8);
- assertEquals(0x0102030405060708L, buf.readLong());
- assertEquals(0x1112131415161718L, buf.readLong());
- assertEquals(0x2122232425262728L, buf.readLong());
- }
- }
-
- @Test
- public void testForEachComponentChangesMadeToByteBufferComponentMustBeReflectedInBuffer() {
- try (Buffer buf = createProtonNetty5Buffer(9)) {
- buf.writeByte((byte) 0xFF);
- AtomicInteger writtenCounter = new AtomicInteger();
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteBuffer buffer = component.writableBuffer();
- while (buffer.hasRemaining()) {
- buffer.put((byte) writtenCounter.incrementAndGet());
- }
- }
- }
- buf.writerOffset(9);
- assertEquals((byte) 0xFF, buf.readByte());
- assertEquals(0x0102030405060708L, buf.readLong());
- }
- }
-
- @Test
- public void testForEachComponentMustHaveZeroWritableBytesWhenNotWritable() {
- try (Buffer buf = createProtonNetty5Buffer(0)) {
- try (var iterator = buf.forEachComponent()) {
- // First component may or may not be null.
- var component = iterator.first();
- if (component != null) {
- assertEquals(0, component.writableBytes());
- assertEquals(0, component.writableArrayLength());
- ByteBuffer byteBuffer = component.writableBuffer();
- assertEquals(0, byteBuffer.remaining());
- assertEquals(0, byteBuffer.capacity());
- assertNull(component.next());
- }
- }
- try (var iterator = buf.forEachComponent()) {
- // First *writable* component is definitely null.
- assertNull(iterator.firstWritable());
- }
- }
- }
-
- @Test
- public void testChangesMadeToByteBufferComponentsInIterationShouldBeReflectedInBuffer() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- AtomicInteger counter = new AtomicInteger();
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteBuffer buffer = component.writableBuffer();
- while (buffer.hasRemaining()) {
- buffer.put((byte) counter.incrementAndGet());
- }
- }
- }
- buf.writerOffset(buf.capacity());
- for (int i = 0; i < 8; i++) {
- assertEquals((byte) i + 1, buf.getByte(i));
- }
- }
- }
-
- @Test
- public void testComponentsOfReadOnlyBufferMustNotHaveAnyWritableBytes() {
- try (Buffer buf = createProtonNetty5Buffer(8).makeReadOnly()) {
- try (var iteration = buf.forEachComponent()) {
- for (var c = iteration.first(); c != null; c = c.next()) {
- assertEquals(0, c.writableBytes());
- assertEquals(0, c.writableArrayLength());
- ByteBuffer byteBuffer = c.writableBuffer();
- assertEquals(0, byteBuffer.remaining());
- assertEquals(0, byteBuffer.capacity());
- }
- }
- try (var iteration = buf.forEachComponent()) {
- assertNull(iteration.firstWritable());
- }
- }
- }
-
- @Test
- public void forEachComponentMustBeAbleToIncrementReaderOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8);
- Buffer target = createProtonNetty5Buffer(5)) {
-
- buf.writeLong(0x0102030405060708L);
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- while (target.writableBytes() > 0 && component.readableBytes() > 0) {
- ByteBuffer byteBuffer = component.readableBuffer();
- byte value = byteBuffer.get();
- byteBuffer.clear();
- target.writeByte(value);
- var cmp = component; // Capture for lambda.
- assertThrows(IndexOutOfBoundsException.class, () -> cmp.skipReadableBytes(9));
- component.skipReadableBytes(0);
- component.skipReadableBytes(1);
- }
- }
- }
-
- assertEquals(5, buf.readerOffset());
- assertEquals(3, buf.readableBytes());
- assertEquals(5, target.readableBytes());
-
- try (Buffer expected = BufferAllocator.onHeapUnpooled().copyOf(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 })) {
- assertEquals(target, expected);
- }
- try (Buffer expected = BufferAllocator.onHeapUnpooled().copyOf(new byte[] { 0x06, 0x07, 0x08 })) {
- assertEquals(buf, expected);
- }
- }
- }
-
- @Test
- public void testForEachComponentMustBeAbleToIncrementWriterOffset() {
- try (Buffer buf = createProtonNetty5Buffer(8).writeLong(0x0102030405060708L);
- Buffer target = buf.copy()) {
-
- buf.writerOffset(0); // Prime the buffer with data, but leave the write-offset at zero.
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- while (component.writableBytes() > 0) {
- ByteBuffer byteBuffer = component.writableBuffer();
- byte value = byteBuffer.get();
- byteBuffer.clear();
- assertEquals(value, target.readByte());
- var cmp = component; // Capture for lambda.
- assertThrows(IndexOutOfBoundsException.class, () -> cmp.skipWritableBytes(9));
- component.skipWritableBytes(0);
- component.skipWritableBytes(1);
- }
- }
- }
-
- assertEquals(8, buf.writerOffset());
- assertEquals(8, target.readerOffset());
- target.readerOffset(0);
- assertEquals(buf, target);
- }
- }
-
- @Test
- public void negativeSkipReadableOnReadableComponentMustThrow() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- assertEquals(0x01020304, buf.readInt());
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- var cmp = component; // Capture for lambda.
- assertThrows(IllegalArgumentException.class, () -> cmp.skipReadableBytes(-1));
- }
- }
- }
- }
-
- @Test
- public void negativeSkipWritableOnWritableComponentMustThrow() {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- var cmp = component; // Capture for lambda.
- assertThrows(IllegalArgumentException.class, () -> cmp.skipWritableBytes(-1));
- }
- }
- }
- }
-
- //----- Test for channel API methods
-
- @Test
- public void testTransferToMustThrowIfBufferIsClosed() throws IOException {
- long position = channel.position();
- long size = channel.size();
- Buffer empty = createProtonNetty5Buffer(8);
- empty.close();
- assertThrows(BufferClosedException.class, () -> empty.transferTo(channel, 8));
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- Buffer withData = createProtonNetty5Buffer(8);
- withData.writeLong(0x0102030405060708L);
- withData.close();
- assertThrows(BufferClosedException.class, () -> withData.transferTo(channel, 8));
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- }
-
- @Test
- public void testTransferToMustCapAtReadableBytes() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- buf.writerOffset(buf.writerOffset() - 5);
- long position = channel.position();
- long size = channel.size();
- int bytesWritten = buf.transferTo(channel, 8);
-
- assertEquals(3, bytesWritten);
- assertEquals(3 + position, channel.position());
- assertEquals(3 + size, channel.size());
- assertEquals(5, buf.writableBytes());
- assertEquals(0, buf.readableBytes());
- }
- }
-
- @Test
- public void testTransferToMustCapAtLength() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- long position = channel.position();
- long size = channel.size();
- int bytesWritten = buf.transferTo(channel, 3);
- assertEquals(3, bytesWritten);
- assertEquals(3 + position, channel.position());
- assertEquals(3 + size, channel.size());
- assertEquals(5, buf.readableBytes());
- }
- }
-
- @Test
- public void testTransferToMustThrowIfChannelIsClosed() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- assertThrows(ClosedChannelException.class, () -> buf.transferTo(closedChannel, 8));
- assertTrue(buf.isAccessible());
- assertEquals(8, buf.readableBytes());
- }
- }
-
- @Test
- public void testTransferToMustThrowIfChannelIsNull() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- assertThrows(NullPointerException.class, () -> buf.transferTo(null, 8));
- assertTrue(buf.isAccessible());
- assertEquals(8, buf.readableBytes());
- }
- }
-
- @Test
- public void testTransferToMustThrowIfLengthIsNegative() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- buf.writeLong(0x0102030405060708L);
- assertThrows(IllegalArgumentException.class, () -> buf.transferTo(channel, -1));
- assertEquals(8, buf.readableBytes());
- }
- }
-
- @Test
- public void transferToMustIgnoreZeroLengthOperations() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long position = channel.position();
- long size = channel.size();
- buf.writeLong(0x0102030405060708L);
- int bytesWritten = buf.transferTo(channel, 0);
- assertEquals(8, buf.readableBytes());
- assertEquals(0, bytesWritten);
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- }
- }
-
- @Test
- public void testTransferToMustMoveDataToChannel() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long value = ThreadLocalRandom.current().nextLong();
- buf.writeLong(value);
- long position = channel.position();
- int bytesWritten = buf.transferTo(channel, 8);
- assertEquals(8, bytesWritten);
- ByteBuffer buffer = ByteBuffer.allocate(8);
- final int bytesRead = channel.read(buffer, position);
- assertEquals(8, bytesRead);
- buffer.flip();
- assertEquals(value, buffer.getLong());
- }
- }
-
- @Test
- public void testTransferToMustMoveReadOnlyDataToChannel() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long value = ThreadLocalRandom.current().nextLong();
- buf.writeLong(value).makeReadOnly();
- long position = channel.position();
- int bytesWritten = buf.transferTo(channel, 8);
- assertEquals(8, bytesWritten);
- ByteBuffer buffer = ByteBuffer.allocate(8);
- int bytesRead = channel.read(buffer, position);
- assertEquals(8, bytesRead);
- buffer.flip();
- assertEquals(value, buffer.getLong());
- }
- }
-
- @Test
- public void testTransferToZeroBytesMustNotThrowOnClosedChannel() throws IOException {
- try (Buffer empty = createProtonNetty5Buffer(0);
- Buffer notEmpty = createProtonNetty5Buffer(4).writeInt(42)) {
-
- empty.transferTo(closedChannel, 4);
- notEmpty.transferTo(closedChannel, 0);
- }
- }
-
- @Test
- public void testTransferFromMustThrowIfBufferIsClosed() throws IOException {
- doTransferFromMustThrowIfBufferIsClosed(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustThrowIfBufferIsClosed() throws IOException {
- doTransferFromMustThrowIfBufferIsClosed(true);
- }
-
- private static void doTransferFromMustThrowIfBufferIsClosed(boolean withPosition) throws IOException {
- try {
- ByteBuffer data = ByteBuffer.allocate(8).putLong(0x0102030405060708L).flip();
- long position = channel.position();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- Buffer empty = createProtonNetty5Buffer(0);
- empty.close();
- assertThrows(BufferClosedException.class, () -> {
- if (withPosition) {
- empty.transferFrom(channel, 4 + position, 8);
- } else {
- empty.transferFrom(channel, 8);
- }
- });
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- Buffer withAvailableSpace = createProtonNetty5Buffer(8);
- withAvailableSpace.close();
- assertThrows(BufferClosedException.class, () -> {
- if (withPosition) {
- withAvailableSpace.transferFrom(channel, 4 + position, 8);
- } else {
- withAvailableSpace.transferFrom(channel, 8);
- }
- });
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustCapAtWritableBytes() throws IOException {
- doTransferFromMustCapAtWritableBytes(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustCapAtWritableBytes() throws IOException {
- doTransferFromMustCapAtWritableBytes(true);
- }
-
- private static void doTransferFromMustCapAtWritableBytes(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(3)) {
- ByteBuffer data = ByteBuffer.allocate(8).putLong(0x0102030405060708L).flip();
- long position = channel.position();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, 4 + position, 8) : buf.transferFrom(channel, 8);
- assertEquals(3, bytesRead);
- assertEquals(withPosition ? position : 3 + position, channel.position());
- assertEquals(size, channel.size());
- assertEquals(0, buf.writableBytes());
- assertEquals(3, buf.readableBytes());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustCapAtLength() throws IOException {
- doTransferFromMustCapAtLength(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustCapAtLength() throws IOException {
- doTransferFromMustCapAtLength(true);
- }
-
- private static void doTransferFromMustCapAtLength(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- ByteBuffer data = ByteBuffer.allocate(8).putLong(0x0102030405060708L).flip();
- long position = channel.position();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, 4 + position, 3) : buf.transferFrom(channel, 3);
- assertEquals(3, bytesRead);
- assertEquals(withPosition ? position : 3 + position, channel.position());
- assertEquals(size, channel.size());
- assertEquals(5, buf.writableBytes());
- assertEquals(3, buf.readableBytes());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustThrowIfChannelIsClosed() {
- doTransferFromMustThrowIfChannelIsClosed(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustThrowIfChannelIsClosed() {
- doTransferFromMustThrowIfChannelIsClosed(true);
- }
-
- private static void doTransferFromMustThrowIfChannelIsClosed(boolean withPosition) {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(ClosedChannelException.class, () -> {
- if (withPosition) {
- buf.transferFrom(closedChannel, 4, 8);
- } else {
- buf.transferFrom(closedChannel, 8);
- }
- });
- assertTrue(buf.isAccessible());
- assertEquals(8, buf.writableBytes());
- }
- }
-
- @Test
- public void testTransferFromMustThrowIfChannelIsNull() {
- doTransferFromMustThrowIfChannelIsNull(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustThrowIfChannelIsNull() {
- doTransferFromMustThrowIfChannelIsNull(true);
- }
-
- private static void doTransferFromMustThrowIfChannelIsNull(boolean withPosition) {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- assertThrows(NullPointerException.class, () -> {
- if (withPosition) {
- buf.transferFrom(null, 4, 8);
- } else {
- buf.transferFrom(null, 8);
- }
- });
- assertTrue(buf.isAccessible());
- assertEquals(8, buf.writableBytes());
- }
- }
-
- @Test
- public void testTransferFromMustThrowIfLengthIsNegative() throws IOException {
- doTransferFromMustThrowIfLengthIsNegative(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustThrowIfLengthIsNegative() throws IOException {
- doTransferFromMustThrowIfLengthIsNegative(true);
- }
-
- private static void doTransferFromMustThrowIfLengthIsNegative(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long position = channel.position();
- ByteBuffer data = ByteBuffer.allocate(8).putLong(0x0102030405060708L).flip();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- assertThrows(IllegalArgumentException.class, () -> {
- if (withPosition) {
- buf.transferFrom(channel, 4 + position, -1);
- } else {
- buf.transferFrom(channel, -1);
- }
- });
- assertTrue(buf.isAccessible());
- assertEquals(8, buf.writableBytes());
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustIgnoreZeroLengthOperations() throws IOException {
- doTransferFromMustIgnoreZeroLengthOperations(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustIgnoreZeroLengthOperations() throws IOException {
- doTransferFromMustIgnoreZeroLengthOperations(true);
- }
-
- private static void doTransferFromMustIgnoreZeroLengthOperations(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long position = channel.position();
- ByteBuffer data = ByteBuffer.allocate(8).putLong(0x0102030405060708L).flip();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, 4 + position, 0) : buf.transferFrom(channel, 0);
- assertEquals(0, bytesRead);
- assertEquals(0, buf.readableBytes());
- assertEquals(8, buf.writableBytes());
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustMoveDataFromChannel() throws IOException {
- doTransferFromMustMoveDataFromChannel(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustMoveDataFromChannel() throws IOException {
- doTransferFromMustMoveDataFromChannel(true);
- }
-
- private static void doTransferFromMustMoveDataFromChannel(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long value = ThreadLocalRandom.current().nextLong();
- ByteBuffer data = ByteBuffer.allocate(8).putLong(value).flip();
- long position = channel.position();
- assertEquals(8, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, position, 8) : buf.transferFrom(channel, 8);
- assertEquals(8, bytesRead);
- assertEquals(8, buf.readableBytes());
- assertEquals(0, buf.writableBytes());
- assertEquals(withPosition ? position : 8 + position, channel.position());
- assertEquals(size, channel.size());
- assertEquals(value, buf.readLong());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustNotReadBeyondEndOfChannel() throws IOException {
- doTransferFromMustNotReadBeyondEndOfChannel(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustNotReadBeyondEndOfChannel() throws IOException {
- doTransferFromMustNotReadBeyondEndOfChannel(true);
- }
-
- private static void doTransferFromMustNotReadBeyondEndOfChannel(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- ByteBuffer data = ByteBuffer.allocate(8).putInt(0x01020304).flip();
- long position = channel.position();
- assertEquals(4, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, position, 8) : buf.transferFrom(channel, 8);
- assertEquals(4, bytesRead);
- assertEquals(4, buf.readableBytes());
- assertEquals(withPosition ? position : 4 + position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustReturnMinusOneForEndOfStream() throws IOException {
- doTransferFromMustReturnMinusOneForEndOfStream(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustReturnMinusOneForEndOfStream() throws IOException {
- doTransferFromMustReturnMinusOneForEndOfStream(true);
- }
-
- private static void doTransferFromMustReturnMinusOneForEndOfStream(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long position = channel.position();
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, position, 8) : buf.transferFrom(channel, 8);
- assertEquals(-1, bytesRead);
- assertEquals(0, buf.readableBytes());
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustReturnMinusOneForEndOfStreamNonScattering() throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8)) {
- long position = channel.position();
- long size = channel.size();
- ReadableByteChannel nonScatteringChannel = new ReadableByteChannel() {
- @Override
- public int read(ByteBuffer dst) throws IOException {
- return channel.read(dst);
- }
-
- @Override
- public boolean isOpen() {
- return channel.isOpen();
- }
-
- @Override
- public void close() throws IOException {
- channel.close();
- }
- };
- final int bytesRead = buf.transferFrom(nonScatteringChannel, 8);
- assertEquals(-1, bytesRead);
- assertEquals(0, buf.readableBytes());
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustStartFromWritableOffset() throws IOException {
- doTransferFromMustStartFromWritableOffset(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustStartFromWritableOffset() throws IOException {
- doTransferFromMustStartFromWritableOffset(true);
- }
-
- private static void doTransferFromMustStartFromWritableOffset(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(4)) {
- ByteBuffer data = ByteBuffer.allocate(4).putInt(0x01020304).flip();
- long position = channel.position();
- assertEquals(4, channel.write(data, position));
- long size = channel.size();
- int bytesRead = withPosition ? buf.transferFrom(channel, position, 2) : buf.transferFrom(channel, 2);
- bytesRead += withPosition ? buf.transferFrom(channel, 2 + position, 2) : buf.transferFrom(channel, 2);
- assertEquals(4, bytesRead);
- assertEquals(4, buf.readableBytes());
- assertEquals(withPosition ? position : 4 + position, channel.position());
- assertEquals(size, channel.size());
- for (int i = 0; i < buf.readableBytes(); i++) {
- assertEquals(data.get(i), buf.readByte());
- }
- } finally {
- channel.position(channel.size());
- }
- }
-
- @Test
- public void testTransferFromMustThrowIfBufferIsReadOnly() throws IOException {
- doTransferFromMustThrowIfBufferIsReadOnly(false);
- }
-
- @Test
- public void testTransferFromWithPositionMustThrowIfBufferIsReadOnly() throws IOException {
- doTransferFromMustThrowIfBufferIsReadOnly(true);
- }
-
- private static void doTransferFromMustThrowIfBufferIsReadOnly(boolean withPosition) throws IOException {
- try (Buffer buf = createProtonNetty5Buffer(8).writeLong(0x0102030405060708L).makeReadOnly()) {
- long position = channel.position();
- long size = channel.size();
- assertThrows(BufferReadOnlyException.class, () -> {
- if (withPosition) {
- buf.transferFrom(channel, 4 + position, 8);
- } else {
- buf.transferFrom(channel, 8);
- }
- });
- assertEquals(8, buf.readableBytes());
- assertEquals(position, channel.position());
- assertEquals(size, channel.size());
- }
- }
-
- @Test
- public void testTransferFromZeroBytesMustNotThrowOnClosedChannel() throws IOException {
- doTransferFromZeroBytesMustNotThrowOnClosedChannel(false);
- }
-
- @Test
- public void testTransferFromWithPositionZeroBytesMustNotThrowOnClosedChannel() throws IOException {
- doTransferFromZeroBytesMustNotThrowOnClosedChannel(true);
- }
-
- private static void doTransferFromZeroBytesMustNotThrowOnClosedChannel(boolean withPosition) throws IOException {
- try (Buffer empty = createProtonNetty5Buffer(0);
- Buffer notEmpty = createProtonNetty5Buffer(4)) {
-
- if (withPosition) {
- empty.transferFrom(closedChannel, 4, 4);
- notEmpty.transferFrom(closedChannel, 4, 0);
- } else {
- empty.transferFrom(closedChannel, 4);
- notEmpty.transferFrom(closedChannel, 0);
- }
- }
- }
-
- private static void verifyReadingForEachSingleComponent(Buffer buf) {
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteBuffer buffer = component.readableBuffer();
- assertEquals(0, buffer.position());
- assertEquals(8, buffer.limit());
- assertEquals(8, buffer.capacity());
-
- assertEquals(0x0102030405060708L, buffer.getLong());
-
- if (component.hasReadableArray()) {
- byte[] array = component.readableArray();
- byte[] arrayCopy = new byte[component.readableArrayLength()];
- System.arraycopy(array, component.readableArrayOffset(), arrayCopy, 0, arrayCopy.length);
- if (buffer.order() == BIG_ENDIAN) {
- assertArrayEquals(arrayCopy, new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
- } else {
- assertArrayEquals(arrayCopy, new byte[] {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x0});
- }
- }
-
- assertThrows(ReadOnlyBufferException.class, () -> buffer.put(0, (byte) 0xFF));
- }
- }
- }
-
- public static void verifyWritingForEachSingleComponent(Buffer buf) {
- buf.fill((byte) 0);
- try (var iterator = buf.forEachComponent()) {
- for (var component = iterator.first(); component != null; component = component.next()) {
- ByteBuffer buffer = component.writableBuffer();
- assertEquals(0, buffer.position());
- assertEquals(8, buffer.limit());
- assertEquals(8, buffer.capacity());
- buffer.putLong(0x0102030405060708L);
- buffer.flip();
- assertEquals(0x0102030405060708L, buffer.getLong());
- buf.writerOffset(8);
- assertEquals(0x0102030405060708L, buf.getLong(0));
-
- assertEquals(0, component.writableNativeAddress());
-
- buf.writerOffset(0);
- if (component.hasWritableArray()) {
- byte[] array = component.writableArray();
- int offset = component.writableArrayOffset();
- byte[] arrayCopy = new byte[component.writableArrayLength()];
- System.arraycopy(array, offset, arrayCopy, 0, arrayCopy.length);
- if (buffer.order() == BIG_ENDIAN) {
- assertArrayEquals(arrayCopy, new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
- } else {
- assertArrayEquals(arrayCopy, new byte[] {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x0});
- }
- }
-
- buffer.put(0, (byte) 0xFF);
- assertEquals((byte) 0xFF, buffer.get(0));
- assertEquals((byte) 0xFF, buf.getByte(0));
- }
- }
- }
- private static Buffer createProtonNetty5Buffer(int capacity) {
- ProtonBuffer protonBuffer = ProtonBufferAllocator.defaultAllocator().allocate(capacity);
- ProtonBufferToNetty5Adapter wrapper = new ProtonBufferToNetty5Adapter(protonBuffer);
-
- return wrapper;
- }
-
- private static FileChannel tempFileChannel(Path parentDirectory) throws IOException {
- Path path = Files.createTempFile(parentDirectory, "BufferAndChannelTest", "txt");
- return FileChannel.open(path, READ, WRITE, DELETE_ON_CLOSE);
- }
-
- public static byte[] readByteArray(Buffer buf) {
- byte[] bs = new byte[buf.readableBytes()];
- buf.copyInto(buf.readerOffset(), bs, 0, bs.length);
- buf.readerOffset(buf.writerOffset());
- return bs;
- }
-
- @SuppressWarnings("resource")
- private static void verifyInaccessible(Buffer buf) {
- verifyReadInaccessible(buf);
-
- verifyWriteInaccessible(buf, BufferClosedException.class);
-
- try (BufferAllocator allocator = BufferAllocator.onHeapUnpooled();
- Buffer target = allocator.allocate(24)) {
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, target, 0, 1));
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, target, 0, 0));
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, new byte[1], 0, 1));
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, new byte[1], 0, 0));
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, ByteBuffer.allocate(1), 0, 1));
- assertThrows(BufferClosedException.class, () -> buf.copyInto(0, ByteBuffer.allocate(1), 0, 0));
- if (CompositeBuffer.isComposite(buf)) {
- assertThrows(BufferClosedException.class, () -> ((CompositeBuffer) buf).extendWith(target.send()));
- }
- }
-
- assertThrows(BufferClosedException.class, () -> buf.split());
- assertThrows(BufferClosedException.class, () -> buf.send());
- assertThrows(BufferClosedException.class, () -> buf.copy());
- assertThrows(BufferClosedException.class, () -> buf.openCursor());
- assertThrows(BufferClosedException.class, () -> buf.openCursor(0, 0));
- assertThrows(BufferClosedException.class, () -> buf.openReverseCursor());
- assertThrows(BufferClosedException.class, () -> buf.openReverseCursor(0, 0));
- }
-
- private static void verifyReadInaccessible(Buffer buf) {
- assertThrows(BufferClosedException.class, () -> buf.readBoolean());
- assertThrows(BufferClosedException.class, () -> buf.readByte());
- assertThrows(BufferClosedException.class, () -> buf.readUnsignedByte());
- assertThrows(BufferClosedException.class, () -> buf.readChar());
- assertThrows(BufferClosedException.class, () -> buf.readShort());
- assertThrows(BufferClosedException.class, () -> buf.readUnsignedShort());
- assertThrows(BufferClosedException.class, () -> buf.readMedium());
- assertThrows(BufferClosedException.class, () -> buf.readUnsignedMedium());
- assertThrows(BufferClosedException.class, () -> buf.readInt());
- assertThrows(BufferClosedException.class, () -> buf.readUnsignedInt());
- assertThrows(BufferClosedException.class, () -> buf.readFloat());
- assertThrows(BufferClosedException.class, () -> buf.readLong());
- assertThrows(BufferClosedException.class, () -> buf.readDouble());
-
- assertThrows(BufferClosedException.class, () -> buf.getBoolean(0));
- assertThrows(BufferClosedException.class, () -> buf.getByte(0));
- assertThrows(BufferClosedException.class, () -> buf.getUnsignedByte(0));
- assertThrows(BufferClosedException.class, () -> buf.getChar(0));
- assertThrows(BufferClosedException.class, () -> buf.getShort(0));
- assertThrows(BufferClosedException.class, () -> buf.getUnsignedShort(0));
- assertThrows(BufferClosedException.class, () -> buf.getMedium(0));
- assertThrows(BufferClosedException.class, () -> buf.getUnsignedMedium(0));
- assertThrows(BufferClosedException.class, () -> buf.getInt(0));
- assertThrows(BufferClosedException.class, () -> buf.getUnsignedInt(0));
- assertThrows(BufferClosedException.class, () -> buf.getFloat(0));
- assertThrows(BufferClosedException.class, () -> buf.getLong(0));
- assertThrows(BufferClosedException.class, () -> buf.getDouble(0));
- }
-
- private static void verifyWriteInaccessible(Buffer buf, Class extends RuntimeException> expected) {
- assertThrows(expected, () -> buf.writeByte((byte) 32));
- assertThrows(expected, () -> buf.writeUnsignedByte(32));
- assertThrows(expected, () -> buf.writeChar('3'));
- assertThrows(expected, () -> buf.writeShort((short) 32));
- assertThrows(expected, () -> buf.writeUnsignedShort(32));
- assertThrows(expected, () -> buf.writeMedium(32));
- assertThrows(expected, () -> buf.writeUnsignedMedium(32));
- assertThrows(expected, () -> buf.writeInt(32));
- assertThrows(expected, () -> buf.writeUnsignedInt(32));
- assertThrows(expected, () -> buf.writeFloat(3.2f));
- assertThrows(expected, () -> buf.writeLong(32));
- assertThrows(expected, () -> buf.writeDouble(32));
-
- assertThrows(expected, () -> buf.setByte(0, (byte) 32));
- assertThrows(expected, () -> buf.setUnsignedByte(0, 32));
- assertThrows(expected, () -> buf.setChar(0, '3'));
- assertThrows(expected, () -> buf.setShort(0, (short) 32));
- assertThrows(expected, () -> buf.setUnsignedShort(0, 32));
- assertThrows(expected, () -> buf.setMedium(0, 32));
- assertThrows(expected, () -> buf.setUnsignedMedium(0, 32));
- assertThrows(expected, () -> buf.setInt(0, 32));
- assertThrows(expected, () -> buf.setUnsignedInt(0, 32));
- assertThrows(expected, () -> buf.setFloat(0, 3.2f));
- assertThrows(expected, () -> buf.setLong(0, 32));
- assertThrows(expected, () -> buf.setDouble(0, 32));
-
- assertThrows(expected, () -> buf.ensureWritable(1));
- assertThrows(expected, () -> buf.fill((byte) 0));
- assertThrows(expected, () -> buf.compact());
- try (BufferAllocator allocator = BufferAllocator.onHeapUnpooled();
- Buffer source = allocator.allocate(8)) {
- assertThrows(expected, () -> source.copyInto(0, buf, 0, 1));
- if (expected == BufferClosedException.class) {
- assertThrows(expected, () -> buf.copyInto(0, source, 0, 1));
- }
- }
- }
-}