From 8325812fccdd9b2f3c6411c76c59ed63fd0813c1 Mon Sep 17 00:00:00 2001 From: Andrew Ross Date: Wed, 5 Feb 2025 08:51:22 -0800 Subject: [PATCH] Remove transport-nio plugin (#17251) Signed-off-by: Andrew Ross --- CHANGELOG-3.0.md | 1 + gradle/missing-javadoc.gradle | 1 - plugins/identity-shiro/build.gradle | 1 - plugins/transport-nio/build.gradle | 192 ------ .../transport-nio/licenses/netty-LICENSE.txt | 202 ------- .../transport-nio/licenses/netty-NOTICE.txt | 116 ---- .../netty-buffer-4.1.117.Final.jar.sha1 | 1 - .../netty-codec-4.1.117.Final.jar.sha1 | 1 - .../netty-codec-http-4.1.117.Final.jar.sha1 | 1 - .../netty-common-4.1.117.Final.jar.sha1 | 1 - .../netty-handler-4.1.117.Final.jar.sha1 | 1 - .../netty-resolver-4.1.117.Final.jar.sha1 | 1 - .../netty-transport-4.1.117.Final.jar.sha1 | 1 - ...-native-unix-common-4.1.117.Final.jar.sha1 | 1 - .../java/org/opensearch/NioIntegTestCase.java | 73 --- .../opensearch/http/nio/NioPipeliningIT.java | 82 --- .../transport/nio/NioTransportLoggingIT.java | 122 ---- .../org/opensearch/http/nio/ByteBufUtils.java | 90 --- .../http/nio/HttpReadWriteHandler.java | 246 -------- .../http/nio/HttpWriteOperation.java | 67 --- .../org/opensearch/http/nio/NettyAdaptor.java | 152 ----- .../opensearch/http/nio/NettyListener.java | 259 -------- .../opensearch/http/nio/NioHttpChannel.java | 61 -- .../http/nio/NioHttpPipeliningHandler.java | 113 ---- .../opensearch/http/nio/NioHttpRequest.java | 336 ----------- .../http/nio/NioHttpRequestCreator.java | 63 -- .../opensearch/http/nio/NioHttpResponse.java | 66 --- .../http/nio/NioHttpResponseCreator.java | 84 --- .../http/nio/NioHttpServerChannel.java | 56 -- .../http/nio/NioHttpServerTransport.java | 367 ------------ .../org/opensearch/http/nio/PagedByteBuf.java | 88 --- .../org/opensearch/http/nio/ssl/SslUtils.java | 48 -- .../opensearch/http/nio/ssl/package-info.java | 12 - .../transport/nio/NioGroupFactory.java | 193 ------ .../transport/nio/NioTcpChannel.java | 92 --- .../transport/nio/NioTcpServerChannel.java | 64 -- .../transport/nio/NioTransport.java | 222 ------- .../transport/nio/NioTransportPlugin.java | 188 ------ .../transport/nio/PageAllocator.java | 61 -- .../transport/nio/TcpReadWriteHandler.java | 94 --- .../plugin-metadata/plugin-security.policy | 44 -- .../http/nio/HttpReadWriteHandlerTests.java | 334 ----------- .../http/nio/NettyAdaptorTests.java | 193 ------ .../opensearch/http/nio/NioHttpClient.java | 388 ------------ .../nio/NioHttpPipeliningHandlerTests.java | 269 --------- .../http/nio/NioHttpServerTransportTests.java | 540 ----------------- .../http/nio/PagedByteBufTests.java | 105 ---- .../SecureNioHttpServerTransportTests.java | 558 ------------------ .../transport/nio/NioGroupFactoryTests.java | 96 --- .../nio/SimpleNioTransportTests.java | 168 ------ .../src/test/resources/README.txt | 14 - .../src/test/resources/certificate.crt | 22 - .../src/test/resources/certificate.key | 28 - qa/smoke-test-http/build.gradle | 1 - .../opensearch/http/HttpSmokeTestCase.java | 15 +- .../http/IdentityAuthenticationIT.java | 3 +- 56 files changed, 7 insertions(+), 6591 deletions(-) delete mode 100644 plugins/transport-nio/build.gradle delete mode 100644 plugins/transport-nio/licenses/netty-LICENSE.txt delete mode 100644 plugins/transport-nio/licenses/netty-NOTICE.txt delete mode 100644 plugins/transport-nio/licenses/netty-buffer-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-codec-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-codec-http-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-common-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-handler-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-resolver-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-transport-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/licenses/netty-transport-native-unix-common-4.1.117.Final.jar.sha1 delete mode 100644 plugins/transport-nio/src/internalClusterTest/java/org/opensearch/NioIntegTestCase.java delete mode 100644 plugins/transport-nio/src/internalClusterTest/java/org/opensearch/http/nio/NioPipeliningIT.java delete mode 100644 plugins/transport-nio/src/internalClusterTest/java/org/opensearch/transport/nio/NioTransportLoggingIT.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/ByteBufUtils.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpReadWriteHandler.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpWriteOperation.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyAdaptor.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyListener.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpChannel.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpPipeliningHandler.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequest.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequestCreator.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponse.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponseCreator.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerChannel.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerTransport.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/PagedByteBuf.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/SslUtils.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/package-info.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioGroupFactory.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpChannel.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpServerChannel.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransport.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransportPlugin.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/PageAllocator.java delete mode 100644 plugins/transport-nio/src/main/java/org/opensearch/transport/nio/TcpReadWriteHandler.java delete mode 100644 plugins/transport-nio/src/main/plugin-metadata/plugin-security.policy delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/HttpReadWriteHandlerTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/NettyAdaptorTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpClient.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpPipeliningHandlerTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpServerTransportTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/PagedByteBufTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/http/nio/ssl/SecureNioHttpServerTransportTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/transport/nio/NioGroupFactoryTests.java delete mode 100644 plugins/transport-nio/src/test/java/org/opensearch/transport/nio/SimpleNioTransportTests.java delete mode 100644 plugins/transport-nio/src/test/resources/README.txt delete mode 100644 plugins/transport-nio/src/test/resources/certificate.crt delete mode 100644 plugins/transport-nio/src/test/resources/certificate.key diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index 3aab0be90af7e..4b627d9b28baa 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -51,6 +51,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Remove custom Map, List and Set collection classes ([#6871](https://github.com/opensearch-project/OpenSearch/pull/6871)) - Remove `index.store.hybrid.mmap.extensions` setting in favor of `index.store.hybrid.nio.extensions` setting ([#9392](https://github.com/opensearch-project/OpenSearch/pull/9392)) - Remove package org.opensearch.action.support.master ([#4856](https://github.com/opensearch-project/OpenSearch/issues/4856)) +- Remove transport-nio plugin ([#16887](https://github.com/opensearch-project/OpenSearch/issues/16887)) ### Fixed - Fix 'org.apache.hc.core5.http.ParseException: Invalid protocol version' under JDK 16+ ([#4827](https://github.com/opensearch-project/OpenSearch/pull/4827)) diff --git a/gradle/missing-javadoc.gradle b/gradle/missing-javadoc.gradle index d65a318b096a9..6e31f838e678a 100644 --- a/gradle/missing-javadoc.gradle +++ b/gradle/missing-javadoc.gradle @@ -149,7 +149,6 @@ configure([ project(":plugins:repository-hdfs"), project(":plugins:repository-s3"), project(":plugins:store-smb"), - project(":plugins:transport-nio"), project(":plugins:crypto-kms"), project(":qa:die-with-dignity"), project(":qa:wildfly"), diff --git a/plugins/identity-shiro/build.gradle b/plugins/identity-shiro/build.gradle index 2ea3e8e6b1e50..436a9b3e48128 100644 --- a/plugins/identity-shiro/build.gradle +++ b/plugins/identity-shiro/build.gradle @@ -31,7 +31,6 @@ dependencies { implementation "org.bouncycastle:bcprov-jdk18on:${versions.bouncycastle}" testImplementation project(path: ':modules:transport-netty4') // for http - testImplementation project(path: ':plugins:transport-nio') // for http testImplementation "org.mockito:mockito-core:${versions.mockito}" testImplementation project(path: ':client:rest-high-level') testImplementation 'junit:junit:4.13.2' diff --git a/plugins/transport-nio/build.gradle b/plugins/transport-nio/build.gradle deleted file mode 100644 index 6ac27b51f8902..0000000000000 --- a/plugins/transport-nio/build.gradle +++ /dev/null @@ -1,192 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -import org.opensearch.gradle.info.BuildParams - -apply plugin: "opensearch.publish" -apply plugin: 'opensearch.internal-cluster-test' - -opensearchplugin { - description = 'The nio transport.' - classname = 'org.opensearch.transport.nio.NioTransportPlugin' - hasClientJar = true -} - -dependencies { - api project(':libs:opensearch-nio') - - // network stack - api "io.netty:netty-buffer:${versions.netty}" - api "io.netty:netty-codec:${versions.netty}" - api "io.netty:netty-codec-http:${versions.netty}" - api "io.netty:netty-common:${versions.netty}" - api "io.netty:netty-handler:${versions.netty}" - api "io.netty:netty-resolver:${versions.netty}" - api "io.netty:netty-transport:${versions.netty}" - api "io.netty:netty-transport-native-unix-common:${versions.netty}" -} - -tasks.named("dependencyLicenses").configure { - mapping from: /netty-.*/, to: 'netty' -} - -thirdPartyAudit { - ignoreMissingClasses( - 'com.aayushatharva.brotli4j.Brotli4jLoader', - 'com.aayushatharva.brotli4j.decoder.DecoderJNI$Status', - 'com.aayushatharva.brotli4j.decoder.DecoderJNI$Wrapper', - 'com.aayushatharva.brotli4j.encoder.BrotliEncoderChannel', - 'com.aayushatharva.brotli4j.encoder.Encoder$Mode', - 'com.aayushatharva.brotli4j.encoder.Encoder$Parameters', - - // from io.netty.logging.CommonsLoggerFactory (netty) - 'org.apache.commons.logging.Log', - 'org.apache.commons.logging.LogFactory', - - // from Log4j (deliberate, Netty will fallback to Log4j 2) - 'org.apache.log4j.Level', - 'org.apache.log4j.Logger', - - // from io.netty.handler.ssl.util.BouncyCastleSelfSignedCertGenerator (netty) - 'org.bouncycastle.cert.X509v3CertificateBuilder', - 'org.bouncycastle.cert.jcajce.JcaX509CertificateConverter', - 'org.bouncycastle.operator.jcajce.JcaContentSignerBuilder', - 'org.bouncycastle.openssl.PEMEncryptedKeyPair', - 'org.bouncycastle.openssl.PEMParser', - 'org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter', - 'org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder', - 'org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder', - 'org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo', - - // from io.netty.handler.ssl.JettyNpnSslEngine (netty) - 'org.eclipse.jetty.npn.NextProtoNego$ClientProvider', - 'org.eclipse.jetty.npn.NextProtoNego$ServerProvider', - 'org.eclipse.jetty.npn.NextProtoNego', - - // from io.netty.handler.codec.marshalling.ChannelBufferByteInput (netty) - 'org.jboss.marshalling.ByteInput', - - // from io.netty.handler.codec.marshalling.ChannelBufferByteOutput (netty) - 'org.jboss.marshalling.ByteOutput', - - // from io.netty.handler.codec.marshalling.CompatibleMarshallingEncoder (netty) - 'org.jboss.marshalling.Marshaller', - - // from io.netty.handler.codec.marshalling.ContextBoundUnmarshallerProvider (netty) - 'org.jboss.marshalling.MarshallerFactory', - 'org.jboss.marshalling.MarshallingConfiguration', - 'org.jboss.marshalling.Unmarshaller', - - // from io.netty.util.internal.logging.InternalLoggerFactory (netty) - it's optional - 'org.slf4j.helpers.FormattingTuple', - 'org.slf4j.helpers.MessageFormatter', - 'org.slf4j.Logger', - 'org.slf4j.LoggerFactory', - 'org.slf4j.spi.LocationAwareLogger', - - 'com.google.protobuf.nano.CodedOutputByteBufferNano', - 'com.google.protobuf.nano.MessageNano', - 'com.ning.compress.BufferRecycler', - 'com.ning.compress.lzf.ChunkDecoder', - 'com.ning.compress.lzf.ChunkEncoder', - 'com.ning.compress.lzf.LZFChunk', - 'com.ning.compress.lzf.LZFEncoder', - 'com.ning.compress.lzf.util.ChunkDecoderFactory', - 'com.ning.compress.lzf.util.ChunkEncoderFactory', - 'lzma.sdk.lzma.Encoder', - 'net.jpountz.lz4.LZ4Compressor', - 'net.jpountz.lz4.LZ4Factory', - 'net.jpountz.lz4.LZ4FastDecompressor', - 'net.jpountz.xxhash.XXHash32', - 'net.jpountz.xxhash.XXHashFactory', - 'org.eclipse.jetty.alpn.ALPN$ClientProvider', - 'org.eclipse.jetty.alpn.ALPN$ServerProvider', - 'org.eclipse.jetty.alpn.ALPN', - - 'org.conscrypt.AllocatedBuffer', - 'org.conscrypt.BufferAllocator', - 'org.conscrypt.Conscrypt', - 'org.conscrypt.HandshakeListener', - - // from io.netty.handler.ssl.OpenSslEngine (netty) - 'io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod', - 'io.netty.internal.tcnative.AsyncTask', - 'io.netty.internal.tcnative.Buffer', - 'io.netty.internal.tcnative.CertificateCompressionAlgo', - 'io.netty.internal.tcnative.Library', - 'io.netty.internal.tcnative.ResultCallback', - 'io.netty.internal.tcnative.SSL', - 'io.netty.internal.tcnative.SSLContext', - 'io.netty.internal.tcnative.SSLPrivateKeyMethod', - 'io.netty.internal.tcnative.SSLSession', - 'io.netty.internal.tcnative.SSLSessionCache', - 'io.netty.internal.tcnative.CertificateCallback', - 'io.netty.internal.tcnative.CertificateVerifier', - 'io.netty.internal.tcnative.SessionTicketKey', - 'io.netty.internal.tcnative.SniHostNameMatcher', - - 'reactor.blockhound.BlockHound$Builder', - 'reactor.blockhound.integration.BlockHoundIntegration' - ) - - ignoreViolations( - - 'io.netty.util.internal.PlatformDependent0', - 'io.netty.util.internal.PlatformDependent0$1', - 'io.netty.util.internal.PlatformDependent0$2', - 'io.netty.util.internal.PlatformDependent0$3', - 'io.netty.util.internal.PlatformDependent0$4', - 'io.netty.util.internal.PlatformDependent0$6', - 'io.netty.util.internal.shaded.org.jctools.queues.BaseLinkedQueueConsumerNodeRef', - 'io.netty.util.internal.shaded.org.jctools.queues.BaseLinkedQueueProducerNodeRef', - 'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields', - 'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields', - 'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields', - 'io.netty.util.internal.shaded.org.jctools.queues.LinkedQueueNode', - 'io.netty.util.internal.shaded.org.jctools.queues.MpmcArrayQueueConsumerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.MpmcArrayQueueProducerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField', - 'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueConsumerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueProducerIndexField', - 'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueProducerLimitField', - 'io.netty.util.internal.shaded.org.jctools.util.UnsafeAccess', - 'io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess', - 'io.netty.util.internal.shaded.org.jctools.util.UnsafeLongArrayAccess', - - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator', - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$1', - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$2', - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$3', - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$4', - 'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$5' - ) -} diff --git a/plugins/transport-nio/licenses/netty-LICENSE.txt b/plugins/transport-nio/licenses/netty-LICENSE.txt deleted file mode 100644 index d645695673349..0000000000000 --- a/plugins/transport-nio/licenses/netty-LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/plugins/transport-nio/licenses/netty-NOTICE.txt b/plugins/transport-nio/licenses/netty-NOTICE.txt deleted file mode 100644 index 5bbf91a14de23..0000000000000 --- a/plugins/transport-nio/licenses/netty-NOTICE.txt +++ /dev/null @@ -1,116 +0,0 @@ - - The Netty Project - ================= - -Please visit the Netty web site for more information: - - * http://netty.io/ - -Copyright 2011 The Netty Project - -The Netty Project 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. - -Also, please refer to each LICENSE..txt file, which is located in -the 'license' directory of the distribution file, for the license terms of the -components that this product depends on. - -------------------------------------------------------------------------------- -This product contains the extensions to Java Collections Framework which has -been derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene: - - * LICENSE: - * license/LICENSE.jsr166y.txt (Public Domain) - * HOMEPAGE: - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/ - * http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/ - -This product contains a modified version of Robert Harder's Public Domain -Base64 Encoder and Decoder, which can be obtained at: - - * LICENSE: - * license/LICENSE.base64.txt (Public Domain) - * HOMEPAGE: - * http://iharder.sourceforge.net/current/java/base64/ - -This product contains a modified version of 'JZlib', a re-implementation of -zlib in pure Java, which can be obtained at: - - * LICENSE: - * license/LICENSE.jzlib.txt (BSD Style License) - * HOMEPAGE: - * http://www.jcraft.com/jzlib/ - -This product contains a modified version of 'Webbit', a Java event based -WebSocket and HTTP server: - - * LICENSE: - * license/LICENSE.webbit.txt (BSD License) - * HOMEPAGE: - * https://github.com/joewalnes/webbit - -This product optionally depends on 'Protocol Buffers', Google's data -interchange format, which can be obtained at: - - * LICENSE: - * license/LICENSE.protobuf.txt (New BSD License) - * HOMEPAGE: - * http://code.google.com/p/protobuf/ - -This product optionally depends on 'Bouncy Castle Crypto APIs' to generate -a temporary self-signed X.509 certificate when the JVM does not provide the -equivalent functionality. It can be obtained at: - - * LICENSE: - * license/LICENSE.bouncycastle.txt (MIT License) - * HOMEPAGE: - * http://www.bouncycastle.org/ - -This product optionally depends on 'SLF4J', a simple logging facade for Java, -which can be obtained at: - - * LICENSE: - * license/LICENSE.slf4j.txt (MIT License) - * HOMEPAGE: - * http://www.slf4j.org/ - -This product optionally depends on 'Apache Commons Logging', a logging -framework, which can be obtained at: - - * LICENSE: - * license/LICENSE.commons-logging.txt (Apache License 2.0) - * HOMEPAGE: - * http://commons.apache.org/logging/ - -This product optionally depends on 'Apache Log4J', a logging framework, -which can be obtained at: - - * LICENSE: - * license/LICENSE.log4j.txt (Apache License 2.0) - * HOMEPAGE: - * http://logging.apache.org/log4j/ - -This product optionally depends on 'JBoss Logging', a logging framework, -which can be obtained at: - - * LICENSE: - * license/LICENSE.jboss-logging.txt (GNU LGPL 2.1) - * HOMEPAGE: - * http://anonsvn.jboss.org/repos/common/common-logging-spi/ - -This product optionally depends on 'Apache Felix', an open source OSGi -framework implementation, which can be obtained at: - - * LICENSE: - * license/LICENSE.felix.txt (Apache License 2.0) - * HOMEPAGE: - * http://felix.apache.org/ diff --git a/plugins/transport-nio/licenses/netty-buffer-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-buffer-4.1.117.Final.jar.sha1 deleted file mode 100644 index 9d10d066cb497..0000000000000 --- a/plugins/transport-nio/licenses/netty-buffer-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -022b4cc28194cb23671274499229e0ef35028fbd \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-codec-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-codec-4.1.117.Final.jar.sha1 deleted file mode 100644 index 2ac134b2057fb..0000000000000 --- a/plugins/transport-nio/licenses/netty-codec-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -2831d3431ed93d9c0b64b1c0cce2ced4737539aa \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-codec-http-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-codec-http-4.1.117.Final.jar.sha1 deleted file mode 100644 index 222d2e3acc03e..0000000000000 --- a/plugins/transport-nio/licenses/netty-codec-http-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -5a0f8cd908b8b09b2cd1d39c1d2086a4d12e6029 \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-common-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-common-4.1.117.Final.jar.sha1 deleted file mode 100644 index b399dfc5a6b14..0000000000000 --- a/plugins/transport-nio/licenses/netty-common-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -9e074a4382f56b37f3b9ee1fc21d53e7af58ec9d \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-handler-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-handler-4.1.117.Final.jar.sha1 deleted file mode 100644 index 0c06e7a876610..0000000000000 --- a/plugins/transport-nio/licenses/netty-handler-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -db14cd99515f8c98a3f2a347718e59f14d85c503 \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-resolver-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-resolver-4.1.117.Final.jar.sha1 deleted file mode 100644 index 390e9268d0b61..0000000000000 --- a/plugins/transport-nio/licenses/netty-resolver-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -581b37489a03162f473264b65f53d504269a74b0 \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-transport-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-transport-4.1.117.Final.jar.sha1 deleted file mode 100644 index ef3a353eeb56c..0000000000000 --- a/plugins/transport-nio/licenses/netty-transport-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -f81d72962bd134d8d8e11b514321134fa5fd0ce6 \ No newline at end of file diff --git a/plugins/transport-nio/licenses/netty-transport-native-unix-common-4.1.117.Final.jar.sha1 b/plugins/transport-nio/licenses/netty-transport-native-unix-common-4.1.117.Final.jar.sha1 deleted file mode 100644 index 792339131bf29..0000000000000 --- a/plugins/transport-nio/licenses/netty-transport-native-unix-common-4.1.117.Final.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -684f2316ff2b2171babbc17c95ac3bd97f5f091e \ No newline at end of file diff --git a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/NioIntegTestCase.java b/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/NioIntegTestCase.java deleted file mode 100644 index 7bf662f6fbc78..0000000000000 --- a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/NioIntegTestCase.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch; - -import org.opensearch.common.network.NetworkModule; -import org.opensearch.common.settings.Settings; -import org.opensearch.plugins.Plugin; -import org.opensearch.test.OpenSearchIntegTestCase; -import org.opensearch.transport.nio.NioTransportPlugin; - -import java.util.Collection; -import java.util.Collections; - -public abstract class NioIntegTestCase extends OpenSearchIntegTestCase { - - @Override - protected boolean ignoreExternalCluster() { - return true; - } - - @Override - protected boolean addMockTransportService() { - return false; - } - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal)); - // randomize nio settings - if (randomBoolean()) { - builder.put(NioTransportPlugin.NIO_WORKER_COUNT.getKey(), random().nextInt(3) + 1); - builder.put(NioTransportPlugin.NIO_HTTP_WORKER_COUNT.getKey(), random().nextInt(3) + 1); - } - builder.put(NetworkModule.TRANSPORT_TYPE_KEY, NioTransportPlugin.NIO_TRANSPORT_NAME); - builder.put(NetworkModule.HTTP_TYPE_KEY, NioTransportPlugin.NIO_HTTP_TRANSPORT_NAME); - return builder.build(); - } - - @Override - protected Collection> nodePlugins() { - return Collections.singletonList(NioTransportPlugin.class); - } - -} diff --git a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/http/nio/NioPipeliningIT.java b/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/http/nio/NioPipeliningIT.java deleted file mode 100644 index c4541e3b1c7d3..0000000000000 --- a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/http/nio/NioPipeliningIT.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.NioIntegTestCase; -import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.test.OpenSearchIntegTestCase.ClusterScope; -import org.opensearch.test.OpenSearchIntegTestCase.Scope; - -import java.util.Collection; -import java.util.Locale; - -import io.netty.handler.codec.http.FullHttpResponse; - -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - -@ClusterScope(scope = Scope.TEST, supportsDedicatedMasters = false, numDataNodes = 1) -public class NioPipeliningIT extends NioIntegTestCase { - - @Override - protected boolean addMockHttpTransport() { - return false; // enable http - } - - public void testThatNioHttpServerSupportsPipelining() throws Exception { - String[] requests = new String[] { "/", "/_nodes/stats", "/", "/_cluster/state", "/" }; - - HttpServerTransport httpServerTransport = internalCluster().getInstance(HttpServerTransport.class); - TransportAddress[] boundAddresses = httpServerTransport.boundAddress().boundAddresses(); - TransportAddress transportAddress = randomFrom(boundAddresses); - - try (NioHttpClient client = NioHttpClient.http()) { - Collection responses = client.get(transportAddress.address(), requests); - assertThat(responses, hasSize(5)); - - Collection opaqueIds = NioHttpClient.returnOpaqueIds(responses); - assertOpaqueIdsInOrder(opaqueIds); - } - } - - private void assertOpaqueIdsInOrder(Collection opaqueIds) { - // check if opaque ids are monotonically increasing - int i = 0; - String msg = String.format(Locale.ROOT, "Expected list of opaque ids to be monotonically increasing, got [%s]", opaqueIds); - for (String opaqueId : opaqueIds) { - assertThat(msg, opaqueId, is(String.valueOf(i++))); - } - } - -} diff --git a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/transport/nio/NioTransportLoggingIT.java b/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/transport/nio/NioTransportLoggingIT.java deleted file mode 100644 index 2be7730cff9e9..0000000000000 --- a/plugins/transport-nio/src/internalClusterTest/java/org/opensearch/transport/nio/NioTransportLoggingIT.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.opensearch.NioIntegTestCase; -import org.opensearch.action.admin.cluster.node.hotthreads.NodesHotThreadsRequest; -import org.opensearch.test.InternalTestCluster; -import org.opensearch.test.MockLogAppender; -import org.opensearch.test.OpenSearchIntegTestCase; -import org.opensearch.test.junit.annotations.TestLogging; -import org.opensearch.transport.TcpTransport; -import org.opensearch.transport.TransportLogger; - -import java.io.IOException; - -@OpenSearchIntegTestCase.ClusterScope(numDataNodes = 2, scope = OpenSearchIntegTestCase.Scope.TEST) -public class NioTransportLoggingIT extends NioIntegTestCase { - - private MockLogAppender appender; - - public void setUp() throws Exception { - super.setUp(); - appender = MockLogAppender.createForLoggers(LogManager.getLogger(TransportLogger.class), LogManager.getLogger(TcpTransport.class)); - } - - public void tearDown() throws Exception { - appender.close(); - super.tearDown(); - } - - @TestLogging(value = "org.opensearch.transport.TransportLogger:trace", reason = "to ensure we log network events on TRACE level") - public void testLoggingHandler() { - final String writePattern = ".*\\[length: \\d+" - + ", request id: \\d+" - + ", type: request" - + ", version: .*" - + ", action: cluster:monitor/nodes/hot_threads\\[n\\]\\]" - + " WRITE: \\d+B"; - final MockLogAppender.LoggingExpectation writeExpectation = new MockLogAppender.PatternSeenEventExpectation( - "hot threads request", - TransportLogger.class.getCanonicalName(), - Level.TRACE, - writePattern - ); - - final String readPattern = ".*\\[length: \\d+" - + ", request id: \\d+" - + ", type: request" - + ", version: .*" - + ", action: cluster:monitor/nodes/hot_threads\\[n\\]\\]" - + " READ: \\d+B"; - - final MockLogAppender.LoggingExpectation readExpectation = new MockLogAppender.PatternSeenEventExpectation( - "hot threads request", - TransportLogger.class.getCanonicalName(), - Level.TRACE, - readPattern - ); - - appender.addExpectation(writeExpectation); - appender.addExpectation(readExpectation); - client().admin().cluster().nodesHotThreads(new NodesHotThreadsRequest()).actionGet(); - appender.assertAllExpectationsMatched(); - } - - @TestLogging(value = "org.opensearch.transport.TcpTransport:DEBUG", reason = "to ensure we log connection events on DEBUG level") - public void testConnectionLogging() throws IOException { - appender.addExpectation( - new MockLogAppender.PatternSeenEventExpectation( - "open connection log", - TcpTransport.class.getCanonicalName(), - Level.DEBUG, - ".*opened transport connection \\[[1-9][0-9]*\\] to .*" - ) - ); - appender.addExpectation( - new MockLogAppender.PatternSeenEventExpectation( - "close connection log", - TcpTransport.class.getCanonicalName(), - Level.DEBUG, - ".*closed transport connection \\[[1-9][0-9]*\\] to .* with age \\[[0-9]+ms\\].*" - ) - ); - - final String nodeName = internalCluster().startNode(); - internalCluster().stopRandomNode(InternalTestCluster.nameFilter(nodeName)); - - appender.assertAllExpectationsMatched(); - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ByteBufUtils.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ByteBufUtils.java deleted file mode 100644 index d6665607af5d3..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ByteBufUtils.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.BytesRefIterator; -import org.opensearch.core.common.bytes.BytesArray; -import org.opensearch.core.common.bytes.BytesReference; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; - -class ByteBufUtils { - - /** - * Turns the given BytesReference into a ByteBuf. Note: the returned ByteBuf will reference the internal - * pages of the BytesReference. Don't free the bytes of reference before the ByteBuf goes out of scope. - */ - static ByteBuf toByteBuf(final BytesReference reference) { - if (reference.length() == 0) { - return Unpooled.EMPTY_BUFFER; - } - final BytesRefIterator iterator = reference.iterator(); - // usually we have one, two, or three components from the header, the message, and a buffer - final List buffers = new ArrayList<>(3); - try { - BytesRef slice; - while ((slice = iterator.next()) != null) { - buffers.add(Unpooled.wrappedBuffer(slice.bytes, slice.offset, slice.length)); - } - - if (buffers.size() == 1) { - return buffers.get(0); - } else { - CompositeByteBuf composite = Unpooled.compositeBuffer(buffers.size()); - composite.addComponents(true, buffers); - return composite; - } - } catch (IOException ex) { - throw new AssertionError("no IO happens here", ex); - } - } - - static BytesReference toBytesReference(final ByteBuf buffer) { - final int readableBytes = buffer.readableBytes(); - if (readableBytes == 0) { - return BytesArray.EMPTY; - } else if (buffer.hasArray()) { - return new BytesArray(buffer.array(), buffer.arrayOffset() + buffer.readerIndex(), readableBytes); - } else { - final ByteBuffer[] byteBuffers = buffer.nioBuffers(); - return BytesReference.fromByteBuffers(byteBuffers); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpReadWriteHandler.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpReadWriteHandler.java deleted file mode 100644 index 6438cca9cc33d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpReadWriteHandler.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.common.Nullable; -import org.opensearch.common.unit.TimeValue; -import org.opensearch.http.HttpHandlingSettings; -import org.opensearch.http.HttpPipelinedRequest; -import org.opensearch.http.HttpPipelinedResponse; -import org.opensearch.http.HttpReadTimeoutException; -import org.opensearch.nio.FlushOperation; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.NioChannelHandler; -import org.opensearch.nio.SocketChannelContext; -import org.opensearch.nio.TaskScheduler; -import org.opensearch.nio.WriteOperation; - -import javax.net.ssl.SSLEngine; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.LongSupplier; - -import io.netty.channel.ChannelHandler; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.http.HttpContentCompressor; -import io.netty.handler.codec.http.HttpContentDecompressor; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.ssl.SslHandler; - -public class HttpReadWriteHandler implements NioChannelHandler { - - private final NettyAdaptor adaptor; - private final NioHttpChannel nioHttpChannel; - private final NioHttpServerTransport transport; - private final TaskScheduler taskScheduler; - private final LongSupplier nanoClock; - private final long readTimeoutNanos; - private boolean channelActive = false; - private boolean requestSinceReadTimeoutTrigger = false; - private int inFlightRequests = 0; - - public HttpReadWriteHandler( - NioHttpChannel nioHttpChannel, - NioHttpServerTransport transport, - HttpHandlingSettings settings, - TaskScheduler taskScheduler, - LongSupplier nanoClock - ) { - this( - nioHttpChannel, - transport, - settings, - taskScheduler, - nanoClock, - null, /* no header verifier */ - new HttpContentDecompressor(), - null /* no SSL/TLS */ - ); - } - - HttpReadWriteHandler( - NioHttpChannel nioHttpChannel, - NioHttpServerTransport transport, - HttpHandlingSettings settings, - TaskScheduler taskScheduler, - LongSupplier nanoClock, - @Nullable ChannelHandler headerVerifier, - ChannelHandler decompressor, - @Nullable SSLEngine sslEngine - ) { - this.nioHttpChannel = nioHttpChannel; - this.transport = transport; - this.taskScheduler = taskScheduler; - this.nanoClock = nanoClock; - this.readTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(settings.getReadTimeoutMillis()); - - List handlers = new ArrayList<>(8); - - SslHandler sslHandler = null; - if (sslEngine != null) { - sslHandler = new SslHandler(sslEngine); - } - - HttpRequestDecoder decoder = new HttpRequestDecoder( - settings.getMaxInitialLineLength(), - settings.getMaxHeaderSize(), - settings.getMaxChunkSize() - ); - decoder.setCumulator(ByteToMessageDecoder.COMPOSITE_CUMULATOR); - handlers.add(decoder); - if (headerVerifier != null) { - handlers.add(headerVerifier); - } - handlers.add(decompressor); - handlers.add(new HttpResponseEncoder()); - handlers.add(new HttpObjectAggregator(settings.getMaxContentLength())); - if (settings.isCompression()) { - handlers.add(new HttpContentCompressor(settings.getCompressionLevel())); - } - handlers.add(new NioHttpRequestCreator()); - handlers.add(new NioHttpResponseCreator()); - handlers.add(new NioHttpPipeliningHandler(transport.getLogger(), settings.getPipeliningMaxEvents())); - - adaptor = new NettyAdaptor(sslHandler, handlers.toArray(new ChannelHandler[0])); - adaptor.addCloseListener((v, e) -> nioHttpChannel.close()); - } - - @Override - public void channelActive() { - channelActive = true; - if (readTimeoutNanos > 0) { - scheduleReadTimeout(); - } - } - - @Override - public int consumeReads(InboundChannelBuffer channelBuffer) { - assert channelActive : "channelActive should have been called"; - int bytesConsumed = adaptor.read(channelBuffer.sliceAndRetainPagesTo(channelBuffer.getIndex())); - Object message; - while ((message = adaptor.pollInboundMessage()) != null) { - ++inFlightRequests; - requestSinceReadTimeoutTrigger = true; - handleRequest(message); - } - - return bytesConsumed; - } - - @Override - public WriteOperation createWriteOperation(SocketChannelContext context, Object message, BiConsumer listener) { - assert assertMessageTypes(message); - return new HttpWriteOperation(context, (HttpPipelinedResponse) message, listener); - } - - @Override - public List writeToBytes(WriteOperation writeOperation) { - assert assertMessageTypes(writeOperation.getObject()); - assert channelActive : "channelActive should have been called"; - --inFlightRequests; - assert inFlightRequests >= 0 : "Inflight requests should never drop below zero, found: " + inFlightRequests; - adaptor.write(writeOperation); - return pollFlushOperations(); - } - - @Override - public List pollFlushOperations() { - ArrayList copiedOperations = new ArrayList<>(adaptor.getOutboundCount()); - FlushOperation flushOperation; - while ((flushOperation = adaptor.pollOutboundOperation()) != null) { - copiedOperations.add(flushOperation); - } - return copiedOperations; - } - - @Override - public boolean closeNow() { - return false; - } - - @Override - public void close() throws IOException { - try { - adaptor.close(); - } catch (Exception e) { - throw new IOException(e); - } - } - - private void handleRequest(Object msg) { - final HttpPipelinedRequest pipelinedRequest = (HttpPipelinedRequest) msg; - boolean success = false; - try { - transport.incomingRequest(pipelinedRequest, nioHttpChannel); - success = true; - } finally { - if (success == false) { - pipelinedRequest.release(); - } - } - } - - private void maybeReadTimeout() { - if (requestSinceReadTimeoutTrigger == false && inFlightRequests == 0) { - transport.onException(nioHttpChannel, new HttpReadTimeoutException(TimeValue.nsecToMSec(readTimeoutNanos))); - } else { - requestSinceReadTimeoutTrigger = false; - scheduleReadTimeout(); - } - } - - private void scheduleReadTimeout() { - taskScheduler.scheduleAtRelativeTime(this::maybeReadTimeout, nanoClock.getAsLong() + readTimeoutNanos); - } - - private static boolean assertMessageTypes(Object message) { - assert message instanceof HttpPipelinedResponse : "This channel only supports messages that are of type: " - + HttpPipelinedResponse.class - + ". Found type: " - + message.getClass() - + "."; - assert ((HttpPipelinedResponse) message).getDelegateRequest() instanceof NioHttpResponse - : "This channel only pipelined responses with a delegate of type: " - + NioHttpResponse.class - + ". Found type: " - + ((HttpPipelinedResponse) message).getDelegateRequest().getClass() - + "."; - return true; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpWriteOperation.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpWriteOperation.java deleted file mode 100644 index f1aa880ee0da6..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/HttpWriteOperation.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.http.HttpPipelinedResponse; -import org.opensearch.nio.SocketChannelContext; -import org.opensearch.nio.WriteOperation; - -import java.util.function.BiConsumer; - -public class HttpWriteOperation implements WriteOperation { - - private final SocketChannelContext channelContext; - private final HttpPipelinedResponse response; - private final BiConsumer listener; - - HttpWriteOperation(SocketChannelContext channelContext, HttpPipelinedResponse response, BiConsumer listener) { - this.channelContext = channelContext; - this.response = response; - this.listener = listener; - } - - @Override - public BiConsumer getListener() { - return listener; - } - - @Override - public SocketChannelContext getChannel() { - return channelContext; - } - - @Override - public HttpPipelinedResponse getObject() { - return response; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyAdaptor.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyAdaptor.java deleted file mode 100644 index 426690b4b696d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyAdaptor.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.ExceptionsHelper; -import org.opensearch.common.Nullable; -import org.opensearch.nio.FlushOperation; -import org.opensearch.nio.Page; -import org.opensearch.nio.WriteOperation; - -import java.nio.ByteBuffer; -import java.util.LinkedList; -import java.util.function.BiConsumer; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.ssl.SslHandler; - -class NettyAdaptor { - - private final EmbeddedChannel nettyChannel; - private final LinkedList flushOperations = new LinkedList<>(); - - NettyAdaptor(ChannelHandler... handlers) { - this(null, handlers); - } - - NettyAdaptor(@Nullable SslHandler sslHandler, ChannelHandler... handlers) { - this.nettyChannel = new EmbeddedChannel(); - - nettyChannel.pipeline().addLast("write_captor", new ChannelOutboundHandlerAdapter() { - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { - // This is a little tricky. The embedded channel will complete the promise once it writes the message - // to its outbound buffer. We do not want to complete the promise until the message is sent. So we - // intercept the promise and pass a different promise back to the rest of the pipeline. - - try { - ByteBuf message = (ByteBuf) msg; - promise.addListener((f) -> message.release()); - NettyListener listener = NettyListener.fromChannelPromise(promise); - flushOperations.add(new FlushOperation(message.nioBuffers(), listener)); - } catch (Exception e) { - promise.setFailure(e); - } - } - }); - if (sslHandler != null) { - nettyChannel.pipeline().addAfter("write_captor", "ssl_handler", sslHandler); - } - nettyChannel.pipeline().addLast(handlers); - } - - public void close() throws Exception { - assert flushOperations.isEmpty() : "Should close outbound operations before calling close"; - - final SslHandler sslHandler = (SslHandler) nettyChannel.pipeline().get("ssl_handler"); - if (sslHandler != null) { - // The nettyChannel.close() or sslHandler.closeOutbound() futures will block indefinitely, - // removing the handler instead from the channel. - nettyChannel.pipeline().remove(sslHandler); - } - - ChannelFuture closeFuture = nettyChannel.close(); - // This should be safe as we are not a real network channel - closeFuture.await(); - if (closeFuture.isSuccess() == false) { - Throwable cause = closeFuture.cause(); - ExceptionsHelper.maybeDieOnAnotherThread(cause); - throw (Exception) cause; - } - } - - public void addCloseListener(BiConsumer listener) { - nettyChannel.closeFuture().addListener(f -> { - if (f.isSuccess()) { - listener.accept(null, null); - } else { - final Throwable cause = f.cause(); - ExceptionsHelper.maybeDieOnAnotherThread(cause); - assert cause instanceof Exception; - listener.accept(null, (Exception) cause); - } - }); - } - - public int read(ByteBuffer[] buffers) { - ByteBuf byteBuf = Unpooled.wrappedBuffer(buffers); - int initialReaderIndex = byteBuf.readerIndex(); - nettyChannel.writeInbound(byteBuf); - return byteBuf.readerIndex() - initialReaderIndex; - } - - public int read(Page[] pages) { - ByteBuf byteBuf = PagedByteBuf.byteBufFromPages(pages); - int readableBytes = byteBuf.readableBytes(); - nettyChannel.writeInbound(byteBuf); - return readableBytes; - } - - public Object pollInboundMessage() { - return nettyChannel.readInbound(); - } - - public void write(WriteOperation writeOperation) { - nettyChannel.writeAndFlush(writeOperation.getObject(), NettyListener.fromBiConsumer(writeOperation.getListener(), nettyChannel)); - } - - public FlushOperation pollOutboundOperation() { - return flushOperations.pollFirst(); - } - - public int getOutboundCount() { - return flushOperations.size(); - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyListener.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyListener.java deleted file mode 100644 index e939dbc07e471..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NettyListener.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.ExceptionsHelper; -import org.opensearch.common.util.concurrent.FutureUtils; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.BiConsumer; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelPromise; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; - -/** - * This is an {@link BiConsumer} that interfaces with netty code. It wraps a netty promise and will - * complete that promise when accept is called. It delegates the normal promise methods to the underlying - * promise. - */ -public class NettyListener implements BiConsumer, ChannelPromise { - - private final ChannelPromise promise; - - private NettyListener(ChannelPromise promise) { - this.promise = promise; - } - - @Override - public void accept(Void v, Exception exception) { - if (exception == null) { - promise.setSuccess(); - } else { - promise.setFailure(exception); - } - } - - @Override - public Channel channel() { - return promise.channel(); - } - - @Override - public ChannelPromise setSuccess(Void result) { - return promise.setSuccess(result); - } - - @Override - public boolean trySuccess(Void result) { - return promise.trySuccess(result); - } - - @Override - public ChannelPromise setSuccess() { - return promise.setSuccess(); - } - - @Override - public boolean trySuccess() { - return promise.trySuccess(); - } - - @Override - public ChannelPromise setFailure(Throwable cause) { - return promise.setFailure(cause); - } - - @Override - public boolean tryFailure(Throwable cause) { - return promise.tryFailure(cause); - } - - @Override - public boolean setUncancellable() { - return promise.setUncancellable(); - } - - @Override - public boolean isSuccess() { - return promise.isSuccess(); - } - - @Override - public boolean isCancellable() { - return promise.isCancellable(); - } - - @Override - public Throwable cause() { - return promise.cause(); - } - - @Override - public ChannelPromise addListener(GenericFutureListener> listener) { - return promise.addListener(listener); - } - - @Override - @SafeVarargs - @SuppressWarnings("varargs") - public final ChannelPromise addListeners(GenericFutureListener>... listeners) { - return promise.addListeners(listeners); - } - - @Override - public ChannelPromise removeListener(GenericFutureListener> listener) { - return promise.removeListener(listener); - } - - @Override - @SafeVarargs - @SuppressWarnings("varargs") - public final ChannelPromise removeListeners(GenericFutureListener>... listeners) { - return promise.removeListeners(listeners); - } - - @Override - public ChannelPromise sync() throws InterruptedException { - return promise.sync(); - } - - @Override - public ChannelPromise syncUninterruptibly() { - return promise.syncUninterruptibly(); - } - - @Override - public ChannelPromise await() throws InterruptedException { - return promise.await(); - } - - @Override - public ChannelPromise awaitUninterruptibly() { - return promise.awaitUninterruptibly(); - } - - @Override - public boolean await(long timeout, TimeUnit unit) throws InterruptedException { - return promise.await(timeout, unit); - } - - @Override - public boolean await(long timeoutMillis) throws InterruptedException { - return promise.await(timeoutMillis); - } - - @Override - public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { - return promise.awaitUninterruptibly(timeout, unit); - } - - @Override - public boolean awaitUninterruptibly(long timeoutMillis) { - return promise.awaitUninterruptibly(timeoutMillis); - } - - @Override - public Void getNow() { - return promise.getNow(); - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return FutureUtils.cancel(promise); - } - - @Override - public boolean isCancelled() { - return promise.isCancelled(); - } - - @Override - public boolean isDone() { - return promise.isDone(); - } - - @Override - public Void get() throws InterruptedException, ExecutionException { - return promise.get(); - } - - @Override - public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return promise.get(timeout, unit); - } - - @Override - public boolean isVoid() { - return promise.isVoid(); - } - - @Override - public ChannelPromise unvoid() { - return promise.unvoid(); - } - - public static NettyListener fromBiConsumer(BiConsumer biConsumer, Channel channel) { - if (biConsumer instanceof NettyListener) { - return (NettyListener) biConsumer; - } else { - ChannelPromise channelPromise = channel.newPromise(); - channelPromise.addListener(f -> { - Throwable cause = f.cause(); - if (cause == null) { - biConsumer.accept(null, null); - } else { - if (cause instanceof Error) { - ExceptionsHelper.maybeDieOnAnotherThread(cause); - biConsumer.accept(null, new Exception(cause)); - } else { - biConsumer.accept(null, (Exception) cause); - } - } - }); - - return new NettyListener(channelPromise); - } - } - - public static NettyListener fromChannelPromise(ChannelPromise channelPromise) { - if (channelPromise instanceof NettyListener) { - return (NettyListener) channelPromise; - } else { - return new NettyListener(channelPromise); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpChannel.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpChannel.java deleted file mode 100644 index 6c341b07f433d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpChannel.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.core.action.ActionListener; -import org.opensearch.http.HttpChannel; -import org.opensearch.http.HttpResponse; -import org.opensearch.nio.NioSocketChannel; - -import java.nio.channels.SocketChannel; - -public class NioHttpChannel extends NioSocketChannel implements HttpChannel { - - public NioHttpChannel(SocketChannel socketChannel) { - super(socketChannel); - } - - public void sendResponse(HttpResponse response, ActionListener listener) { - getContext().sendMessage(response, ActionListener.toBiConsumer(listener)); - } - - @Override - public void addCloseListener(ActionListener listener) { - addCloseListener(ActionListener.toBiConsumer(listener)); - } - - @Override - public String toString() { - return "NioHttpChannel{" + "localAddress=" + getLocalAddress() + ", remoteAddress=" + getRemoteAddress() + '}'; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpPipeliningHandler.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpPipeliningHandler.java deleted file mode 100644 index ed1e95b1b8c69..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpPipeliningHandler.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.apache.logging.log4j.Logger; -import org.opensearch.common.collect.Tuple; -import org.opensearch.http.HttpPipelinedRequest; -import org.opensearch.http.HttpPipelinedResponse; -import org.opensearch.http.HttpPipeliningAggregator; -import org.opensearch.http.HttpRequest; - -import java.nio.channels.ClosedChannelException; -import java.util.List; - -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; - -/** - * Implements HTTP pipelining ordering, ensuring that responses are completely served in the same order as their corresponding requests. - */ -public class NioHttpPipeliningHandler extends ChannelDuplexHandler { - - private final Logger logger; - private final HttpPipeliningAggregator aggregator; - - /** - * Construct a new pipelining handler; this handler should be used downstream of HTTP decoding/aggregation. - * - * @param logger for logging unexpected errors - * @param maxEventsHeld the maximum number of channel events that will be retained prior to aborting the channel connection; this is - * required as events cannot queue up indefinitely - */ - public NioHttpPipeliningHandler(Logger logger, final int maxEventsHeld) { - this.logger = logger; - this.aggregator = new HttpPipeliningAggregator<>(maxEventsHeld); - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, final Object msg) { - assert msg instanceof HttpRequest : "Invalid message type: " + msg.getClass(); - HttpPipelinedRequest pipelinedRequest = aggregator.read((HttpRequest) msg); - ctx.fireChannelRead(pipelinedRequest); - } - - @Override - public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) { - assert msg instanceof HttpPipelinedResponse : "Invalid message type: " + msg.getClass(); - HttpPipelinedResponse response = (HttpPipelinedResponse) msg; - boolean success = false; - try { - NettyListener listener = NettyListener.fromChannelPromise(promise); - List> readyResponses = aggregator.write(response, listener); - success = true; - for (Tuple responseToWrite : readyResponses) { - ctx.write(responseToWrite.v1().getDelegateRequest(), responseToWrite.v2()); - } - } catch (IllegalStateException e) { - ctx.channel().close(); - } finally { - if (success == false) { - promise.setFailure(new ClosedChannelException()); - } - } - } - - @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) { - List> inflightResponses = aggregator.removeAllInflightResponses(); - - if (inflightResponses.isEmpty() == false) { - ClosedChannelException closedChannelException = new ClosedChannelException(); - for (Tuple inflightResponse : inflightResponses) { - try { - inflightResponse.v2().setFailure(closedChannelException); - } catch (RuntimeException e) { - logger.error("unexpected error while releasing pipelined http responses", e); - } - } - } - ctx.close(promise); - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequest.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequest.java deleted file mode 100644 index 5abd6f2710198..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequest.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.http.HttpRequest; -import org.opensearch.rest.RestRequest; - -import java.util.AbstractMap; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.cookie.Cookie; -import io.netty.handler.codec.http.cookie.ServerCookieDecoder; -import io.netty.handler.codec.http.cookie.ServerCookieEncoder; - -public class NioHttpRequest implements HttpRequest { - - private final FullHttpRequest request; - private final BytesReference content; - private final HttpHeadersMap headers; - private final AtomicBoolean released; - private final Exception inboundException; - private final boolean pooled; - - NioHttpRequest(FullHttpRequest request) { - this( - request, - new HttpHeadersMap(request.headers()), - new AtomicBoolean(false), - true, - ByteBufUtils.toBytesReference(request.content()) - ); - } - - NioHttpRequest(FullHttpRequest request, Exception inboundException) { - this( - request, - new HttpHeadersMap(request.headers()), - new AtomicBoolean(false), - true, - ByteBufUtils.toBytesReference(request.content()), - inboundException - ); - } - - private NioHttpRequest( - FullHttpRequest request, - HttpHeadersMap headers, - AtomicBoolean released, - boolean pooled, - BytesReference content - ) { - this(request, headers, released, pooled, content, null); - } - - private NioHttpRequest( - FullHttpRequest request, - HttpHeadersMap headers, - AtomicBoolean released, - boolean pooled, - BytesReference content, - Exception inboundException - ) { - this.request = request; - this.headers = headers; - this.content = content; - this.pooled = pooled; - this.released = released; - this.inboundException = inboundException; - } - - @Override - public RestRequest.Method method() { - HttpMethod httpMethod = request.method(); - if (httpMethod == HttpMethod.GET) return RestRequest.Method.GET; - - if (httpMethod == HttpMethod.POST) return RestRequest.Method.POST; - - if (httpMethod == HttpMethod.PUT) return RestRequest.Method.PUT; - - if (httpMethod == HttpMethod.DELETE) return RestRequest.Method.DELETE; - - if (httpMethod == HttpMethod.HEAD) { - return RestRequest.Method.HEAD; - } - - if (httpMethod == HttpMethod.OPTIONS) { - return RestRequest.Method.OPTIONS; - } - - if (httpMethod == HttpMethod.PATCH) { - return RestRequest.Method.PATCH; - } - - if (httpMethod == HttpMethod.TRACE) { - return RestRequest.Method.TRACE; - } - - if (httpMethod == HttpMethod.CONNECT) { - return RestRequest.Method.CONNECT; - } - - throw new IllegalArgumentException("Unexpected http method: " + httpMethod); - } - - @Override - public String uri() { - return request.uri(); - } - - @Override - public BytesReference content() { - assert released.get() == false; - return content; - } - - @Override - public void release() { - if (pooled && released.compareAndSet(false, true)) { - request.release(); - } - } - - @Override - public HttpRequest releaseAndCopy() { - assert released.get() == false; - if (pooled == false) { - return this; - } - try { - final ByteBuf copiedContent = Unpooled.copiedBuffer(request.content()); - return new NioHttpRequest( - new DefaultFullHttpRequest( - request.protocolVersion(), - request.method(), - request.uri(), - copiedContent, - request.headers(), - request.trailingHeaders() - ), - headers, - new AtomicBoolean(false), - false, - ByteBufUtils.toBytesReference(copiedContent) - ); - } finally { - release(); - } - } - - @Override - public final Map> getHeaders() { - return headers; - } - - @Override - public List strictCookies() { - String cookieString = request.headers().get(HttpHeaderNames.COOKIE); - if (cookieString != null) { - Set cookies = ServerCookieDecoder.STRICT.decode(cookieString); - if (!cookies.isEmpty()) { - return ServerCookieEncoder.STRICT.encode(cookies); - } - } - return Collections.emptyList(); - } - - @Override - public HttpVersion protocolVersion() { - if (request.protocolVersion().equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_0)) { - return HttpRequest.HttpVersion.HTTP_1_0; - } else if (request.protocolVersion().equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_1)) { - return HttpRequest.HttpVersion.HTTP_1_1; - } else { - throw new IllegalArgumentException("Unexpected http protocol version: " + request.protocolVersion()); - } - } - - @Override - public HttpRequest removeHeader(String header) { - HttpHeaders headersWithoutContentTypeHeader = new DefaultHttpHeaders(); - headersWithoutContentTypeHeader.add(request.headers()); - headersWithoutContentTypeHeader.remove(header); - HttpHeaders trailingHeaders = new DefaultHttpHeaders(); - trailingHeaders.add(request.trailingHeaders()); - trailingHeaders.remove(header); - FullHttpRequest requestWithoutHeader = new DefaultFullHttpRequest( - request.protocolVersion(), - request.method(), - request.uri(), - request.content(), - headersWithoutContentTypeHeader, - trailingHeaders - ); - return new NioHttpRequest(requestWithoutHeader, new HttpHeadersMap(requestWithoutHeader.headers()), released, pooled, content); - } - - @Override - public NioHttpResponse createResponse(RestStatus status, BytesReference content) { - return new NioHttpResponse(request.headers(), request.protocolVersion(), status, content); - } - - @Override - public Exception getInboundException() { - return inboundException; - } - - public FullHttpRequest nettyRequest() { - return request; - } - - /** - * A wrapper of {@link HttpHeaders} that implements a map to prevent copying unnecessarily. This class does not support modifications - * and due to the underlying implementation, it performs case insensitive lookups of key to values. - *

- * It is important to note that this implementation does have some downsides in that each invocation of the - * {@link #values()} and {@link #entrySet()} methods will perform a copy of the values in the HttpHeaders rather than returning a - * view of the underlying values. - */ - private static class HttpHeadersMap implements Map> { - - private final HttpHeaders httpHeaders; - - private HttpHeadersMap(HttpHeaders httpHeaders) { - this.httpHeaders = httpHeaders; - } - - @Override - public int size() { - return httpHeaders.size(); - } - - @Override - public boolean isEmpty() { - return httpHeaders.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return key instanceof String && httpHeaders.contains((String) key); - } - - @Override - public boolean containsValue(Object value) { - return value instanceof List && httpHeaders.names().stream().map(httpHeaders::getAll).anyMatch(value::equals); - } - - @Override - public List get(Object key) { - return key instanceof String ? httpHeaders.getAll((String) key) : null; - } - - @Override - public List put(String key, List value) { - throw new UnsupportedOperationException("modifications are not supported"); - } - - @Override - public List remove(Object key) { - throw new UnsupportedOperationException("modifications are not supported"); - } - - @Override - public void putAll(Map> m) { - throw new UnsupportedOperationException("modifications are not supported"); - } - - @Override - public void clear() { - throw new UnsupportedOperationException("modifications are not supported"); - } - - @Override - public Set keySet() { - return httpHeaders.names(); - } - - @Override - public Collection> values() { - return httpHeaders.names().stream().map(k -> Collections.unmodifiableList(httpHeaders.getAll(k))).collect(Collectors.toList()); - } - - @Override - public Set>> entrySet() { - return httpHeaders.names() - .stream() - .map(k -> new AbstractMap.SimpleImmutableEntry<>(k, httpHeaders.getAll(k))) - .collect(Collectors.toSet()); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequestCreator.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequestCreator.java deleted file mode 100644 index 27e43f4eef386..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpRequestCreator.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.ExceptionsHelper; - -import java.util.List; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageDecoder; -import io.netty.handler.codec.http.FullHttpRequest; - -@ChannelHandler.Sharable -class NioHttpRequestCreator extends MessageToMessageDecoder { - - @Override - protected void decode(ChannelHandlerContext ctx, FullHttpRequest msg, List out) { - if (msg.decoderResult().isFailure()) { - final Throwable cause = msg.decoderResult().cause(); - final Exception nonError; - if (cause instanceof Error) { - ExceptionsHelper.maybeDieOnAnotherThread(cause); - nonError = new Exception(cause); - } else { - nonError = (Exception) cause; - } - out.add(new NioHttpRequest(msg.retain(), nonError)); - } else { - out.add(new NioHttpRequest(msg.retain())); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponse.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponse.java deleted file mode 100644 index c349ee14bc70f..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponse.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.http.HttpResponse; - -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; - -public class NioHttpResponse extends DefaultFullHttpResponse implements HttpResponse { - - private final HttpHeaders requestHeaders; - - NioHttpResponse(HttpHeaders requestHeaders, HttpVersion version, RestStatus status, BytesReference content) { - super(version, HttpResponseStatus.valueOf(status.getStatus()), ByteBufUtils.toByteBuf(content)); - this.requestHeaders = requestHeaders; - } - - @Override - public void addHeader(String name, String value) { - headers().add(name, value); - } - - @Override - public boolean containsHeader(String name) { - return headers().contains(name); - } - - public HttpHeaders requestHeaders() { - return requestHeaders; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponseCreator.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponseCreator.java deleted file mode 100644 index 93822b57ec40f..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpResponseCreator.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.common.Booleans; -import org.opensearch.monitor.jvm.JvmInfo; - -import java.util.List; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageEncoder; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.HttpResponse; - -/** - * Split up large responses to prevent batch compression or other CPU intensive operations down the pipeline. - */ -@ChannelHandler.Sharable -public class NioHttpResponseCreator extends MessageToMessageEncoder { - - private static final String DO_NOT_SPLIT = "opensearch.unsafe.do_not_split_http_responses"; - - private static final boolean DO_NOT_SPLIT_HTTP_RESPONSES; - private static final int SPLIT_THRESHOLD; - - static { - DO_NOT_SPLIT_HTTP_RESPONSES = Booleans.parseBoolean(System.getProperty(DO_NOT_SPLIT), false); - // Netty will add some header bytes if it compresses this message. So we downsize slightly. - SPLIT_THRESHOLD = (int) (suggestedMaxAllocationSize() * 0.99); - } - - @Override - protected void encode(ChannelHandlerContext ctx, NioHttpResponse msg, List out) { - if (DO_NOT_SPLIT_HTTP_RESPONSES || msg.content().readableBytes() <= SPLIT_THRESHOLD) { - out.add(msg.retain()); - } else { - HttpResponse response = new DefaultHttpResponse(msg.protocolVersion(), msg.status(), msg.headers()); - out.add(response); - ByteBuf content = msg.content(); - while (content.readableBytes() > SPLIT_THRESHOLD) { - out.add(new DefaultHttpContent(content.readRetainedSlice(SPLIT_THRESHOLD))); - } - out.add(new DefaultLastHttpContent(content.readRetainedSlice(content.readableBytes()))); - } - } - - private static long suggestedMaxAllocationSize() { - return Math.max(Math.max(JvmInfo.jvmInfo().getG1RegionSize(), 0) >> 2, 256 * 1024); - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerChannel.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerChannel.java deleted file mode 100644 index 2c47bf009f2a3..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerChannel.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.core.action.ActionListener; -import org.opensearch.http.HttpServerChannel; -import org.opensearch.nio.NioServerSocketChannel; - -import java.nio.channels.ServerSocketChannel; - -public class NioHttpServerChannel extends NioServerSocketChannel implements HttpServerChannel { - - public NioHttpServerChannel(ServerSocketChannel serverSocketChannel) { - super(serverSocketChannel); - } - - @Override - public void addCloseListener(ActionListener listener) { - addCloseListener(ActionListener.toBiConsumer(listener)); - } - - @Override - public String toString() { - return "NioHttpServerChannel{localAddress=" + getLocalAddress() + "}"; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerTransport.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerTransport.java deleted file mode 100644 index 9eca5fc87120d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/NioHttpServerTransport.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.OpenSearchException; -import org.opensearch.action.support.PlainActionFuture; -import org.opensearch.common.Nullable; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.BigArrays; -import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.unit.ByteSizeValue; -import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.http.AbstractHttpServerTransport; -import org.opensearch.http.HttpChannel; -import org.opensearch.http.HttpServerChannel; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.http.nio.ssl.SslUtils; -import org.opensearch.nio.BytesChannelContext; -import org.opensearch.nio.ChannelFactory; -import org.opensearch.nio.Config; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.NioGroup; -import org.opensearch.nio.NioSelector; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.nio.ServerChannelContext; -import org.opensearch.nio.SocketChannelContext; -import org.opensearch.plugins.SecureHttpTransportSettingsProvider; -import org.opensearch.telemetry.tracing.Tracer; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TransportAdapterProvider; -import org.opensearch.transport.nio.NioGroupFactory; -import org.opensearch.transport.nio.PageAllocator; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.HttpContentDecompressor; - -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_CHUNK_SIZE; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_HEADER_SIZE; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_INITIAL_LINE_LENGTH; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_KEEP_ALIVE; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_KEEP_COUNT; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_KEEP_IDLE; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_KEEP_INTERVAL; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_NO_DELAY; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_REUSE_ADDRESS; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_TCP_SEND_BUFFER_SIZE; -import static org.opensearch.http.HttpTransportSettings.SETTING_PIPELINING_MAX_EVENTS; - -public class NioHttpServerTransport extends AbstractHttpServerTransport { - private static final Logger logger = LogManager.getLogger(NioHttpServerTransport.class); - - public static final String REQUEST_HEADER_VERIFIER = SecureHttpTransportSettingsProvider.REQUEST_HEADER_VERIFIER; - public static final String REQUEST_DECOMPRESSOR = SecureHttpTransportSettingsProvider.REQUEST_DECOMPRESSOR; - - protected final PageAllocator pageAllocator; - private final NioGroupFactory nioGroupFactory; - - protected final boolean tcpNoDelay; - protected final boolean tcpKeepAlive; - protected final int tcpKeepIdle; - protected final int tcpKeepInterval; - protected final int tcpKeepCount; - protected final boolean reuseAddress; - protected final int tcpSendBufferSize; - protected final int tcpReceiveBufferSize; - - private volatile NioGroup nioGroup; - private ChannelFactory channelFactory; - private final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider; - - public NioHttpServerTransport( - Settings settings, - NetworkService networkService, - BigArrays bigArrays, - PageCacheRecycler pageCacheRecycler, - ThreadPool threadPool, - NamedXContentRegistry xContentRegistry, - Dispatcher dispatcher, - NioGroupFactory nioGroupFactory, - ClusterSettings clusterSettings, - Tracer tracer - ) { - this( - settings, - networkService, - bigArrays, - pageCacheRecycler, - threadPool, - xContentRegistry, - dispatcher, - nioGroupFactory, - clusterSettings, - null, - tracer - ); - } - - public NioHttpServerTransport( - Settings settings, - NetworkService networkService, - BigArrays bigArrays, - PageCacheRecycler pageCacheRecycler, - ThreadPool threadPool, - NamedXContentRegistry xContentRegistry, - Dispatcher dispatcher, - NioGroupFactory nioGroupFactory, - ClusterSettings clusterSettings, - @Nullable SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider, - Tracer tracer - ) { - super(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, tracer); - this.pageAllocator = new PageAllocator(pageCacheRecycler); - this.nioGroupFactory = nioGroupFactory; - - ByteSizeValue maxChunkSize = SETTING_HTTP_MAX_CHUNK_SIZE.get(settings); - ByteSizeValue maxHeaderSize = SETTING_HTTP_MAX_HEADER_SIZE.get(settings); - ByteSizeValue maxInitialLineLength = SETTING_HTTP_MAX_INITIAL_LINE_LENGTH.get(settings); - int pipeliningMaxEvents = SETTING_PIPELINING_MAX_EVENTS.get(settings); - - this.tcpNoDelay = SETTING_HTTP_TCP_NO_DELAY.get(settings); - this.tcpKeepAlive = SETTING_HTTP_TCP_KEEP_ALIVE.get(settings); - this.tcpKeepIdle = SETTING_HTTP_TCP_KEEP_IDLE.get(settings); - this.tcpKeepInterval = SETTING_HTTP_TCP_KEEP_INTERVAL.get(settings); - this.tcpKeepCount = SETTING_HTTP_TCP_KEEP_COUNT.get(settings); - this.reuseAddress = SETTING_HTTP_TCP_REUSE_ADDRESS.get(settings); - this.tcpSendBufferSize = Math.toIntExact(SETTING_HTTP_TCP_SEND_BUFFER_SIZE.get(settings).getBytes()); - this.tcpReceiveBufferSize = Math.toIntExact(SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE.get(settings).getBytes()); - this.secureHttpTransportSettingsProvider = secureHttpTransportSettingsProvider; - - logger.debug( - "using max_chunk_size[{}], max_header_size[{}], max_initial_line_length[{}], max_content_length[{}]," - + " pipelining_max_events[{}]", - maxChunkSize, - maxHeaderSize, - maxInitialLineLength, - maxContentLength, - pipeliningMaxEvents - ); - } - - public Logger getLogger() { - return logger; - } - - @Override - protected void doStart() { - boolean success = false; - try { - nioGroup = nioGroupFactory.getHttpGroup(); - channelFactory = channelFactory(); - bindServer(); - success = true; - } catch (IOException e) { - throw new OpenSearchException(e); - } finally { - if (success == false) { - doStop(); // otherwise we leak threads since we never moved to started - } - } - } - - @Override - protected void stopInternal() { - try { - nioGroup.close(); - } catch (Exception e) { - logger.warn("unexpected exception while stopping nio group", e); - } - } - - @Override - protected HttpServerChannel bind(InetSocketAddress socketAddress) throws IOException { - NioHttpServerChannel httpServerChannel = nioGroup.bindServerChannel(socketAddress, channelFactory); - PlainActionFuture future = PlainActionFuture.newFuture(); - httpServerChannel.addBindListener(ActionListener.toBiConsumer(future)); - future.actionGet(); - return httpServerChannel; - } - - protected ChannelFactory channelFactory() throws SSLException { - return new HttpChannelFactory(secureHttpTransportSettingsProvider); - } - - protected void acceptChannel(NioSocketChannel socketChannel) { - super.serverAcceptedChannel((HttpChannel) socketChannel); - } - - private class HttpChannelFactory extends ChannelFactory { - private final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider; - private final ChannelInboundHandlerAdapter headerVerifier; - private final TransportAdapterProvider decompressorProvider; - - private HttpChannelFactory(@Nullable SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider) { - super( - tcpNoDelay, - tcpKeepAlive, - tcpKeepIdle, - tcpKeepInterval, - tcpKeepCount, - reuseAddress, - tcpSendBufferSize, - tcpReceiveBufferSize - ); - this.secureHttpTransportSettingsProvider = secureHttpTransportSettingsProvider; - - final List headerVerifiers = getHeaderVerifiers(secureHttpTransportSettingsProvider); - final Optional> decompressorProviderOpt = getDecompressorProvider( - secureHttpTransportSettingsProvider - ); - - // There could be multiple request decompressor providers configured, using the first one - decompressorProviderOpt.ifPresent(p -> logger.debug("Using request decompressor provider: {}", p)); - - if (headerVerifiers.size() > 1) { - throw new IllegalArgumentException( - "Cannot have more than one header verifier configured, supplied " + headerVerifiers.size() - ); - } - - this.headerVerifier = headerVerifiers.isEmpty() ? null : headerVerifiers.get(0); - this.decompressorProvider = decompressorProviderOpt.orElseGet(() -> new TransportAdapterProvider() { - @Override - public String name() { - return REQUEST_DECOMPRESSOR; - } - - @Override - public Optional create(Settings settings, HttpServerTransport transport, Class adapterClass) { - return Optional.empty(); - } - }); - - } - - private List getHeaderVerifiers( - @Nullable SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider - ) { - if (secureHttpTransportSettingsProvider == null) { - return Collections.emptyList(); - } - - return secureHttpTransportSettingsProvider.getHttpTransportAdapterProviders(settings) - .stream() - .filter(p -> REQUEST_HEADER_VERIFIER.equalsIgnoreCase(p.name())) - .map(p -> p.create(settings, NioHttpServerTransport.this, ChannelInboundHandlerAdapter.class)) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - } - - private Optional> getDecompressorProvider( - @Nullable SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider - ) { - if (secureHttpTransportSettingsProvider == null) { - return Optional.empty(); - } - - return secureHttpTransportSettingsProvider.getHttpTransportAdapterProviders(settings) - .stream() - .filter(p -> REQUEST_DECOMPRESSOR.equalsIgnoreCase(p.name())) - .findFirst(); - } - - @Override - public NioHttpChannel createChannel(NioSelector selector, SocketChannel channel, Config.Socket socketConfig) throws IOException { - SSLEngine engine = null; - if (secureHttpTransportSettingsProvider != null) { - engine = secureHttpTransportSettingsProvider.buildSecureHttpServerEngine(settings, NioHttpServerTransport.this) - .orElseGet(SslUtils::createDefaultServerSSLEngine); - } - - NioHttpChannel httpChannel = new NioHttpChannel(channel); - HttpReadWriteHandler handler = new HttpReadWriteHandler( - httpChannel, - NioHttpServerTransport.this, - handlingSettings, - selector.getTaskScheduler(), - threadPool::relativeTimeInMillis, - headerVerifier, - decompressorProvider.create(settings, NioHttpServerTransport.this, ChannelInboundHandlerAdapter.class) - .orElseGet(HttpContentDecompressor::new), - engine - ); - Consumer exceptionHandler = (e) -> onException(httpChannel, e); - SocketChannelContext context = new BytesChannelContext( - httpChannel, - selector, - socketConfig, - exceptionHandler, - handler, - new InboundChannelBuffer(pageAllocator) - ); - httpChannel.setContext(context); - return httpChannel; - } - - @Override - public NioHttpServerChannel createServerChannel( - NioSelector selector, - ServerSocketChannel channel, - Config.ServerSocket socketConfig - ) { - NioHttpServerChannel httpServerChannel = new NioHttpServerChannel(channel); - Consumer exceptionHandler = (e) -> onServerException(httpServerChannel, e); - Consumer acceptor = NioHttpServerTransport.this::acceptChannel; - ServerChannelContext context = new ServerChannelContext( - httpServerChannel, - this, - selector, - socketConfig, - acceptor, - exceptionHandler - ); - httpServerChannel.setContext(context); - return httpServerChannel; - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/PagedByteBuf.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/PagedByteBuf.java deleted file mode 100644 index 221b2104e9904..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/PagedByteBuf.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.nio.Page; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.buffer.UnpooledHeapByteBuf; - -public class PagedByteBuf extends UnpooledHeapByteBuf { - - private final Runnable releasable; - - private PagedByteBuf(byte[] array, Runnable releasable) { - super(UnpooledByteBufAllocator.DEFAULT, array, array.length); - this.releasable = releasable; - } - - static ByteBuf byteBufFromPages(Page[] pages) { - int componentCount = pages.length; - if (componentCount == 0) { - return Unpooled.EMPTY_BUFFER; - } else if (componentCount == 1) { - return byteBufFromPage(pages[0]); - } else { - int maxComponents = Math.max(16, componentCount); - final List components = new ArrayList<>(componentCount); - for (Page page : pages) { - components.add(byteBufFromPage(page)); - } - return new CompositeByteBuf(UnpooledByteBufAllocator.DEFAULT, false, maxComponents, components); - } - } - - private static ByteBuf byteBufFromPage(Page page) { - ByteBuffer buffer = page.byteBuffer(); - assert buffer.isDirect() == false && buffer.hasArray() : "Must be a heap buffer with an array"; - int offset = buffer.arrayOffset() + buffer.position(); - PagedByteBuf newByteBuf = new PagedByteBuf(buffer.array(), page::close); - return newByteBuf.slice(offset, buffer.remaining()); - } - - @Override - protected void deallocate() { - try { - super.deallocate(); - } finally { - releasable.run(); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/SslUtils.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/SslUtils.java deleted file mode 100644 index afd67f9799273..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/SslUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ -package org.opensearch.http.nio.ssl; - -import org.opensearch.OpenSearchSecurityException; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; - -import java.security.NoSuchAlgorithmException; - -public class SslUtils { - private static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" }; - - private SslUtils() { - - } - - public static SSLEngine createDefaultServerSSLEngine() { - try { - final SSLEngine engine = SSLContext.getDefault().createSSLEngine(); - engine.setEnabledProtocols(DEFAULT_SSL_PROTOCOLS); - engine.setUseClientMode(false); - return engine; - } catch (final NoSuchAlgorithmException ex) { - throw new OpenSearchSecurityException("Unable to initialize default server SSL engine", ex); - } - } - - public static SSLEngine createDefaultClientSSLEngine() { - try { - final SSLEngine engine = SSLContext.getDefault().createSSLEngine(); - engine.setEnabledProtocols(DEFAULT_SSL_PROTOCOLS); - engine.setUseClientMode(true); - return engine; - } catch (final NoSuchAlgorithmException ex) { - throw new OpenSearchSecurityException("Unable to initialize default client SSL engine", ex); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/package-info.java b/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/package-info.java deleted file mode 100644 index a67f8247ebd4d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/http/nio/ssl/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/** - * SSL supporting utility classes - */ -package org.opensearch.http.nio.ssl; diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioGroupFactory.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioGroupFactory.java deleted file mode 100644 index 8463c81a3492b..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioGroupFactory.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.message.ParameterizedMessage; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.concurrent.AbstractRefCounted; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.nio.ChannelFactory; -import org.opensearch.nio.EventHandler; -import org.opensearch.nio.NioGroup; -import org.opensearch.nio.NioSelectorGroup; -import org.opensearch.nio.NioServerSocketChannel; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.transport.TcpTransport; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.InetSocketAddress; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.opensearch.common.util.concurrent.OpenSearchExecutors.daemonThreadFactory; - -/** - * Creates and returns {@link NioSelectorGroup} instances. It will return a shared group for - * both {@link #getHttpGroup()} and {@link #getTransportGroup()} if - * {@link NioTransportPlugin#NIO_HTTP_WORKER_COUNT} is configured to be 0. If that setting is not 0, then it - * will return a different group in the {@link #getHttpGroup()} call. - */ -public final class NioGroupFactory { - - private final Logger logger; - private final Settings settings; - private final int httpWorkerCount; - - private RefCountedNioGroup refCountedGroup; - - public NioGroupFactory(Settings settings, Logger logger) { - this.logger = logger; - this.settings = settings; - this.httpWorkerCount = NioTransportPlugin.NIO_HTTP_WORKER_COUNT.get(settings); - } - - public Settings getSettings() { - return settings; - } - - public synchronized NioGroup getTransportGroup() throws IOException { - return getGenericGroup(); - } - - public synchronized NioGroup getHttpGroup() throws IOException { - if (httpWorkerCount == 0) { - return getGenericGroup(); - } else { - return new NioSelectorGroup( - daemonThreadFactory(this.settings, HttpServerTransport.HTTP_SERVER_WORKER_THREAD_NAME_PREFIX), - httpWorkerCount, - (s) -> new EventHandler(this::onException, s) - ); - } - } - - private NioGroup getGenericGroup() throws IOException { - if (refCountedGroup == null) { - ThreadFactory threadFactory = daemonThreadFactory(this.settings, TcpTransport.TRANSPORT_WORKER_THREAD_NAME_PREFIX); - NioSelectorGroup nioGroup = new NioSelectorGroup( - threadFactory, - NioTransportPlugin.NIO_WORKER_COUNT.get(settings), - (s) -> new EventHandler(this::onException, s) - ); - this.refCountedGroup = new RefCountedNioGroup(nioGroup); - return new WrappedNioGroup(refCountedGroup); - } else { - refCountedGroup.incRef(); - return new WrappedNioGroup(refCountedGroup); - } - } - - private void onException(Exception exception) { - logger.warn( - new ParameterizedMessage("exception caught on transport layer [thread={}]", Thread.currentThread().getName()), - exception - ); - } - - private static class RefCountedNioGroup extends AbstractRefCounted implements NioGroup { - - public static final String NAME = "ref-counted-nio-group"; - private final NioSelectorGroup nioGroup; - - private RefCountedNioGroup(NioSelectorGroup nioGroup) { - super(NAME); - this.nioGroup = nioGroup; - } - - @Override - protected void closeInternal() { - try { - nioGroup.close(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - @Override - public S bindServerChannel(InetSocketAddress address, ChannelFactory factory) - throws IOException { - return nioGroup.bindServerChannel(address, factory); - } - - @Override - public S openChannel(InetSocketAddress address, ChannelFactory factory) throws IOException { - return nioGroup.openChannel(address, factory); - } - - @Override - public void close() throws IOException { - throw new UnsupportedOperationException("Should not close. Instead use decRef call."); - } - } - - /** - * Wraps the {@link RefCountedNioGroup}. Calls {@link RefCountedNioGroup#decRef()} on close. After close, - * this wrapped instance can no longer be used. - */ - private static class WrappedNioGroup implements NioGroup { - - private final RefCountedNioGroup refCountedNioGroup; - - private final AtomicBoolean isOpen = new AtomicBoolean(true); - - private WrappedNioGroup(RefCountedNioGroup refCountedNioGroup) { - this.refCountedNioGroup = refCountedNioGroup; - } - - public S bindServerChannel(InetSocketAddress address, ChannelFactory factory) - throws IOException { - ensureOpen(); - return refCountedNioGroup.bindServerChannel(address, factory); - } - - public S openChannel(InetSocketAddress address, ChannelFactory factory) throws IOException { - ensureOpen(); - return refCountedNioGroup.openChannel(address, factory); - } - - @Override - public void close() { - if (isOpen.compareAndSet(true, false)) { - refCountedNioGroup.decRef(); - } - } - - private void ensureOpen() { - if (isOpen.get() == false) { - throw new IllegalStateException("NioGroup is closed."); - } - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpChannel.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpChannel.java deleted file mode 100644 index 3aa02d11dfd75..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpChannel.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.transport.TcpChannel; - -import java.nio.channels.SocketChannel; - -public class NioTcpChannel extends NioSocketChannel implements TcpChannel { - - private final boolean isServer; - private final String profile; - private final ChannelStats stats = new ChannelStats(); - - public NioTcpChannel(boolean isServer, String profile, SocketChannel socketChannel) { - super(socketChannel); - this.isServer = isServer; - this.profile = profile; - } - - public void sendMessage(BytesReference reference, ActionListener listener) { - getContext().sendMessage(BytesReference.toByteBuffers(reference), ActionListener.toBiConsumer(listener)); - } - - @Override - public boolean isServerChannel() { - return isServer; - } - - @Override - public String getProfile() { - return profile; - } - - @Override - public void addCloseListener(ActionListener listener) { - addCloseListener(ActionListener.toBiConsumer(listener)); - } - - @Override - public void addConnectListener(ActionListener listener) { - addConnectListener(ActionListener.toBiConsumer(listener)); - } - - @Override - public ChannelStats getChannelStats() { - return stats; - } - - @Override - public void close() { - getContext().closeChannel(); - } - - @Override - public String toString() { - return "TcpNioSocketChannel{" + "localAddress=" + getLocalAddress() + ", remoteAddress=" + getRemoteAddress() + '}'; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpServerChannel.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpServerChannel.java deleted file mode 100644 index a0fb2ef4cfdf2..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTcpServerChannel.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.core.action.ActionListener; -import org.opensearch.nio.NioServerSocketChannel; -import org.opensearch.transport.TcpServerChannel; - -import java.nio.channels.ServerSocketChannel; - -/** - * This is an implementation of {@link NioServerSocketChannel} that adheres to the {@link TcpServerChannel} - * interface. As it is a server socket, setting SO_LINGER and sending messages is not supported. - */ -public class NioTcpServerChannel extends NioServerSocketChannel implements TcpServerChannel { - - public NioTcpServerChannel(ServerSocketChannel socketChannel) { - super(socketChannel); - } - - public void close() { - getContext().closeChannel(); - } - - @Override - public void addCloseListener(ActionListener listener) { - addCloseListener(ActionListener.toBiConsumer(listener)); - } - - @Override - public String toString() { - return "TcpNioServerSocketChannel{" + "localAddress=" + getLocalAddress() + '}'; - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransport.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransport.java deleted file mode 100644 index 55920bab4efd3..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransport.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.OpenSearchException; -import org.opensearch.Version; -import org.opensearch.action.support.PlainActionFuture; -import org.opensearch.cluster.node.DiscoveryNode; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.io.stream.NamedWriteableRegistry; -import org.opensearch.core.indices.breaker.CircuitBreakerService; -import org.opensearch.nio.BytesChannelContext; -import org.opensearch.nio.ChannelFactory; -import org.opensearch.nio.Config; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.NioGroup; -import org.opensearch.nio.NioSelector; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.nio.ServerChannelContext; -import org.opensearch.telemetry.tracing.Tracer; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.TcpTransport; -import org.opensearch.transport.TransportSettings; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Consumer; -import java.util.function.Function; - -import static org.opensearch.common.util.concurrent.ConcurrentCollections.newConcurrentMap; - -public class NioTransport extends TcpTransport { - - private static final Logger logger = LogManager.getLogger(NioTransport.class); - - protected final PageAllocator pageAllocator; - private final ConcurrentMap profileToChannelFactory = newConcurrentMap(); - private final NioGroupFactory groupFactory; - private volatile NioGroup nioGroup; - private volatile Function clientChannelFactory; - - protected NioTransport( - Settings settings, - Version version, - ThreadPool threadPool, - NetworkService networkService, - PageCacheRecycler pageCacheRecycler, - NamedWriteableRegistry namedWriteableRegistry, - CircuitBreakerService circuitBreakerService, - NioGroupFactory groupFactory, - Tracer tracer - ) { - super(settings, version, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, tracer); - this.pageAllocator = new PageAllocator(pageCacheRecycler); - this.groupFactory = groupFactory; - } - - @Override - protected NioTcpServerChannel bind(String name, InetSocketAddress address) throws IOException { - TcpChannelFactory channelFactory = this.profileToChannelFactory.get(name); - NioTcpServerChannel serverChannel = nioGroup.bindServerChannel(address, channelFactory); - PlainActionFuture future = PlainActionFuture.newFuture(); - serverChannel.addBindListener(ActionListener.toBiConsumer(future)); - future.actionGet(); - return serverChannel; - } - - @Override - protected NioTcpChannel initiateChannel(DiscoveryNode node) throws IOException { - InetSocketAddress address = node.getAddress().address(); - return nioGroup.openChannel(address, clientChannelFactory.apply(node)); - } - - @Override - protected void doStart() { - boolean success = false; - try { - nioGroup = groupFactory.getTransportGroup(); - - ProfileSettings clientProfileSettings = new ProfileSettings(settings, TransportSettings.DEFAULT_PROFILE); - clientChannelFactory = clientChannelFactoryFunction(clientProfileSettings); - - if (NetworkService.NETWORK_SERVER.get(settings)) { - // loop through all profiles and start them up, special handling for default one - for (ProfileSettings profileSettings : profileSettings) { - String profileName = profileSettings.profileName; - TcpChannelFactory factory = serverChannelFactory(profileSettings); - profileToChannelFactory.putIfAbsent(profileName, factory); - bindServer(profileSettings); - } - } - - super.doStart(); - success = true; - } catch (IOException e) { - throw new OpenSearchException(e); - } finally { - if (success == false) { - doStop(); - } - } - } - - @Override - protected void stopInternal() { - try { - nioGroup.close(); - } catch (Exception e) { - logger.warn("unexpected exception while stopping nio group", e); - } - profileToChannelFactory.clear(); - } - - protected void acceptChannel(NioSocketChannel channel) { - serverAcceptedChannel((NioTcpChannel) channel); - } - - protected TcpChannelFactory serverChannelFactory(ProfileSettings profileSettings) { - return new TcpChannelFactoryImpl(profileSettings, false); - } - - protected Function clientChannelFactoryFunction(ProfileSettings profileSettings) { - return (n) -> new TcpChannelFactoryImpl(profileSettings, true); - } - - protected abstract static class TcpChannelFactory extends ChannelFactory { - - protected TcpChannelFactory(ProfileSettings profileSettings) { - super( - profileSettings.tcpNoDelay, - profileSettings.tcpKeepAlive, - profileSettings.tcpKeepIdle, - profileSettings.tcpKeepInterval, - profileSettings.tcpKeepCount, - profileSettings.reuseAddress, - Math.toIntExact(profileSettings.sendBufferSize.getBytes()), - Math.toIntExact(profileSettings.receiveBufferSize.getBytes()) - ); - } - } - - private class TcpChannelFactoryImpl extends TcpChannelFactory { - - private final boolean isClient; - private final String profileName; - - private TcpChannelFactoryImpl(ProfileSettings profileSettings, boolean isClient) { - super(profileSettings); - this.isClient = isClient; - this.profileName = profileSettings.profileName; - } - - @Override - public NioTcpChannel createChannel(NioSelector selector, SocketChannel channel, Config.Socket socketConfig) { - NioTcpChannel nioChannel = new NioTcpChannel(isClient == false, profileName, channel); - Consumer exceptionHandler = (e) -> onException(nioChannel, e); - TcpReadWriteHandler handler = new TcpReadWriteHandler(nioChannel, pageCacheRecycler, NioTransport.this); - BytesChannelContext context = new BytesChannelContext( - nioChannel, - selector, - socketConfig, - exceptionHandler, - handler, - new InboundChannelBuffer(pageAllocator) - ); - nioChannel.setContext(context); - return nioChannel; - } - - @Override - public NioTcpServerChannel createServerChannel( - NioSelector selector, - ServerSocketChannel channel, - Config.ServerSocket socketConfig - ) { - NioTcpServerChannel nioChannel = new NioTcpServerChannel(channel); - Consumer exceptionHandler = (e) -> onServerException(nioChannel, e); - Consumer acceptor = NioTransport.this::acceptChannel; - ServerChannelContext context = new ServerChannelContext(nioChannel, this, selector, socketConfig, acceptor, exceptionHandler); - nioChannel.setContext(context); - return nioChannel; - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransportPlugin.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransportPlugin.java deleted file mode 100644 index 7707369b59120..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/NioTransportPlugin.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.Version; -import org.opensearch.common.SetOnce; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Setting; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.BigArrays; -import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.common.util.concurrent.OpenSearchExecutors; -import org.opensearch.core.common.io.stream.NamedWriteableRegistry; -import org.opensearch.core.indices.breaker.CircuitBreakerService; -import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.http.HttpServerTransport.Dispatcher; -import org.opensearch.http.nio.NioHttpServerTransport; -import org.opensearch.plugins.NetworkPlugin; -import org.opensearch.plugins.Plugin; -import org.opensearch.plugins.SecureHttpTransportSettingsProvider; -import org.opensearch.telemetry.tracing.Tracer; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.Transport; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -import static org.opensearch.common.settings.Setting.intSetting; - -public class NioTransportPlugin extends Plugin implements NetworkPlugin { - - public static final String NIO_TRANSPORT_NAME = "nio-transport"; - public static final String NIO_HTTP_TRANSPORT_NAME = "nio-http-transport"; - public static final String NIO_SECURE_HTTP_TRANSPORT_NAME = "nio-http-transport-secure"; - - private static final Logger logger = LogManager.getLogger(NioTransportPlugin.class); - - public static final Setting NIO_WORKER_COUNT = new Setting<>( - "transport.nio.worker_count", - (s) -> Integer.toString(OpenSearchExecutors.allocatedProcessors(s)), - (s) -> Setting.parseInt(s, 1, "transport.nio.worker_count"), - Setting.Property.NodeScope - ); - public static final Setting NIO_HTTP_WORKER_COUNT = intSetting("http.nio.worker_count", 0, 0, Setting.Property.NodeScope); - - private final SetOnce groupFactory = new SetOnce<>(); - - @Override - public List> getSettings() { - return Arrays.asList(NIO_HTTP_WORKER_COUNT, NIO_WORKER_COUNT); - } - - @Override - public Map> getTransports( - Settings settings, - ThreadPool threadPool, - PageCacheRecycler pageCacheRecycler, - CircuitBreakerService circuitBreakerService, - NamedWriteableRegistry namedWriteableRegistry, - NetworkService networkService, - Tracer tracer - ) { - return Collections.singletonMap( - NIO_TRANSPORT_NAME, - () -> new NioTransport( - settings, - Version.CURRENT, - threadPool, - networkService, - pageCacheRecycler, - namedWriteableRegistry, - circuitBreakerService, - getNioGroupFactory(settings), - tracer - ) - ); - } - - @Override - public Map> getHttpTransports( - Settings settings, - ThreadPool threadPool, - BigArrays bigArrays, - PageCacheRecycler pageCacheRecycler, - CircuitBreakerService circuitBreakerService, - NamedXContentRegistry xContentRegistry, - NetworkService networkService, - HttpServerTransport.Dispatcher dispatcher, - ClusterSettings clusterSettings, - Tracer tracer - ) { - return Collections.singletonMap( - NIO_HTTP_TRANSPORT_NAME, - () -> new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageCacheRecycler, - threadPool, - xContentRegistry, - dispatcher, - getNioGroupFactory(settings), - clusterSettings, - tracer - ) - ); - } - - @Override - public Map> getSecureHttpTransports( - Settings settings, - ThreadPool threadPool, - BigArrays bigArrays, - PageCacheRecycler pageCacheRecycler, - CircuitBreakerService circuitBreakerService, - NamedXContentRegistry xContentRegistry, - NetworkService networkService, - Dispatcher dispatcher, - ClusterSettings clusterSettings, - SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider, - Tracer tracer - ) { - return Collections.singletonMap( - NIO_SECURE_HTTP_TRANSPORT_NAME, - () -> new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageCacheRecycler, - threadPool, - xContentRegistry, - dispatcher, - getNioGroupFactory(settings), - clusterSettings, - secureHttpTransportSettingsProvider, - tracer - ) - ); - } - - private synchronized NioGroupFactory getNioGroupFactory(Settings settings) { - NioGroupFactory nioGroupFactory = groupFactory.get(); - if (nioGroupFactory != null) { - assert nioGroupFactory.getSettings().equals(settings) : "Different settings than originally provided"; - return nioGroupFactory; - } else { - groupFactory.set(new NioGroupFactory(settings, logger)); - return groupFactory.get(); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/PageAllocator.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/PageAllocator.java deleted file mode 100644 index 65913b58d870d..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/PageAllocator.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.common.recycler.Recycler; -import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.nio.Page; - -import java.nio.ByteBuffer; -import java.util.function.IntFunction; - -public class PageAllocator implements IntFunction { - - private static final int RECYCLE_LOWER_THRESHOLD = PageCacheRecycler.BYTE_PAGE_SIZE / 2; - - private final PageCacheRecycler recycler; - - public PageAllocator(PageCacheRecycler recycler) { - this.recycler = recycler; - } - - @Override - public Page apply(int length) { - if (length >= RECYCLE_LOWER_THRESHOLD && length <= PageCacheRecycler.BYTE_PAGE_SIZE) { - Recycler.V bytePage = recycler.bytePage(false); - return new Page(ByteBuffer.wrap(bytePage.v(), 0, length), bytePage::close); - } else { - return new Page(ByteBuffer.allocate(length), () -> {}); - } - } -} diff --git a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/TcpReadWriteHandler.java b/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/TcpReadWriteHandler.java deleted file mode 100644 index 0c90deed6411c..0000000000000 --- a/plugins/transport-nio/src/main/java/org/opensearch/transport/nio/TcpReadWriteHandler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.common.bytes.ReleasableBytesReference; -import org.opensearch.common.lease.Releasable; -import org.opensearch.common.lease.Releasables; -import org.opensearch.common.util.PageCacheRecycler; -import org.opensearch.common.util.io.IOUtils; -import org.opensearch.core.common.breaker.CircuitBreaker; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.common.bytes.CompositeBytesReference; -import org.opensearch.nio.BytesWriteHandler; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.Page; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.InboundPipeline; -import org.opensearch.transport.TcpTransport; -import org.opensearch.transport.Transport; - -import java.io.IOException; -import java.util.function.Supplier; - -public class TcpReadWriteHandler extends BytesWriteHandler { - - private final NioTcpChannel channel; - private final InboundPipeline pipeline; - - public TcpReadWriteHandler(NioTcpChannel channel, PageCacheRecycler recycler, TcpTransport transport) { - this.channel = channel; - final ThreadPool threadPool = transport.getThreadPool(); - final Supplier breaker = transport.getInflightBreaker(); - final Transport.RequestHandlers requestHandlers = transport.getRequestHandlers(); - this.pipeline = new InboundPipeline( - transport.getVersion(), - transport.getStatsTracker(), - recycler, - threadPool::relativeTimeInMillis, - breaker, - requestHandlers::getHandler, - transport::inboundMessage - ); - } - - @Override - public int consumeReads(InboundChannelBuffer channelBuffer) throws IOException { - Page[] pages = channelBuffer.sliceAndRetainPagesTo(channelBuffer.getIndex()); - BytesReference[] references = new BytesReference[pages.length]; - for (int i = 0; i < pages.length; ++i) { - references[i] = BytesReference.fromByteBuffer(pages[i].byteBuffer()); - } - Releasable releasable = () -> IOUtils.closeWhileHandlingException(pages); - try (ReleasableBytesReference reference = new ReleasableBytesReference(CompositeBytesReference.of(references), releasable)) { - pipeline.handleBytes(channel, reference); - return reference.length(); - } - } - - @Override - public void close() { - Releasables.closeWhileHandlingException(pipeline); - super.close(); - } -} diff --git a/plugins/transport-nio/src/main/plugin-metadata/plugin-security.policy b/plugins/transport-nio/src/main/plugin-metadata/plugin-security.policy deleted file mode 100644 index 767b876bf8e79..0000000000000 --- a/plugins/transport-nio/src/main/plugin-metadata/plugin-security.policy +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -grant codeBase "${codebase.opensearch-nio}" { - // opensearch-nio makes and accepts socket connections - permission java.net.SocketPermission "*", "accept,connect"; -}; - -grant codeBase "${codebase.netty-common}" { - // This should only currently be required as we use the netty http client for tests - // netty makes and accepts socket connections - permission java.net.SocketPermission "*", "accept,connect"; - // Netty sets custom classloader for some of its internal threads - permission java.lang.RuntimePermission "*", "setContextClassLoader"; -}; diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/HttpReadWriteHandlerTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/HttpReadWriteHandlerTests.java deleted file mode 100644 index a3f7a7822cd40..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/HttpReadWriteHandlerTests.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.common.settings.Settings; -import org.opensearch.common.unit.TimeValue; -import org.opensearch.core.common.bytes.BytesArray; -import org.opensearch.core.common.unit.ByteSizeValue; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.http.CorsHandler; -import org.opensearch.http.HttpChannel; -import org.opensearch.http.HttpHandlingSettings; -import org.opensearch.http.HttpPipelinedRequest; -import org.opensearch.http.HttpPipelinedResponse; -import org.opensearch.http.HttpReadTimeoutException; -import org.opensearch.http.HttpRequest; -import org.opensearch.nio.FlushOperation; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.SocketChannelContext; -import org.opensearch.nio.TaskScheduler; -import org.opensearch.rest.RestRequest; -import org.opensearch.test.OpenSearchTestCase; -import org.junit.Before; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.function.BiConsumer; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponseDecoder; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; -import org.mockito.ArgumentCaptor; - -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_READ_TIMEOUT; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class HttpReadWriteHandlerTests extends OpenSearchTestCase { - - private HttpReadWriteHandler handler; - private NioHttpChannel channel; - private NioHttpServerTransport transport; - private TaskScheduler taskScheduler; - - private final RequestEncoder requestEncoder = new RequestEncoder(); - private final ResponseDecoder responseDecoder = new ResponseDecoder(); - - @Before - public void setMocks() { - transport = mock(NioHttpServerTransport.class); - doAnswer(invocation -> { - ((HttpRequest) invocation.getArguments()[0]).releaseAndCopy(); - return null; - }).when(transport).incomingRequest(any(HttpRequest.class), any(HttpChannel.class)); - Settings settings = Settings.builder().put(SETTING_HTTP_MAX_CONTENT_LENGTH.getKey(), new ByteSizeValue(1024)).build(); - HttpHandlingSettings httpHandlingSettings = HttpHandlingSettings.fromSettings(settings); - channel = mock(NioHttpChannel.class); - taskScheduler = mock(TaskScheduler.class); - - handler = new HttpReadWriteHandler(channel, transport, httpHandlingSettings, taskScheduler, System::nanoTime); - handler.channelActive(); - } - - public void testSuccessfulDecodeHttpRequest() throws IOException { - String uri = "localhost:9090/" + randomAlphaOfLength(8); - io.netty.handler.codec.http.HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri); - - ByteBuf buf = requestEncoder.encode(httpRequest); - int slicePoint = randomInt(buf.writerIndex() - 1); - ByteBuf slicedBuf = buf.retainedSlice(0, slicePoint); - ByteBuf slicedBuf2 = buf.retainedSlice(slicePoint, buf.writerIndex() - slicePoint); - try { - handler.consumeReads(toChannelBuffer(slicedBuf)); - - verify(transport, times(0)).incomingRequest(any(HttpRequest.class), any(NioHttpChannel.class)); - - handler.consumeReads(toChannelBuffer(slicedBuf2)); - - ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(HttpRequest.class); - verify(transport).incomingRequest(requestCaptor.capture(), any(NioHttpChannel.class)); - - HttpRequest nioHttpRequest = requestCaptor.getValue(); - assertEquals(HttpRequest.HttpVersion.HTTP_1_1, nioHttpRequest.protocolVersion()); - assertEquals(RestRequest.Method.GET, nioHttpRequest.method()); - } finally { - handler.close(); - buf.release(); - slicedBuf.release(); - slicedBuf2.release(); - } - } - - public void testDecodeHttpRequestError() throws IOException { - String uri = "localhost:9090/" + randomAlphaOfLength(8); - io.netty.handler.codec.http.HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri); - - ByteBuf buf = requestEncoder.encode(httpRequest); - try { - buf.setByte(0, ' '); - buf.setByte(1, ' '); - buf.setByte(2, ' '); - - handler.consumeReads(toChannelBuffer(buf)); - - ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(HttpRequest.class); - verify(transport).incomingRequest(requestCaptor.capture(), any(NioHttpChannel.class)); - - assertNotNull(requestCaptor.getValue().getInboundException()); - assertTrue(requestCaptor.getValue().getInboundException() instanceof IllegalArgumentException); - } finally { - buf.release(); - } - } - - public void testDecodeHttpRequestContentLengthToLongGeneratesOutboundMessage() throws IOException { - String uri = "localhost:9090/" + randomAlphaOfLength(8); - io.netty.handler.codec.http.HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri, false); - HttpUtil.setContentLength(httpRequest, 1025); - HttpUtil.setKeepAlive(httpRequest, false); - - ByteBuf buf = requestEncoder.encode(httpRequest); - try { - handler.consumeReads(toChannelBuffer(buf)); - } finally { - buf.release(); - } - verify(transport, times(0)).incomingRequest(any(), any()); - - List flushOperations = handler.pollFlushOperations(); - assertFalse(flushOperations.isEmpty()); - - FlushOperation flushOperation = flushOperations.get(0); - FullHttpResponse response = responseDecoder.decode(Unpooled.wrappedBuffer(flushOperation.getBuffersToWrite())); - try { - assertEquals(HttpVersion.HTTP_1_1, response.protocolVersion()); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - - flushOperation.getListener().accept(null, null); - // Since we have keep-alive set to false, we should close the channel after the response has been - // flushed - verify(channel).close(); - } finally { - response.release(); - } - } - - @SuppressWarnings("unchecked") - public void testEncodeHttpResponse() throws IOException { - prepareHandlerForResponse(handler); - HttpPipelinedResponse httpResponse = emptyGetResponse(0); - - SocketChannelContext context = mock(SocketChannelContext.class); - HttpWriteOperation writeOperation = new HttpWriteOperation(context, httpResponse, mock(BiConsumer.class)); - List flushOperations = handler.writeToBytes(writeOperation); - FlushOperation operation = flushOperations.get(0); - FullHttpResponse response = responseDecoder.decode(Unpooled.wrappedBuffer(operation.getBuffersToWrite())); - ((ChannelPromise) operation.getListener()).setSuccess(); - try { - assertEquals(HttpResponseStatus.OK, response.status()); - assertEquals(HttpVersion.HTTP_1_1, response.protocolVersion()); - } finally { - response.release(); - } - } - - @SuppressWarnings("unchecked") - public void testReadTimeout() throws IOException { - TimeValue timeValue = TimeValue.timeValueMillis(500); - Settings settings = Settings.builder().put(SETTING_HTTP_READ_TIMEOUT.getKey(), timeValue).build(); - HttpHandlingSettings httpHandlingSettings = HttpHandlingSettings.fromSettings(settings); - - CorsHandler corsHandler = CorsHandler.disabled(); - TaskScheduler taskScheduler = new TaskScheduler(); - - Iterator timeValues = Arrays.asList(0, 2, 4, 6, 8).iterator(); - handler = new HttpReadWriteHandler(channel, transport, httpHandlingSettings, taskScheduler, timeValues::next); - handler.channelActive(); - - prepareHandlerForResponse(handler); - SocketChannelContext context = mock(SocketChannelContext.class); - HttpWriteOperation writeOperation0 = new HttpWriteOperation(context, emptyGetResponse(0), mock(BiConsumer.class)); - ((ChannelPromise) handler.writeToBytes(writeOperation0).get(0).getListener()).setSuccess(); - - taskScheduler.pollTask(timeValue.getNanos() + 1).run(); - // There was a read. Do not close. - verify(transport, times(0)).onException(eq(channel), any(HttpReadTimeoutException.class)); - - prepareHandlerForResponse(handler); - prepareHandlerForResponse(handler); - - taskScheduler.pollTask(timeValue.getNanos() + 3).run(); - // There was a read. Do not close. - verify(transport, times(0)).onException(eq(channel), any(HttpReadTimeoutException.class)); - - HttpWriteOperation writeOperation1 = new HttpWriteOperation(context, emptyGetResponse(1), mock(BiConsumer.class)); - ((ChannelPromise) handler.writeToBytes(writeOperation1).get(0).getListener()).setSuccess(); - - taskScheduler.pollTask(timeValue.getNanos() + 5).run(); - // There has not been a read, however there is still an inflight request. Do not close. - verify(transport, times(0)).onException(eq(channel), any(HttpReadTimeoutException.class)); - - HttpWriteOperation writeOperation2 = new HttpWriteOperation(context, emptyGetResponse(2), mock(BiConsumer.class)); - ((ChannelPromise) handler.writeToBytes(writeOperation2).get(0).getListener()).setSuccess(); - - taskScheduler.pollTask(timeValue.getNanos() + 7).run(); - // No reads and no inflight requests, close - verify(transport, times(1)).onException(eq(channel), any(HttpReadTimeoutException.class)); - assertNull(taskScheduler.pollTask(timeValue.getNanos() + 9)); - } - - private static HttpPipelinedResponse emptyGetResponse(int sequence) { - DefaultFullHttpRequest nettyRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); - HttpPipelinedRequest httpRequest = new HttpPipelinedRequest(sequence, new NioHttpRequest(nettyRequest)); - HttpPipelinedResponse httpResponse = httpRequest.createResponse(RestStatus.OK, BytesArray.EMPTY); - httpResponse.addHeader(HttpHeaderNames.CONTENT_LENGTH.toString(), "0"); - return httpResponse; - } - - private void prepareHandlerForResponse(HttpReadWriteHandler handler) throws IOException { - HttpMethod method = randomBoolean() ? HttpMethod.GET : HttpMethod.HEAD; - HttpVersion version = randomBoolean() ? HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1; - String uri = "http://localhost:9090/" + randomAlphaOfLength(8); - - io.netty.handler.codec.http.HttpRequest request = new DefaultFullHttpRequest(version, method, uri); - ByteBuf buf = requestEncoder.encode(request); - try { - handler.consumeReads(toChannelBuffer(buf)); - } finally { - buf.release(); - } - - ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(HttpPipelinedRequest.class); - verify(transport, atLeastOnce()).incomingRequest(requestCaptor.capture(), any(HttpChannel.class)); - - HttpRequest httpRequest = requestCaptor.getValue(); - assertNotNull(httpRequest); - assertEquals(method.name(), httpRequest.method().name()); - if (version == HttpVersion.HTTP_1_1) { - assertEquals(HttpRequest.HttpVersion.HTTP_1_1, httpRequest.protocolVersion()); - } else { - assertEquals(HttpRequest.HttpVersion.HTTP_1_0, httpRequest.protocolVersion()); - } - assertEquals(httpRequest.uri(), uri); - } - - private InboundChannelBuffer toChannelBuffer(ByteBuf buf) { - InboundChannelBuffer buffer = InboundChannelBuffer.allocatingInstance(); - int readableBytes = buf.readableBytes(); - buffer.ensureCapacity(readableBytes); - int bytesWritten = 0; - ByteBuffer[] byteBuffers = buffer.sliceBuffersTo(readableBytes); - int i = 0; - while (bytesWritten != readableBytes) { - ByteBuffer byteBuffer = byteBuffers[i++]; - int initialRemaining = byteBuffer.remaining(); - buf.readBytes(byteBuffer); - bytesWritten += initialRemaining - byteBuffer.remaining(); - } - buffer.incrementIndex(bytesWritten); - return buffer; - } - - private static final int MAX = 16 * 1024 * 1024; - - private static class RequestEncoder { - - private final EmbeddedChannel requestEncoder = new EmbeddedChannel(new HttpRequestEncoder(), new HttpObjectAggregator(MAX)); - - private ByteBuf encode(io.netty.handler.codec.http.HttpRequest httpRequest) { - requestEncoder.writeOutbound(httpRequest); - return requestEncoder.readOutbound(); - } - } - - private static class ResponseDecoder { - - private final EmbeddedChannel responseDecoder = new EmbeddedChannel(new HttpResponseDecoder(), new HttpObjectAggregator(MAX)); - - private FullHttpResponse decode(ByteBuf response) { - responseDecoder.writeInbound(response); - return responseDecoder.readInbound(); - } - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NettyAdaptorTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NettyAdaptorTests.java deleted file mode 100644 index 21634725d5279..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NettyAdaptorTests.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.nio.FlushOperation; -import org.opensearch.test.OpenSearchTestCase; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.channel.SimpleChannelInboundHandler; - -public class NettyAdaptorTests extends OpenSearchTestCase { - - public void testBasicRead() { - TenIntsToStringsHandler handler = new TenIntsToStringsHandler(); - NettyAdaptor nettyAdaptor = new NettyAdaptor(handler); - ByteBuffer message = ByteBuffer.allocate(40); - for (int i = 0; i < 10; ++i) { - message.putInt(i); - } - message.flip(); - ByteBuffer[] buffers = { message }; - assertEquals(40, nettyAdaptor.read(buffers)); - assertEquals("0123456789", handler.result); - } - - public void testBasicReadWithExcessData() { - TenIntsToStringsHandler handler = new TenIntsToStringsHandler(); - NettyAdaptor nettyAdaptor = new NettyAdaptor(handler); - ByteBuffer message = ByteBuffer.allocate(52); - for (int i = 0; i < 13; ++i) { - message.putInt(i); - } - message.flip(); - ByteBuffer[] buffers = { message }; - assertEquals(40, nettyAdaptor.read(buffers)); - assertEquals("0123456789", handler.result); - } - - public void testUncaughtReadExceptionsBubbleUp() { - NettyAdaptor nettyAdaptor = new NettyAdaptor(new TenIntsToStringsHandler()); - ByteBuffer message = ByteBuffer.allocate(40); - for (int i = 0; i < 9; ++i) { - message.putInt(i); - } - message.flip(); - ByteBuffer[] buffers = { message }; - expectThrows(IllegalStateException.class, () -> nettyAdaptor.read(buffers)); - } - - public void testWriteInsidePipelineIsCaptured() { - TenIntsToStringsHandler tenIntsToStringsHandler = new TenIntsToStringsHandler(); - PromiseCheckerHandler promiseCheckerHandler = new PromiseCheckerHandler(); - NettyAdaptor nettyAdaptor = new NettyAdaptor( - new CapitalizeWriteHandler(), - promiseCheckerHandler, - new WriteInMiddleHandler(), - tenIntsToStringsHandler - ); - byte[] bytes = "SHOULD_WRITE".getBytes(StandardCharsets.UTF_8); - ByteBuffer message = ByteBuffer.wrap(bytes); - ByteBuffer[] buffers = { message }; - assertNull(nettyAdaptor.pollOutboundOperation()); - nettyAdaptor.read(buffers); - assertFalse(tenIntsToStringsHandler.wasCalled); - FlushOperation flushOperation = nettyAdaptor.pollOutboundOperation(); - assertNotNull(flushOperation); - assertEquals("FAILED", Unpooled.wrappedBuffer(flushOperation.getBuffersToWrite()).toString(StandardCharsets.UTF_8)); - assertFalse(promiseCheckerHandler.isCalled.get()); - flushOperation.getListener().accept(null, null); - assertTrue(promiseCheckerHandler.isCalled.get()); - } - - public void testCloseListener() { - AtomicBoolean listenerCalled = new AtomicBoolean(false); - CloseChannelHandler handler = new CloseChannelHandler(); - NettyAdaptor nettyAdaptor = new NettyAdaptor(handler); - byte[] bytes = "SHOULD_CLOSE".getBytes(StandardCharsets.UTF_8); - ByteBuffer[] buffers = { ByteBuffer.wrap(bytes) }; - nettyAdaptor.addCloseListener((v, e) -> listenerCalled.set(true)); - assertFalse(listenerCalled.get()); - nettyAdaptor.read(buffers); - assertTrue(listenerCalled.get()); - - } - - private class TenIntsToStringsHandler extends SimpleChannelInboundHandler { - - private String result; - boolean wasCalled = false; - - @Override - protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { - wasCalled = true; - if (msg.readableBytes() < 10 * 4) { - throw new IllegalStateException("Must have ten ints"); - } - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < 10; ++i) { - builder.append(msg.readInt()); - } - result = builder.toString(); - } - } - - private class WriteInMiddleHandler extends ChannelInboundHandlerAdapter { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - ByteBuf buffer = (ByteBuf) msg; - String bufferString = buffer.toString(StandardCharsets.UTF_8); - if (bufferString.equals("SHOULD_WRITE")) { - ctx.writeAndFlush("Failed"); - } else { - throw new IllegalArgumentException("Only accept SHOULD_WRITE message"); - } - } - } - - private class CapitalizeWriteHandler extends ChannelOutboundHandlerAdapter { - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - String string = (String) msg; - assert string.equals("Failed") : "Should be the same was what we wrote."; - super.write(ctx, Unpooled.wrappedBuffer(string.toUpperCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8)), promise); - } - } - - private class PromiseCheckerHandler extends ChannelOutboundHandlerAdapter { - - private AtomicBoolean isCalled = new AtomicBoolean(false); - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - promise.addListener((f) -> isCalled.set(true)); - super.write(ctx, msg, promise); - } - } - - private class CloseChannelHandler extends ChannelInboundHandlerAdapter { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - ByteBuf buffer = (ByteBuf) msg; - String bufferString = buffer.toString(StandardCharsets.UTF_8); - if (bufferString.equals("SHOULD_CLOSE")) { - ctx.close(); - } else { - throw new IllegalArgumentException("Only accept SHOULD_CLOSE message"); - } - } - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpClient.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpClient.java deleted file mode 100644 index ff878eb55e411..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpClient.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.opensearch.action.support.PlainActionFuture; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.io.IOUtils; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.unit.ByteSizeUnit; -import org.opensearch.core.common.unit.ByteSizeValue; -import org.opensearch.nio.BytesChannelContext; -import org.opensearch.nio.ChannelFactory; -import org.opensearch.nio.Config; -import org.opensearch.nio.EventHandler; -import org.opensearch.nio.FlushOperation; -import org.opensearch.nio.InboundChannelBuffer; -import org.opensearch.nio.NioChannelHandler; -import org.opensearch.nio.NioSelector; -import org.opensearch.nio.NioSelectorGroup; -import org.opensearch.nio.NioServerSocketChannel; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.nio.SocketChannelContext; -import org.opensearch.nio.WriteOperation; -import org.opensearch.tasks.Task; - -import java.io.Closeable; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.InetSocketAddress; -import java.nio.channels.ServerSocketChannel; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.channel.ChannelHandler; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpContentDecompressor; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseDecoder; -import io.netty.handler.ssl.ClientAuth; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.SslHandler; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; - -import static org.opensearch.common.util.concurrent.OpenSearchExecutors.daemonThreadFactory; -import static io.netty.handler.codec.http.HttpHeaderNames.HOST; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; -import static org.junit.Assert.fail; - -/** - * Tiny helper to send http requests over nio. - */ -public class NioHttpClient implements Closeable { - - static Collection returnOpaqueIds(Collection responses) { - List list = new ArrayList<>(responses.size()); - for (HttpResponse response : responses) { - list.add(response.headers().get(Task.X_OPAQUE_ID)); - } - return list; - } - - private static final Logger logger = LogManager.getLogger(NioHttpClient.class); - - private final NioSelectorGroup nioGroup; - private final boolean secure; - - private NioHttpClient(final boolean secure) { - try { - this.secure = secure; - nioGroup = new NioSelectorGroup( - daemonThreadFactory(Settings.EMPTY, "nio-http-client"), - 1, - (s) -> new EventHandler(this::onException, s) - ); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static NioHttpClient http() { - return new NioHttpClient(false); - } - - public static NioHttpClient https() { - return new NioHttpClient(true); - } - - public Collection get(InetSocketAddress remoteAddress, String... uris) throws InterruptedException { - Collection requests = new ArrayList<>(uris.length); - for (int i = 0; i < uris.length; i++) { - final HttpRequest httpRequest = new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, uris[i]); - httpRequest.headers().add(HOST, "localhost"); - httpRequest.headers().add(Task.X_OPAQUE_ID, String.valueOf(i)); - requests.add(httpRequest); - } - return sendRequests(remoteAddress, requests); - } - - public final FullHttpResponse send(InetSocketAddress remoteAddress, FullHttpRequest httpRequest) throws InterruptedException { - Collection responses = sendRequests(remoteAddress, Collections.singleton(httpRequest)); - assert responses.size() == 1 : "expected 1 and only 1 http response"; - return responses.iterator().next(); - } - - public final NioSocketChannel connect(InetSocketAddress remoteAddress) { - ChannelFactory factory = new ClientChannelFactory( - new CountDownLatch(0), - new ArrayList<>(), - secure - ); - try { - NioSocketChannel nioSocketChannel = nioGroup.openChannel(remoteAddress, factory); - PlainActionFuture connectFuture = PlainActionFuture.newFuture(); - nioSocketChannel.addConnectListener(ActionListener.toBiConsumer(connectFuture)); - connectFuture.actionGet(); - return nioSocketChannel; - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private void onException(Exception e) { - logger.error("Exception from http client", e); - } - - private synchronized Collection sendRequests(InetSocketAddress remoteAddress, Collection requests) - throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(requests.size()); - final Collection content = Collections.synchronizedList(new ArrayList<>(requests.size())); - - ChannelFactory factory = new ClientChannelFactory(latch, content, secure); - - NioSocketChannel nioSocketChannel = null; - try { - nioSocketChannel = nioGroup.openChannel(remoteAddress, factory); - PlainActionFuture connectFuture = PlainActionFuture.newFuture(); - nioSocketChannel.addConnectListener(ActionListener.toBiConsumer(connectFuture)); - connectFuture.actionGet(); - - for (HttpRequest request : requests) { - nioSocketChannel.getContext().sendMessage(request, (v, e) -> {}); - } - if (latch.await(30L, TimeUnit.SECONDS) == false) { - fail("Failed to get all expected responses."); - } - - } catch (IOException e) { - throw new UncheckedIOException(e); - } finally { - if (nioSocketChannel != null) { - nioSocketChannel.close(); - } - } - - return content; - } - - @Override - public void close() { - IOUtils.closeWhileHandlingException(nioGroup::close); - } - - private class ClientChannelFactory extends ChannelFactory { - - private final CountDownLatch latch; - private final Collection content; - private final boolean secure; - - private ClientChannelFactory(CountDownLatch latch, Collection content, final boolean secure) { - super( - NetworkService.TCP_NO_DELAY.get(Settings.EMPTY), - NetworkService.TCP_KEEP_ALIVE.get(Settings.EMPTY), - NetworkService.TCP_KEEP_IDLE.get(Settings.EMPTY), - NetworkService.TCP_KEEP_INTERVAL.get(Settings.EMPTY), - NetworkService.TCP_KEEP_COUNT.get(Settings.EMPTY), - NetworkService.TCP_REUSE_ADDRESS.get(Settings.EMPTY), - Math.toIntExact(NetworkService.TCP_SEND_BUFFER_SIZE.get(Settings.EMPTY).getBytes()), - Math.toIntExact(NetworkService.TCP_RECEIVE_BUFFER_SIZE.get(Settings.EMPTY).getBytes()) - ); - this.latch = latch; - this.content = content; - this.secure = secure; - } - - @Override - public NioSocketChannel createChannel(NioSelector selector, java.nio.channels.SocketChannel channel, Config.Socket socketConfig) - throws IOException { - NioSocketChannel nioSocketChannel = new NioSocketChannel(channel); - HttpClientHandler handler = new HttpClientHandler(nioSocketChannel, latch, content, secure); - Consumer exceptionHandler = (e) -> { - latch.countDown(); - onException(e); - nioSocketChannel.close(); - }; - SocketChannelContext context = new BytesChannelContext( - nioSocketChannel, - selector, - socketConfig, - exceptionHandler, - handler, - InboundChannelBuffer.allocatingInstance() - ); - nioSocketChannel.setContext(context); - return nioSocketChannel; - } - - @Override - public NioServerSocketChannel createServerChannel( - NioSelector selector, - ServerSocketChannel channel, - Config.ServerSocket socketConfig - ) { - throw new UnsupportedOperationException("Cannot create server channel"); - } - } - - private static class HttpClientHandler implements NioChannelHandler { - - private final NettyAdaptor adaptor; - private final CountDownLatch latch; - private final Collection content; - - private HttpClientHandler( - NioSocketChannel channel, - CountDownLatch latch, - Collection content, - final boolean secure - ) throws IOException { - this.latch = latch; - this.content = content; - final int maxContentLength = Math.toIntExact(new ByteSizeValue(100, ByteSizeUnit.MB).getBytes()); - List handlers = new ArrayList<>(5); - - SslHandler sslHandler = null; - if (secure) { - sslHandler = new SslHandler( - SslContextBuilder.forClient() - .clientAuth(ClientAuth.NONE) - .trustManager(InsecureTrustManagerFactory.INSTANCE) - .build() - .newEngine(UnpooledByteBufAllocator.DEFAULT) - ); - } - - handlers.add(new HttpResponseDecoder()); - handlers.add(new HttpRequestEncoder()); - handlers.add(new HttpContentDecompressor()); - handlers.add(new HttpObjectAggregator(maxContentLength)); - - adaptor = new NettyAdaptor(sslHandler, handlers.toArray(new ChannelHandler[0])); - adaptor.addCloseListener((v, e) -> channel.close()); - } - - @Override - public void channelActive() {} - - @Override - public WriteOperation createWriteOperation(SocketChannelContext context, Object message, BiConsumer listener) { - assert message instanceof HttpRequest : "Expected type HttpRequest.class, found: " + message.getClass(); - return new WriteOperation() { - @Override - public BiConsumer getListener() { - return listener; - } - - @Override - public SocketChannelContext getChannel() { - return context; - } - - @Override - public Object getObject() { - return message; - } - }; - } - - @Override - public List writeToBytes(WriteOperation writeOperation) { - adaptor.write(writeOperation); - return pollFlushOperations(); - } - - @Override - public List pollFlushOperations() { - ArrayList copiedOperations = new ArrayList<>(adaptor.getOutboundCount()); - FlushOperation flushOperation; - while ((flushOperation = adaptor.pollOutboundOperation()) != null) { - copiedOperations.add(flushOperation); - } - return copiedOperations; - } - - @Override - public int consumeReads(InboundChannelBuffer channelBuffer) throws IOException { - int bytesConsumed = adaptor.read(channelBuffer.sliceAndRetainPagesTo(channelBuffer.getIndex())); - Object message; - while ((message = adaptor.pollInboundMessage()) != null) { - handleResponse(message); - } - - return bytesConsumed; - } - - @Override - public boolean closeNow() { - return false; - } - - @Override - public void close() throws IOException { - try { - adaptor.close(); - // After closing the pipeline, we must poll to see if any new messages are available. This - // is because HTTP supports a channel being closed as an end of content marker. - Object message; - while ((message = adaptor.pollInboundMessage()) != null) { - handleResponse(message); - } - } catch (Exception e) { - throw new IOException(e); - } - } - - private void handleResponse(Object message) { - final FullHttpResponse response = (FullHttpResponse) message; - DefaultFullHttpResponse newResponse = new DefaultFullHttpResponse( - response.protocolVersion(), - response.status(), - Unpooled.copiedBuffer(response.content()), - response.headers().copy(), - response.trailingHeaders().copy() - ); - response.release(); - content.add(newResponse); - latch.countDown(); - } - } - -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpPipeliningHandlerTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpPipeliningHandlerTests.java deleted file mode 100644 index d0c0406bd7774..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpPipeliningHandlerTests.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.common.Randomness; -import org.opensearch.core.common.bytes.BytesArray; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.http.HttpPipelinedRequest; -import org.opensearch.http.HttpPipelinedResponse; -import org.opensearch.http.HttpRequest; -import org.opensearch.http.HttpResponse; -import org.opensearch.test.OpenSearchTestCase; -import org.junit.After; - -import java.nio.channels.ClosedChannelException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import io.netty.buffer.ByteBufUtil; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.QueryStringDecoder; - -import static org.hamcrest.core.Is.is; -import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -public class NioHttpPipeliningHandlerTests extends OpenSearchTestCase { - - private final ExecutorService handlerService = Executors.newFixedThreadPool(randomIntBetween(4, 8)); - private final ExecutorService eventLoopService = Executors.newFixedThreadPool(1); - private final Map waitingRequests = new ConcurrentHashMap<>(); - private final Map finishingRequests = new ConcurrentHashMap<>(); - - @After - public void cleanup() throws Exception { - waitingRequests.keySet().forEach(this::finishRequest); - shutdownExecutorServices(); - } - - private CountDownLatch finishRequest(String url) { - waitingRequests.get(url).countDown(); - return finishingRequests.get(url); - } - - private void shutdownExecutorServices() throws InterruptedException { - if (!handlerService.isShutdown()) { - handlerService.shutdown(); - handlerService.awaitTermination(10, TimeUnit.SECONDS); - } - if (!eventLoopService.isShutdown()) { - eventLoopService.shutdown(); - eventLoopService.awaitTermination(10, TimeUnit.SECONDS); - } - } - - public void testThatPipeliningWorksWithFastSerializedRequests() throws InterruptedException { - final int numberOfRequests = randomIntBetween(2, 128); - final EmbeddedChannel embeddedChannel = new EmbeddedChannel( - new NioHttpPipeliningHandler(logger, numberOfRequests), - new WorkEmulatorHandler() - ); - - for (int i = 0; i < numberOfRequests; i++) { - embeddedChannel.writeInbound(createHttpRequest("/" + String.valueOf(i))); - } - - final List latches = new ArrayList<>(); - for (final String url : waitingRequests.keySet()) { - latches.add(finishRequest(url)); - } - - for (final CountDownLatch latch : latches) { - latch.await(); - } - - embeddedChannel.flush(); - - for (int i = 0; i < numberOfRequests; i++) { - assertReadHttpMessageHasContent(embeddedChannel, String.valueOf(i)); - } - - assertTrue(embeddedChannel.isOpen()); - } - - public void testThatPipeliningWorksWhenSlowRequestsInDifferentOrder() throws InterruptedException { - final int numberOfRequests = randomIntBetween(2, 128); - final EmbeddedChannel embeddedChannel = new EmbeddedChannel( - new NioHttpPipeliningHandler(logger, numberOfRequests), - new WorkEmulatorHandler() - ); - - for (int i = 0; i < numberOfRequests; i++) { - embeddedChannel.writeInbound(createHttpRequest("/" + String.valueOf(i))); - } - - // random order execution - final List urls = new ArrayList<>(waitingRequests.keySet()); - Randomness.shuffle(urls); - final List latches = new ArrayList<>(); - for (final String url : urls) { - latches.add(finishRequest(url)); - } - - for (final CountDownLatch latch : latches) { - latch.await(); - } - - embeddedChannel.flush(); - - for (int i = 0; i < numberOfRequests; i++) { - assertReadHttpMessageHasContent(embeddedChannel, String.valueOf(i)); - } - - assertTrue(embeddedChannel.isOpen()); - } - - public void testThatPipeliningClosesConnectionWithTooManyEvents() throws InterruptedException { - final int numberOfRequests = randomIntBetween(2, 128); - final EmbeddedChannel embeddedChannel = new EmbeddedChannel( - new NioHttpPipeliningHandler(logger, numberOfRequests), - new WorkEmulatorHandler() - ); - - for (int i = 0; i < 1 + numberOfRequests + 1; i++) { - embeddedChannel.writeInbound(createHttpRequest("/" + Integer.toString(i))); - } - - final List latches = new ArrayList<>(); - final List requests = IntStream.range(1, numberOfRequests + 1).boxed().collect(Collectors.toList()); - Randomness.shuffle(requests); - - for (final Integer request : requests) { - latches.add(finishRequest(request.toString())); - } - - for (final CountDownLatch latch : latches) { - latch.await(); - } - - finishRequest(Integer.toString(numberOfRequests + 1)).await(); - - embeddedChannel.flush(); - - assertFalse(embeddedChannel.isOpen()); - } - - public void testPipeliningRequestsAreReleased() { - final int numberOfRequests = 10; - final EmbeddedChannel embeddedChannel = new EmbeddedChannel(new NioHttpPipeliningHandler(logger, numberOfRequests + 1)); - - for (int i = 0; i < numberOfRequests; i++) { - embeddedChannel.writeInbound(createHttpRequest("/" + i)); - } - - HttpPipelinedRequest inbound; - ArrayList requests = new ArrayList<>(); - while ((inbound = embeddedChannel.readInbound()) != null) { - requests.add(inbound); - } - - ArrayList promises = new ArrayList<>(); - for (int i = 1; i < requests.size(); ++i) { - ChannelPromise promise = embeddedChannel.newPromise(); - promises.add(promise); - HttpPipelinedRequest pipelinedRequest = requests.get(i); - HttpPipelinedResponse resp = pipelinedRequest.createResponse(RestStatus.OK, BytesArray.EMPTY); - embeddedChannel.writeAndFlush(resp, promise); - } - - for (ChannelPromise promise : promises) { - assertFalse(promise.isDone()); - } - embeddedChannel.close().syncUninterruptibly(); - for (ChannelPromise promise : promises) { - assertTrue(promise.isDone()); - assertTrue(promise.cause() instanceof ClosedChannelException); - } - } - - private void assertReadHttpMessageHasContent(EmbeddedChannel embeddedChannel, String expectedContent) { - FullHttpResponse response = (FullHttpResponse) embeddedChannel.outboundMessages().poll(); - assertNotNull("Expected response to exist, maybe you did not wait long enough?", response); - assertNotNull("Expected response to have content " + expectedContent, response.content()); - String data = new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8); - assertThat(data, is(expectedContent)); - } - - private NioHttpRequest createHttpRequest(String uri) { - return new NioHttpRequest(new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, uri)); - } - - private class WorkEmulatorHandler extends SimpleChannelInboundHandler { - - @Override - protected void channelRead0(final ChannelHandlerContext ctx, HttpPipelinedRequest pipelinedRequest) { - final HttpRequest request = pipelinedRequest.getDelegateRequest(); - final QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); - - final String uri = decoder.path().replace("/", ""); - final BytesReference content = new BytesArray(uri.getBytes(StandardCharsets.UTF_8)); - HttpResponse httpResponse = pipelinedRequest.createResponse(RestStatus.OK, content); - httpResponse.addHeader(CONTENT_LENGTH.toString(), Integer.toString(content.length())); - - final CountDownLatch waitingLatch = new CountDownLatch(1); - waitingRequests.put(uri, waitingLatch); - final CountDownLatch finishingLatch = new CountDownLatch(1); - finishingRequests.put(uri, finishingLatch); - - handlerService.submit(() -> { - try { - waitingLatch.await(1000, TimeUnit.SECONDS); - final ChannelPromise promise = ctx.newPromise(); - eventLoopService.submit(() -> { - ctx.write(httpResponse, promise); - finishingLatch.countDown(); - }); - } catch (InterruptedException e) { - fail(e.toString()); - } - }); - } - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpServerTransportTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpServerTransportTests.java deleted file mode 100644 index 61b42f2a6b77a..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/NioHttpServerTransportTests.java +++ /dev/null @@ -1,540 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.apache.logging.log4j.message.ParameterizedMessage; -import org.opensearch.OpenSearchException; -import org.opensearch.common.network.NetworkAddress; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Setting; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.unit.TimeValue; -import org.opensearch.common.util.MockBigArrays; -import org.opensearch.common.util.MockPageCacheRecycler; -import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.core.common.bytes.BytesArray; -import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.core.common.unit.ByteSizeValue; -import org.opensearch.core.indices.breaker.NoneCircuitBreakerService; -import org.opensearch.http.BindHttpException; -import org.opensearch.http.CorsHandler; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.http.HttpTransportSettings; -import org.opensearch.http.NullDispatcher; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.telemetry.tracing.noop.NoopTracer; -import org.opensearch.test.OpenSearchTestCase; -import org.opensearch.test.rest.FakeRestRequest; -import org.opensearch.threadpool.TestThreadPool; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.nio.NioGroupFactory; -import org.junit.After; -import org.junit.Before; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; - -import static org.opensearch.core.rest.RestStatus.BAD_REQUEST; -import static org.opensearch.core.rest.RestStatus.OK; -import static org.opensearch.http.HttpTransportSettings.SETTING_CORS_ALLOW_ORIGIN; -import static org.opensearch.http.HttpTransportSettings.SETTING_CORS_ENABLED; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; - -/** - * Tests for the {@link NioHttpServerTransport} class. - */ -public class NioHttpServerTransportTests extends OpenSearchTestCase { - - private NetworkService networkService; - private ThreadPool threadPool; - private MockBigArrays bigArrays; - private MockPageCacheRecycler pageRecycler; - - @Before - public void setup() throws Exception { - networkService = new NetworkService(Collections.emptyList()); - threadPool = new TestThreadPool("test"); - pageRecycler = new MockPageCacheRecycler(Settings.EMPTY); - bigArrays = new MockBigArrays(pageRecycler, new NoneCircuitBreakerService()); - } - - @After - public void shutdown() throws Exception { - if (threadPool != null) { - threadPool.shutdownNow(); - } - threadPool = null; - networkService = null; - bigArrays = null; - } - - /** - * Test that {@link NioHttpServerTransport} supports the "Expect: 100-continue" HTTP header - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectContinueHeader() throws InterruptedException { - final Settings settings = createSettings(); - final int contentLength = randomIntBetween(1, HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).bytesAsInt()); - runExpectHeaderTest(settings, HttpHeaderValues.CONTINUE.toString(), contentLength, HttpResponseStatus.CONTINUE); - } - - /** - * Test that {@link NioHttpServerTransport} responds to a - * 100-continue expectation with too large a content-length - * with a 413 status. - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectContinueHeaderContentLengthTooLong() throws InterruptedException { - final String key = HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH.getKey(); - final int maxContentLength = randomIntBetween(1, 104857600); - final Settings settings = createBuilderWithPort().put(key, maxContentLength + "b").build(); - final int contentLength = randomIntBetween(maxContentLength + 1, Integer.MAX_VALUE); - runExpectHeaderTest(settings, HttpHeaderValues.CONTINUE.toString(), contentLength, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE); - } - - /** - * Test that {@link NioHttpServerTransport} responds to an unsupported expectation with a 417 status. - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectUnsupportedExpectation() throws InterruptedException { - final Settings settings = createSettings(); - runExpectHeaderTest(settings, "chocolate=yummy", 0, HttpResponseStatus.EXPECTATION_FAILED); - } - - private void runExpectHeaderTest( - final Settings settings, - final String expectation, - final int contentLength, - final HttpResponseStatus expectedStatus - ) throws InterruptedException { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - @Override - public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { - channel.sendResponse(new BytesRestResponse(OK, BytesRestResponse.TEXT_CONTENT_TYPE, new BytesArray("done"))); - } - - @Override - public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - }; - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - try (NioHttpClient client = NioHttpClient.http()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/"); - request.headers().set(HttpHeaderNames.EXPECT, expectation); - HttpUtil.setContentLength(request, contentLength); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(expectedStatus)); - if (expectedStatus.equals(HttpResponseStatus.CONTINUE)) { - final FullHttpRequest continuationRequest = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, - HttpMethod.POST, - "/", - Unpooled.EMPTY_BUFFER - ); - final FullHttpResponse continuationResponse = client.send(remoteAddress.address(), continuationRequest); - try { - assertThat(continuationResponse.status(), is(HttpResponseStatus.OK)); - assertThat( - new String(ByteBufUtil.getBytes(continuationResponse.content()), StandardCharsets.UTF_8), - is("done") - ); - } finally { - continuationResponse.release(); - } - } - } finally { - response.release(); - } - } - } - } - - public void testBindUnavailableAddress() { - final Settings initialSettings = createSettings(); - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - initialSettings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - new NullDispatcher(), - new NioGroupFactory(Settings.EMPTY, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - Settings settings = Settings.builder() - .put("http.port", remoteAddress.getPort()) - .put("network.host", remoteAddress.getAddress()) - .build(); - try ( - NioHttpServerTransport otherTransport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - new NullDispatcher(), - new NioGroupFactory(Settings.EMPTY, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - BindHttpException bindHttpException = expectThrows(BindHttpException.class, () -> otherTransport.start()); - assertEquals("Failed to bind to " + NetworkAddress.format(remoteAddress.address()), bindHttpException.getMessage()); - } - } - } - - public void testCorsRequest() throws InterruptedException { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError(); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - - }; - - final Settings settings = createBuilderWithPort().put(SETTING_CORS_ENABLED.getKey(), true) - .put(SETTING_CORS_ALLOW_ORIGIN.getKey(), "test-cors.org") - .build(); - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - // Test pre-flight request - try (NioHttpClient client = NioHttpClient.http()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.OPTIONS, "/"); - request.headers().add(CorsHandler.ORIGIN, "test-cors.org"); - request.headers().add(CorsHandler.ACCESS_CONTROL_REQUEST_METHOD, "POST"); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.OK)); - assertThat(response.headers().get(CorsHandler.ACCESS_CONTROL_ALLOW_ORIGIN), equalTo("test-cors.org")); - assertThat(response.headers().get(CorsHandler.VARY), equalTo(CorsHandler.ORIGIN)); - assertTrue(response.headers().contains(CorsHandler.DATE)); - } finally { - response.release(); - } - } - - // Test short-circuited request - try (NioHttpClient client = NioHttpClient.http()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); - request.headers().add(CorsHandler.ORIGIN, "google.com"); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.FORBIDDEN)); - } finally { - response.release(); - } - } - } - } - - public void testLargeCompressedResponse() throws InterruptedException { - final String responseString = randomAlphaOfLength(4 * 1024 * 1024); - final String url = "/thing"; - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - if (url.equals(request.uri())) { - channel.sendResponse(new BytesRestResponse(OK, responseString)); - } else { - logger.error("--> Unexpected successful uri [{}]", request.uri()); - throw new AssertionError(); - } - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - - }; - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - Settings.EMPTY, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(Settings.EMPTY, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.http()) { - DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); - request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, randomFrom("deflate", "gzip")); - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.OK)); - byte[] bytes = new byte[response.content().readableBytes()]; - response.content().readBytes(bytes); - assertThat(new String(bytes, StandardCharsets.UTF_8), equalTo(responseString)); - } finally { - response.release(); - } - } - } - } - - public void testBadRequest() throws InterruptedException { - final AtomicReference causeReference = new AtomicReference<>(); - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError(); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - causeReference.set(cause); - try { - final OpenSearchException e = new OpenSearchException("you sent a bad request and you should feel bad"); - channel.sendResponse(new BytesRestResponse(channel, BAD_REQUEST, e)); - } catch (final IOException e) { - throw new AssertionError(e); - } - } - - }; - - final Settings settings; - final int maxInitialLineLength; - final Setting httpMaxInitialLineLengthSetting = HttpTransportSettings.SETTING_HTTP_MAX_INITIAL_LINE_LENGTH; - if (randomBoolean()) { - maxInitialLineLength = httpMaxInitialLineLengthSetting.getDefault(Settings.EMPTY).bytesAsInt(); - settings = createSettings(); - } else { - maxInitialLineLength = randomIntBetween(1, 8192); - settings = createBuilderWithPort().put(httpMaxInitialLineLengthSetting.getKey(), maxInitialLineLength + "b").build(); - } - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.http()) { - final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8")); - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.BAD_REQUEST)); - assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), - containsString("you sent a bad request and you should feel bad") - ); - } finally { - response.release(); - } - } - } - - assertNotNull(causeReference.get()); - assertThat(causeReference.get(), instanceOf(TooLongFrameException.class)); - } - - public void testReadTimeout() throws Exception { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError("Should not have received a dispatched request"); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError("Should not have received a dispatched request"); - } - - }; - - Settings settings = createBuilderWithPort().put( - HttpTransportSettings.SETTING_HTTP_READ_TIMEOUT.getKey(), - new TimeValue(randomIntBetween(100, 300)) - ).build(); - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.http()) { - NioSocketChannel channel = null; - try { - CountDownLatch channelClosedLatch = new CountDownLatch(1); - channel = client.connect(remoteAddress.address()); - channel.addCloseListener((r, t) -> channelClosedLatch.countDown()); - assertTrue("Channel should be closed due to read timeout", channelClosedLatch.await(1, TimeUnit.MINUTES)); - } finally { - if (channel != null) { - channel.close(); - } - } - } - } - } - - private Settings createSettings() { - return createBuilderWithPort().build(); - } - - private Settings.Builder createBuilderWithPort() { - return Settings.builder().put(HttpTransportSettings.SETTING_HTTP_PORT.getKey(), getPortRange()); - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/PagedByteBufTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/PagedByteBufTests.java deleted file mode 100644 index c540c1854e509..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/PagedByteBufTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.http.nio; - -import org.opensearch.nio.Page; -import org.opensearch.test.OpenSearchTestCase; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicInteger; - -import io.netty.buffer.ByteBuf; - -public class PagedByteBufTests extends OpenSearchTestCase { - - public void testReleasingPage() { - AtomicInteger integer = new AtomicInteger(0); - int pageCount = randomInt(10) + 1; - ArrayList pages = new ArrayList<>(); - for (int i = 0; i < pageCount; ++i) { - pages.add(new Page(ByteBuffer.allocate(10), integer::incrementAndGet)); - } - - ByteBuf byteBuf = PagedByteBuf.byteBufFromPages(pages.toArray(new Page[0])); - - assertEquals(0, integer.get()); - byteBuf.retain(); - byteBuf.release(); - assertEquals(0, integer.get()); - ByteBuf secondBuf = byteBuf.retainedSlice(); - byteBuf.release(); - assertEquals(0, integer.get()); - secondBuf.release(); - assertEquals(pageCount, integer.get()); - } - - public void testBytesAreUsed() { - byte[] bytes1 = new byte[10]; - byte[] bytes2 = new byte[10]; - - for (int i = 0; i < 10; ++i) { - bytes1[i] = (byte) i; - } - - for (int i = 10; i < 20; ++i) { - bytes2[i - 10] = (byte) i; - } - - Page[] pages = new Page[2]; - pages[0] = new Page(ByteBuffer.wrap(bytes1), () -> {}); - pages[1] = new Page(ByteBuffer.wrap(bytes2), () -> {}); - - ByteBuf byteBuf = PagedByteBuf.byteBufFromPages(pages); - assertEquals(20, byteBuf.readableBytes()); - - for (int i = 0; i < 20; ++i) { - assertEquals((byte) i, byteBuf.getByte(i)); - } - - Page[] pages2 = new Page[2]; - ByteBuffer firstBuffer = ByteBuffer.wrap(bytes1); - firstBuffer.position(2); - ByteBuffer secondBuffer = ByteBuffer.wrap(bytes2); - secondBuffer.limit(8); - pages2[0] = new Page(firstBuffer, () -> {}); - pages2[1] = new Page(secondBuffer, () -> {}); - - ByteBuf byteBuf2 = PagedByteBuf.byteBufFromPages(pages2); - assertEquals(16, byteBuf2.readableBytes()); - - for (int i = 2; i < 18; ++i) { - assertEquals((byte) i, byteBuf2.getByte(i - 2)); - } - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/ssl/SecureNioHttpServerTransportTests.java b/plugins/transport-nio/src/test/java/org/opensearch/http/nio/ssl/SecureNioHttpServerTransportTests.java deleted file mode 100644 index 1adfe0370344c..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/http/nio/ssl/SecureNioHttpServerTransportTests.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -package org.opensearch.http.nio.ssl; - -import org.apache.logging.log4j.message.ParameterizedMessage; -import org.opensearch.OpenSearchException; -import org.opensearch.common.network.NetworkAddress; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Setting; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.unit.TimeValue; -import org.opensearch.common.util.MockBigArrays; -import org.opensearch.common.util.MockPageCacheRecycler; -import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.core.common.bytes.BytesArray; -import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.core.common.unit.ByteSizeValue; -import org.opensearch.core.indices.breaker.NoneCircuitBreakerService; -import org.opensearch.http.BindHttpException; -import org.opensearch.http.CorsHandler; -import org.opensearch.http.HttpServerTransport; -import org.opensearch.http.HttpTransportSettings; -import org.opensearch.http.NullDispatcher; -import org.opensearch.http.nio.NioHttpClient; -import org.opensearch.http.nio.NioHttpServerTransport; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.plugins.SecureHttpTransportSettingsProvider; -import org.opensearch.plugins.TransportExceptionHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.telemetry.tracing.noop.NoopTracer; -import org.opensearch.test.OpenSearchTestCase; -import org.opensearch.test.rest.FakeRestRequest; -import org.opensearch.threadpool.TestThreadPool; -import org.opensearch.threadpool.ThreadPool; -import org.opensearch.transport.nio.NioGroupFactory; -import org.junit.After; -import org.junit.Before; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Optional; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; - -import static org.opensearch.core.rest.RestStatus.BAD_REQUEST; -import static org.opensearch.core.rest.RestStatus.OK; -import static org.opensearch.http.HttpTransportSettings.SETTING_CORS_ALLOW_ORIGIN; -import static org.opensearch.http.HttpTransportSettings.SETTING_CORS_ENABLED; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; - -/** - * Tests for the secure {@link NioHttpServerTransport} class. - */ -public class SecureNioHttpServerTransportTests extends OpenSearchTestCase { - - private NetworkService networkService; - private ThreadPool threadPool; - private MockBigArrays bigArrays; - private MockPageCacheRecycler pageRecycler; - private ClusterSettings clusterSettings; - private SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider; - - @Before - public void setup() throws Exception { - networkService = new NetworkService(Collections.emptyList()); - threadPool = new TestThreadPool("test"); - pageRecycler = new MockPageCacheRecycler(Settings.EMPTY); - bigArrays = new MockBigArrays(pageRecycler, new NoneCircuitBreakerService()); - clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); - - secureHttpTransportSettingsProvider = new SecureHttpTransportSettingsProvider() { - @Override - public Optional buildHttpServerExceptionHandler(Settings settings, HttpServerTransport transport) { - return Optional.empty(); - } - - @Override - public Optional buildSecureHttpServerEngine(Settings settings, HttpServerTransport transport) throws SSLException { - try { - SSLEngine engine = SslContextBuilder.forServer( - SecureNioHttpServerTransportTests.class.getResourceAsStream("/certificate.crt"), - SecureNioHttpServerTransportTests.class.getResourceAsStream("/certificate.key") - ).trustManager(InsecureTrustManagerFactory.INSTANCE).build().newEngine(UnpooledByteBufAllocator.DEFAULT); - return Optional.of(engine); - } catch (final IOException ex) { - throw new SSLException(ex); - } - } - }; - } - - @After - public void shutdown() throws Exception { - if (threadPool != null) { - threadPool.shutdownNow(); - } - threadPool = null; - networkService = null; - bigArrays = null; - clusterSettings = null; - } - - /** - * Test that {@link NioHttpServerTransport} supports the "Expect: 100-continue" HTTP header - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectContinueHeader() throws InterruptedException { - final Settings settings = createSettings(); - final int contentLength = randomIntBetween(1, HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).bytesAsInt()); - runExpectHeaderTest(settings, HttpHeaderValues.CONTINUE.toString(), contentLength, HttpResponseStatus.CONTINUE); - } - - /** - * Test that {@link NioHttpServerTransport} responds to a - * 100-continue expectation with too large a content-length - * with a 413 status. - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectContinueHeaderContentLengthTooLong() throws InterruptedException { - final String key = HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH.getKey(); - final int maxContentLength = randomIntBetween(1, 104857600); - final Settings settings = createBuilderWithPort().put(key, maxContentLength + "b").build(); - final int contentLength = randomIntBetween(maxContentLength + 1, Integer.MAX_VALUE); - runExpectHeaderTest(settings, HttpHeaderValues.CONTINUE.toString(), contentLength, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE); - } - - /** - * Test that {@link NioHttpServerTransport} responds to an unsupported expectation with a 417 status. - * @throws InterruptedException if the client communication with the server is interrupted - */ - public void testExpectUnsupportedExpectation() throws InterruptedException { - Settings settings = createSettings(); - runExpectHeaderTest(settings, "chocolate=yummy", 0, HttpResponseStatus.EXPECTATION_FAILED); - } - - private void runExpectHeaderTest( - final Settings settings, - final String expectation, - final int contentLength, - final HttpResponseStatus expectedStatus - ) throws InterruptedException { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - @Override - public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { - channel.sendResponse(new BytesRestResponse(OK, BytesRestResponse.TEXT_CONTENT_TYPE, new BytesArray("done"))); - } - - @Override - public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - }; - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - clusterSettings, - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - try (NioHttpClient client = NioHttpClient.https()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/"); - request.headers().set(HttpHeaderNames.EXPECT, expectation); - HttpUtil.setContentLength(request, contentLength); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(expectedStatus)); - if (expectedStatus.equals(HttpResponseStatus.CONTINUE)) { - final FullHttpRequest continuationRequest = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, - HttpMethod.POST, - "/", - Unpooled.EMPTY_BUFFER - ); - final FullHttpResponse continuationResponse = client.send(remoteAddress.address(), continuationRequest); - try { - assertThat(continuationResponse.status(), is(HttpResponseStatus.OK)); - assertThat( - new String(ByteBufUtil.getBytes(continuationResponse.content()), StandardCharsets.UTF_8), - is("done") - ); - } finally { - continuationResponse.release(); - } - } - } finally { - response.release(); - } - } - } - } - - public void testBindUnavailableAddress() { - Settings initialSettings = createSettings(); - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - initialSettings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - new NullDispatcher(), - new NioGroupFactory(Settings.EMPTY, logger), - clusterSettings, - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - Settings settings = Settings.builder() - .put("http.port", remoteAddress.getPort()) - .put("network.host", remoteAddress.getAddress()) - .build(); - try ( - NioHttpServerTransport otherTransport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - new NullDispatcher(), - new NioGroupFactory(Settings.EMPTY, logger), - clusterSettings, - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - BindHttpException bindHttpException = expectThrows(BindHttpException.class, otherTransport::start); - assertEquals("Failed to bind to " + NetworkAddress.format(remoteAddress.address()), bindHttpException.getMessage()); - } - } - } - - public void testCorsRequest() throws InterruptedException { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError(); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - - }; - - final Settings settings = createBuilderWithPort().put(SETTING_CORS_ENABLED.getKey(), true) - .put(SETTING_CORS_ALLOW_ORIGIN.getKey(), "test-cors.org") - .build(); - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - // Test pre-flight request - try (NioHttpClient client = NioHttpClient.https()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.OPTIONS, "/"); - request.headers().add(CorsHandler.ORIGIN, "test-cors.org"); - request.headers().add(CorsHandler.ACCESS_CONTROL_REQUEST_METHOD, "POST"); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.OK)); - assertThat(response.headers().get(CorsHandler.ACCESS_CONTROL_ALLOW_ORIGIN), equalTo("test-cors.org")); - assertThat(response.headers().get(CorsHandler.VARY), equalTo(CorsHandler.ORIGIN)); - assertTrue(response.headers().contains(CorsHandler.DATE)); - } finally { - response.release(); - } - } - - // Test short-circuited request - try (NioHttpClient client = NioHttpClient.https()) { - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); - request.headers().add(CorsHandler.ORIGIN, "google.com"); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.FORBIDDEN)); - } finally { - response.release(); - } - } - } - } - - public void testLargeCompressedResponse() throws InterruptedException { - final String responseString = randomAlphaOfLength(4 * 1024 * 1024); - final String url = "/thing"; - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - if (url.equals(request.uri())) { - channel.sendResponse(new BytesRestResponse(OK, responseString)); - } else { - logger.error("--> Unexpected successful uri [{}]", request.uri()); - throw new AssertionError(); - } - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError(); - } - - }; - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - Settings.EMPTY, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(Settings.EMPTY, logger), - clusterSettings, - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.https()) { - DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); - request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, randomFrom("deflate", "gzip")); - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.OK)); - byte[] bytes = new byte[response.content().readableBytes()]; - response.content().readBytes(bytes); - assertThat(new String(bytes, StandardCharsets.UTF_8), equalTo(responseString)); - } finally { - response.release(); - } - } - } - } - - public void testBadRequest() throws InterruptedException { - final AtomicReference causeReference = new AtomicReference<>(); - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError(); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - causeReference.set(cause); - try { - final OpenSearchException e = new OpenSearchException("you sent a bad request and you should feel bad"); - channel.sendResponse(new BytesRestResponse(channel, BAD_REQUEST, e)); - } catch (final IOException e) { - throw new AssertionError(e); - } - } - - }; - - final Settings settings; - final int maxInitialLineLength; - final Setting httpMaxInitialLineLengthSetting = HttpTransportSettings.SETTING_HTTP_MAX_INITIAL_LINE_LENGTH; - if (randomBoolean()) { - maxInitialLineLength = httpMaxInitialLineLengthSetting.getDefault(Settings.EMPTY).bytesAsInt(); - settings = createSettings(); - } else { - maxInitialLineLength = randomIntBetween(1, 8192); - settings = createBuilderWithPort().put(httpMaxInitialLineLengthSetting.getKey(), maxInitialLineLength + "b").build(); - } - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - clusterSettings, - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.https()) { - final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8")); - final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); - - final FullHttpResponse response = client.send(remoteAddress.address(), request); - try { - assertThat(response.status(), equalTo(HttpResponseStatus.BAD_REQUEST)); - assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), - containsString("you sent a bad request and you should feel bad") - ); - } finally { - response.release(); - } - } - } - - assertNotNull(causeReference.get()); - assertThat(causeReference.get(), instanceOf(TooLongFrameException.class)); - } - - public void testReadTimeout() throws Exception { - final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() { - - @Override - public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) { - logger.error("--> Unexpected successful request [{}]", FakeRestRequest.requestToString(request)); - throw new AssertionError("Should not have received a dispatched request"); - } - - @Override - public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { - logger.error( - new ParameterizedMessage("--> Unexpected bad request [{}]", FakeRestRequest.requestToString(channel.request())), - cause - ); - throw new AssertionError("Should not have received a dispatched request"); - } - - }; - - Settings settings = createBuilderWithPort().put( - HttpTransportSettings.SETTING_HTTP_READ_TIMEOUT.getKey(), - new TimeValue(randomIntBetween(100, 300)) - ).build(); - - try ( - NioHttpServerTransport transport = new NioHttpServerTransport( - settings, - networkService, - bigArrays, - pageRecycler, - threadPool, - xContentRegistry(), - dispatcher, - new NioGroupFactory(settings, logger), - new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), - secureHttpTransportSettingsProvider, - NoopTracer.INSTANCE - ) - ) { - transport.start(); - final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses()); - - try (NioHttpClient client = NioHttpClient.https()) { - NioSocketChannel channel = null; - try { - CountDownLatch channelClosedLatch = new CountDownLatch(1); - channel = client.connect(remoteAddress.address()); - channel.addCloseListener((r, t) -> channelClosedLatch.countDown()); - assertTrue("Channel should be closed due to read timeout", channelClosedLatch.await(1, TimeUnit.MINUTES)); - } finally { - if (channel != null) { - channel.close(); - } - } - } - } - } - - private Settings createSettings() { - return createBuilderWithPort().build(); - } - - private Settings.Builder createBuilderWithPort() { - return Settings.builder().put(HttpTransportSettings.SETTING_HTTP_PORT.getKey(), getPortRange()); - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/NioGroupFactoryTests.java b/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/NioGroupFactoryTests.java deleted file mode 100644 index 965632af1daf2..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/NioGroupFactoryTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.common.settings.Settings; -import org.opensearch.nio.ChannelFactory; -import org.opensearch.nio.Config; -import org.opensearch.nio.NioGroup; -import org.opensearch.nio.NioSelector; -import org.opensearch.nio.NioServerSocketChannel; -import org.opensearch.nio.NioSocketChannel; -import org.opensearch.nio.ServerChannelContext; -import org.opensearch.test.OpenSearchTestCase; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.function.Consumer; - -public class NioGroupFactoryTests extends OpenSearchTestCase { - - public void testSharedGroupStillWorksWhenOneInstanceClosed() throws IOException { - NioGroupFactory groupFactory = new NioGroupFactory(Settings.EMPTY, logger); - - InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - NioGroup httpGroup = groupFactory.getHttpGroup(); - try { - NioGroup transportGroup = groupFactory.getTransportGroup(); - transportGroup.close(); - expectThrows(IllegalStateException.class, () -> transportGroup.bindServerChannel(inetSocketAddress, new BindingFactory())); - - httpGroup.bindServerChannel(inetSocketAddress, new BindingFactory()); - } finally { - httpGroup.close(); - } - expectThrows(IllegalStateException.class, () -> httpGroup.bindServerChannel(inetSocketAddress, new BindingFactory())); - } - - private static class BindingFactory extends ChannelFactory { - - private BindingFactory() { - super(false, false, -1, -1, -1, false, -1, -1); - } - - @Override - public NioSocketChannel createChannel(NioSelector selector, SocketChannel channel, Config.Socket socketConfig) throws IOException { - throw new IOException("boom"); - } - - @Override - public NioServerSocketChannel createServerChannel( - NioSelector selector, - ServerSocketChannel channel, - Config.ServerSocket socketConfig - ) { - NioServerSocketChannel nioChannel = new NioServerSocketChannel(channel); - Consumer exceptionHandler = (e) -> {}; - Consumer acceptor = (c) -> {}; - ServerChannelContext context = new ServerChannelContext(nioChannel, this, selector, socketConfig, acceptor, exceptionHandler); - nioChannel.setContext(context); - return nioChannel; - } - } -} diff --git a/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/SimpleNioTransportTests.java b/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/SimpleNioTransportTests.java deleted file mode 100644 index f5d1c618f5ace..0000000000000 --- a/plugins/transport-nio/src/test/java/org/opensearch/transport/nio/SimpleNioTransportTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.transport.nio; - -import org.opensearch.Version; -import org.opensearch.cluster.node.DiscoveryNode; -import org.opensearch.common.network.NetworkService; -import org.opensearch.common.settings.ClusterSettings; -import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.MockPageCacheRecycler; -import org.opensearch.common.util.io.IOUtils; -import org.opensearch.common.util.net.NetUtils; -import org.opensearch.core.action.ActionListener; -import org.opensearch.core.common.io.stream.NamedWriteableRegistry; -import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.core.indices.breaker.NoneCircuitBreakerService; -import org.opensearch.telemetry.tracing.noop.NoopTracer; -import org.opensearch.test.transport.MockTransportService; -import org.opensearch.test.transport.StubbableTransport; -import org.opensearch.transport.AbstractSimpleTransportTestCase; -import org.opensearch.transport.ConnectTransportException; -import org.opensearch.transport.ConnectionProfile; -import org.opensearch.transport.TcpChannel; -import org.opensearch.transport.TcpTransport; -import org.opensearch.transport.TestProfiles; -import org.opensearch.transport.Transport; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.channels.SocketChannel; -import java.util.Collections; - -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySet; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.lessThanOrEqualTo; - -public class SimpleNioTransportTests extends AbstractSimpleTransportTestCase { - - @Override - protected Transport build(Settings settings, final Version version, ClusterSettings clusterSettings, boolean doHandshake) { - NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(Collections.emptyList()); - NetworkService networkService = new NetworkService(Collections.emptyList()); - return new NioTransport( - settings, - version, - threadPool, - networkService, - new MockPageCacheRecycler(settings), - namedWriteableRegistry, - new NoneCircuitBreakerService(), - new NioGroupFactory(settings, logger), - NoopTracer.INSTANCE - ) { - - @Override - public void executeHandshake( - DiscoveryNode node, - TcpChannel channel, - ConnectionProfile profile, - ActionListener listener - ) { - if (doHandshake) { - super.executeHandshake(node, channel, profile, listener); - } else { - listener.onResponse(version.minimumCompatibilityVersion()); - } - } - }; - } - - public void testConnectException() throws UnknownHostException { - try { - serviceA.connectToNode( - new DiscoveryNode( - "C", - new TransportAddress(InetAddress.getByName("localhost"), 9876), - emptyMap(), - emptySet(), - Version.CURRENT - ) - ); - fail("Expected ConnectTransportException"); - } catch (ConnectTransportException e) { - assertThat(e.getMessage(), containsString("connect_exception")); - assertThat(e.getMessage(), containsString("[127.0.0.1:9876]")); - Throwable cause = e.getCause(); - assertThat(cause, instanceOf(IOException.class)); - } - } - - public void testDefaultKeepAliveSettings() throws IOException { - assumeTrue("setting default keepalive options not supported on this platform", (IOUtils.LINUX || IOUtils.MAC_OS_X)); - try ( - MockTransportService serviceC = buildService("TS_C", Version.CURRENT, Settings.EMPTY); - MockTransportService serviceD = buildService("TS_D", Version.CURRENT, Settings.EMPTY) - ) { - serviceC.start(); - serviceC.acceptIncomingRequests(); - serviceD.start(); - serviceD.acceptIncomingRequests(); - - try (Transport.Connection connection = serviceC.openConnection(serviceD.getLocalDiscoNode(), TestProfiles.LIGHT_PROFILE)) { - assertThat(connection, instanceOf(StubbableTransport.WrappedConnection.class)); - Transport.Connection conn = ((StubbableTransport.WrappedConnection) connection).getConnection(); - assertThat(conn, instanceOf(TcpTransport.NodeChannels.class)); - TcpTransport.NodeChannels nodeChannels = (TcpTransport.NodeChannels) conn; - for (TcpChannel channel : nodeChannels.getChannels()) { - assertFalse(channel.isServerChannel()); - checkDefaultKeepAliveOptions(channel); - } - - assertThat(serviceD.getOriginalTransport(), instanceOf(TcpTransport.class)); - for (TcpChannel channel : getAcceptedChannels((TcpTransport) serviceD.getOriginalTransport())) { - assertTrue(channel.isServerChannel()); - checkDefaultKeepAliveOptions(channel); - } - } - } - } - - private void checkDefaultKeepAliveOptions(TcpChannel channel) throws IOException { - assertThat(channel, instanceOf(NioTcpChannel.class)); - NioTcpChannel nioChannel = (NioTcpChannel) channel; - SocketChannel socketChannel = nioChannel.getRawChannel(); - assertThat(socketChannel.supportedOptions(), hasItem(NetUtils.getTcpKeepIdleSocketOptionOrNull())); - Integer keepIdle = socketChannel.getOption(NetUtils.getTcpKeepIdleSocketOptionOrNull()); - assertNotNull(keepIdle); - assertThat(keepIdle, lessThanOrEqualTo(500)); - assertThat(socketChannel.supportedOptions(), hasItem(NetUtils.getTcpKeepIntervalSocketOptionOrNull())); - Integer keepInterval = socketChannel.getOption(NetUtils.getTcpKeepIntervalSocketOptionOrNull()); - assertNotNull(keepInterval); - assertThat(keepInterval, lessThanOrEqualTo(500)); - } -} diff --git a/plugins/transport-nio/src/test/resources/README.txt b/plugins/transport-nio/src/test/resources/README.txt deleted file mode 100644 index a4353cee45a97..0000000000000 --- a/plugins/transport-nio/src/test/resources/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -# This is README describes how the certificates in this directory were created. -# This file can also be executed as a script -# - -# 1. Create certificate key - -openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes - -# 2. Export the certificate in pkcs12 format - -openssl pkcs12 -export -in certificate.crt -inkey certificate.key -out server.p12 -name netty4-secure -password pass:password - diff --git a/plugins/transport-nio/src/test/resources/certificate.crt b/plugins/transport-nio/src/test/resources/certificate.crt deleted file mode 100644 index 54c78fdbcf6de..0000000000000 --- a/plugins/transport-nio/src/test/resources/certificate.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIUddAawr5zygcd+Dcn9WVDpO4BJ7YwDQYJKoZIhvcNAQEL -BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X -DTI0MDMxNDE5NDQzOVoXDTI3MDEwMjE5NDQzOVowWTELMAkGA1UEBhMCQVUxEzAR -BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 -IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAzjOKkg6Iba5zfZ8b/RYw+PGmGEfbdGuuF10Wz4Jmx/Nk4VfDLxdh -TW8VllUL2JD7uPkjABj7pW3awAbvIJ+VGbKqfBr1Nsz0mPPzhT8cfuMH/FDZgQs3 -4HuqDKr0LfC1Kw5E3WF0GVMBDNu0U+nKoeqySeYjGdxDnd3W4cqK5AnUxL0RnIny -Bw7ZuhcU55XndH/Xauro/2EpvJduDsWMdqt7ZfIf1TOmaiQHK+82yb/drVaJbczK -uTpn1Kv2bnzkQEckgq+z1dLNOOyvP2xf+nsziw5ilJe92e5GJOUJYFAlEgUAGpfD -dv6j/gTRYvdJCJItOQEQtektNCAZsoc0wwIDAQABo1MwUTAdBgNVHQ4EFgQUzHts -wIt+zhB/R4U4Do2P6rr0YhkwHwYDVR0jBBgwFoAUzHtswIt+zhB/R4U4Do2P6rr0 -YhkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAveh870jJX7vt -oLCrdugsyo79pR4f7Nr1kUy3jJrfoaoUmrjiiiHWgT22fGwp7j1GZF2mVfo8YVaK -63YNn5gB2NNZhguPOFC4AdvHRYOKRBOaOvWK8oq7BcJ//18JYI/pPnpgkYvJjqv4 -gFKaZX9qWtujHpAmKiVGs7pwYGNXfixPHRNV4owcfHMIH5dhbbqT49j94xVpjbXs -OymKtFl4kpCE/0LzKFrFcuu55Am1VLBHx2cPpHLOipgUcF5BHFlQ8AXiCMOwfPAw -d22mLB6Gt1oVEpyvQHYd3e04FetEXQ9E8T+NKWZx/8Ucf+IWBYmZBRxch6O83xgk -bAbGzqkbzQ== ------END CERTIFICATE----- diff --git a/plugins/transport-nio/src/test/resources/certificate.key b/plugins/transport-nio/src/test/resources/certificate.key deleted file mode 100644 index 228350180935d..0000000000000 --- a/plugins/transport-nio/src/test/resources/certificate.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDOM4qSDohtrnN9 -nxv9FjD48aYYR9t0a64XXRbPgmbH82ThV8MvF2FNbxWWVQvYkPu4+SMAGPulbdrA -Bu8gn5UZsqp8GvU2zPSY8/OFPxx+4wf8UNmBCzfge6oMqvQt8LUrDkTdYXQZUwEM -27RT6cqh6rJJ5iMZ3EOd3dbhyorkCdTEvRGcifIHDtm6FxTnled0f9dq6uj/YSm8 -l24OxYx2q3tl8h/VM6ZqJAcr7zbJv92tVoltzMq5OmfUq/ZufORARySCr7PV0s04 -7K8/bF/6ezOLDmKUl73Z7kYk5QlgUCUSBQAal8N2/qP+BNFi90kIki05ARC16S00 -IBmyhzTDAgMBAAECggEAVOdiElvLjyX6xeoC00YU6hxOIMdNtHU2HMamwtDV01UD -38mMQ9KjrQelYt4n34drLrHe2IZw75/5J4JzagJrmUY47psHBwaDXItuZRokeJaw -zhLYTEs7OcKRtV+a5WOspUrdzi33aQoFb67zZG3qkpsZyFXrdBV+/fy/Iv+MCvLH -xR0jQ5mzE3cw20R7S4nddChBA/y8oKGOo6QRf2SznC1jL/+yolHvJPEn1v8AUxYm -BMPHxj1O0c4M4IxnJQ3Y5Jy9OaFMyMsFlF1hVhc/3LDDxDyOuBsVsFDicojyrRea -GKngIke0yezy7Wo4NUcp8YQhafonpWVsSJJdOUotcQKBgQD0rihFBXVtcG1d/Vy7 -FvLHrmccD56JNV744LSn2CDM7W1IulNbDUZINdCFqL91u5LpxozeE1FPY1nhwncJ -N7V7XYCaSLCuV1YJzRmUCjnzk2RyopGpzWog3f9uUFGgrk1HGbNAv99k/REya6Iu -IRSkuQhaJOj3bRXzonh0K4GjewKBgQDXvamtCioOUMSP8vq919YMkBw7F+z/fr0p -pamO8HL9eewAUg6N92JQ9kobSo/GptdmdHIjs8LqnS5C3H13GX5Qlf5GskOlCpla -V55ElaSp0gvKwWE168U7gQH4etPQAXXJrOGFaGbPj9W81hTUud7HVE88KYdfWTBo -I7TuE25tWQKBgBRjcr2Vn9xXsvVTCGgamG5lLPhcoNREGz7X0pXt34XT/vhBdnKu -331i5pZMom+YCrzqK5DRwUPBPpseTjb5amj2OKIijn5ojqXQbmI0m/GdBZC71TF2 -CXLlrMQvcy3VeGEFVjd+BYpvwAAYkfIQFZ1IQdbpHnSHpX2guzLK8UmDAoGBANUy -PIcf0EetUVHfkCIjNQfdMcjD8BTcLhsF9vWmcDxFTA9VB8ULf0D64mjt2f85yQsa -b+EQN8KZ6alxMxuLOeRxFYLPj0F9o+Y/R8wHBV48kCKhz2r1v0b6SfQ/jSm1B61x -BrxLW64qOdIOzS8bLyhUDKkrcPesr8V548aRtUKhAoGBAKlNJFd8BCGKD9Td+3dE -oP1iHTX5XZ+cQIqL0e+GMQlK4HnQP566DFZU5/GHNNAfmyxd5iSRwhTqPMHRAmOb -pqQwsyufx0dFeIBxeSO3Z6jW5h2sl4nBipZpw9bzv6EBL1xRr0SfMNZzdnf4JFzc -0htGo/VO93Z2pv8w7uGUz1nN ------END PRIVATE KEY----- diff --git a/qa/smoke-test-http/build.gradle b/qa/smoke-test-http/build.gradle index 496fda6bb717d..466a4988cbf7c 100644 --- a/qa/smoke-test-http/build.gradle +++ b/qa/smoke-test-http/build.gradle @@ -36,7 +36,6 @@ apply plugin: 'opensearch.test-with-dependencies' dependencies { testImplementation project(path: ':modules:transport-netty4') // for http testImplementation project(path: ':plugins:transport-reactor-netty4') // for http - testImplementation project(path: ':plugins:transport-nio') testImplementation project(path: ':plugins:identity-shiro') // for http } diff --git a/qa/smoke-test-http/src/test/java/org/opensearch/http/HttpSmokeTestCase.java b/qa/smoke-test-http/src/test/java/org/opensearch/http/HttpSmokeTestCase.java index 6d8e80a0a63ea..aff251e934f81 100644 --- a/qa/smoke-test-http/src/test/java/org/opensearch/http/HttpSmokeTestCase.java +++ b/qa/smoke-test-http/src/test/java/org/opensearch/http/HttpSmokeTestCase.java @@ -37,7 +37,6 @@ import org.opensearch.test.OpenSearchIntegTestCase; import org.opensearch.transport.Netty4ModulePlugin; import org.opensearch.transport.nio.MockNioTransportPlugin; -import org.opensearch.transport.nio.NioTransportPlugin; import org.opensearch.transport.reactor.ReactorNetty4Plugin; import org.junit.BeforeClass; @@ -53,16 +52,14 @@ public abstract class HttpSmokeTestCase extends OpenSearchIntegTestCase { @SuppressWarnings("unchecked") @BeforeClass public static void setUpTransport() { - nodeTransportTypeKey = getTypeKey(randomFrom(getTestTransportPlugin(), Netty4ModulePlugin.class, NioTransportPlugin.class)); - nodeHttpTypeKey = getHttpTypeKey(randomFrom(Netty4ModulePlugin.class, NioTransportPlugin.class, ReactorNetty4Plugin.class)); - clientTypeKey = getTypeKey(randomFrom(getTestTransportPlugin(), Netty4ModulePlugin.class, NioTransportPlugin.class)); + nodeTransportTypeKey = getTypeKey(randomFrom(getTestTransportPlugin(), Netty4ModulePlugin.class)); + nodeHttpTypeKey = getHttpTypeKey(randomFrom(Netty4ModulePlugin.class, ReactorNetty4Plugin.class)); + clientTypeKey = getTypeKey(randomFrom(getTestTransportPlugin(), Netty4ModulePlugin.class)); } private static String getTypeKey(Class clazz) { if (clazz.equals(MockNioTransportPlugin.class)) { return MockNioTransportPlugin.MOCK_NIO_TRANSPORT_NAME; - } else if (clazz.equals(NioTransportPlugin.class)) { - return NioTransportPlugin.NIO_TRANSPORT_NAME; } else { assert clazz.equals(Netty4ModulePlugin.class); return Netty4ModulePlugin.NETTY_TRANSPORT_NAME; @@ -70,9 +67,7 @@ private static String getTypeKey(Class clazz) { } private static String getHttpTypeKey(Class clazz) { - if (clazz.equals(NioTransportPlugin.class)) { - return NioTransportPlugin.NIO_HTTP_TRANSPORT_NAME; - } else if (clazz.equals(ReactorNetty4Plugin.class)) { + if (clazz.equals(ReactorNetty4Plugin.class)) { return ReactorNetty4Plugin.REACTOR_NETTY_HTTP_TRANSPORT_NAME; } else { assert clazz.equals(Netty4ModulePlugin.class); @@ -95,7 +90,7 @@ protected Settings nodeSettings(int nodeOrdinal) { @Override protected Collection> nodePlugins() { - return Arrays.asList(getTestTransportPlugin(), Netty4ModulePlugin.class, NioTransportPlugin.class, ReactorNetty4Plugin.class); + return Arrays.asList(getTestTransportPlugin(), Netty4ModulePlugin.class, ReactorNetty4Plugin.class); } @Override diff --git a/qa/smoke-test-http/src/test/java/org/opensearch/http/IdentityAuthenticationIT.java b/qa/smoke-test-http/src/test/java/org/opensearch/http/IdentityAuthenticationIT.java index 3936a142945a4..8e8e724bbe855 100644 --- a/qa/smoke-test-http/src/test/java/org/opensearch/http/IdentityAuthenticationIT.java +++ b/qa/smoke-test-http/src/test/java/org/opensearch/http/IdentityAuthenticationIT.java @@ -24,7 +24,6 @@ import org.opensearch.test.OpenSearchIntegTestCase; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.transport.Netty4ModulePlugin; -import org.opensearch.transport.nio.NioTransportPlugin; import org.opensearch.transport.reactor.ReactorNetty4Plugin; import static org.hamcrest.Matchers.equalTo; @@ -42,7 +41,7 @@ protected Settings nodeSettings(int nodeOrdinal) { @Override protected Collection> nodePlugins() { - return Arrays.asList(OpenSearchTestCase.getTestTransportPlugin(), Netty4ModulePlugin.class, NioTransportPlugin.class, ReactorNetty4Plugin.class, ShiroIdentityPlugin.class); + return Arrays.asList(OpenSearchTestCase.getTestTransportPlugin(), Netty4ModulePlugin.class, ReactorNetty4Plugin.class, ShiroIdentityPlugin.class); }