diff --git a/build.gradle.kts b/build.gradle.kts index b34712e16..57d578792 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,17 +36,4 @@ subprojects { if (name.endsWith("test", ignoreCase = true)) onlyIf { !rootProject.hasProperty("skipTests") } if (name.startsWith("link", ignoreCase = true)) onlyIf { !rootProject.hasProperty("skipLink") } } - - //workaround for https://youtrack.jetbrains.com/issue/KT-44884 - configurations.matching { !it.name.startsWith("kotlinCompilerPluginClasspath") }.all { - resolutionStrategy.eachDependency { - val version = requested.version - if (requested.group == "org.jetbrains.kotlinx" && - requested.name.startsWith("kotlinx-coroutines") && - version != null && !version.contains("native-mt") - ) { - useVersion("$version-native-mt") - } - } - } } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index dc6733cb0..1494f2a8b 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -4,12 +4,14 @@ pluginManagement { repositories { gradlePluginPortal() mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } } dependencyResolutionManagement { repositories { mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } versionCatalogs { diff --git a/buildSrc/src/main/kotlin/TestOptIn.kt b/buildSrc/src/main/kotlin/TestOptIn.kt index 95763339b..e09d3317c 100644 --- a/buildSrc/src/main/kotlin/TestOptIn.kt +++ b/buildSrc/src/main/kotlin/TestOptIn.kt @@ -11,9 +11,6 @@ fun LanguageSettingsBuilder.optInForTest() { optIn("kotlinx.coroutines.FlowPreview") optIn("kotlinx.coroutines.DelicateCoroutinesApi") - optIn("io.ktor.util.InternalAPI") - optIn("io.ktor.utils.io.core.internal.DangerousInternalIoApi") - optIn("io.rsocket.kotlin.TransportApi") optIn("io.rsocket.kotlin.ExperimentalMetadataApi") optIn("io.rsocket.kotlin.ExperimentalStreamsApi") diff --git a/buildSrc/src/main/kotlin/rsocket.multiplatform.gradle.kts b/buildSrc/src/main/kotlin/rsocket.multiplatform.gradle.kts index ca6e34de9..75d4f3fe9 100644 --- a/buildSrc/src/main/kotlin/rsocket.multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/rsocket.multiplatform.gradle.kts @@ -10,11 +10,6 @@ kotlin { optIn("kotlin.RequiresOptIn") - //TODO: kludge, this is needed now, - // as ktor isn't fully supports kotlin 1.5.3x opt-in changes - // will be not needed after ktor 2.0.0 - optIn("io.ktor.utils.io.core.ExperimentalIoApi") - if (name.contains("test", ignoreCase = true)) optInForTest() } } diff --git a/gradle.properties b/gradle.properties index b30f3a978..5e6b411cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,11 +19,9 @@ version=0.15.0-SNAPSHOT #Kotlin kotlin.js.compiler=both kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableGranularSourceSetsMetadata=true -kotlin.native.enableDependencyPropagation=false kotlin.native.ignoreIncorrectDependencies=true -#TODO native debug tests fail for ktor -kotlin.native.cacheKind.linuxX64=none +kotlin.native.binary.memoryModel=experimental +kotlin.native.binary.freezing=disabled #Gradle org.gradle.parallel=true org.gradle.caching=true diff --git a/gradle/js/yarn/yarn.lock b/gradle/js/yarn/yarn.lock index 259afacbb..c602cf22a 100644 --- a/gradle/js/yarn/yarn.lock +++ b/gradle/js/yarn/yarn.lock @@ -211,6 +211,13 @@ abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + accepts@~1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -274,6 +281,11 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -552,6 +564,14 @@ dom-serialize@^2.2.1: extend "^3.0.0" void-elements "^2.0.0" +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -655,6 +675,11 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -826,6 +851,11 @@ glob@^7.1.3, glob@^7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" @@ -1235,6 +1265,11 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-fetch@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" @@ -1676,6 +1711,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + ua-parser-js@^0.7.28: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" @@ -1833,6 +1873,13 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +ws@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + ws@~7.4.2: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a99155396..f6ded983b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,19 @@ [versions] -kotlin = "1.6.10" +kotlin = "1.6.20-M1-106" kotlinx-atomicfu = "0.17.0" -kotlinx-coroutines = "1.5.2-native-mt" -kotlinx-benchmark = "0.4.0" +kotlinx-coroutines = "1.6.0" +kotlinx-benchmark = "0.4.2" -ktor = "1.6.7" +ktor = "2.0.0-eap-317" turbine = "0.7.0" -versionUpdates = "0.39.0" +versionUpdates = "0.41.0" rsocket-java = "1.1.1" -jmh = "1.33" +jmh = "1.34" [libraries] kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } @@ -25,12 +25,13 @@ kotlinx-benchmark = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime" ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" } ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor" } ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" } -ktor-http-cio = { module = "io.ktor:ktor-http-cio", version.ref = "ktor" } +ktor-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } ktor-server-core = { module = "io.ktor:ktor-server", version.ref = "ktor" } -ktor-server-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" } +ktor-server-websockets = { module = "io.ktor:ktor-server-websockets", version.ref = "ktor" } ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" } ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } ktor-server-jetty = { module = "io.ktor:ktor-server-jetty", version.ref = "ktor" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d2880ba80..2e6e5897b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/frame/io/packet.kt b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/frame/io/packet.kt index 56b6f46f8..48de32018 100644 --- a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/frame/io/packet.kt +++ b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/frame/io/packet.kt @@ -21,7 +21,7 @@ import io.ktor.utils.io.core.internal.* import io.ktor.utils.io.pool.* internal inline fun buildPacket(pool: ObjectPool, block: BytePacketBuilder.() -> Unit): ByteReadPacket { - val builder = BytePacketBuilder(0, pool) + val builder = BytePacketBuilder(pool) try { block(builder) return builder.build() diff --git a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/RequestFlow.kt b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/RequestFlow.kt index 7cc3463e1..ed4b84cf7 100644 --- a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/RequestFlow.kt +++ b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/RequestFlow.kt @@ -51,7 +51,6 @@ internal suspend inline fun FlowCollector.emitAllWithRequestN( internal abstract class RequestFlow : Flow { private val consumed = atomic(false) - @InternalCoroutinesApi override suspend fun collect(collector: FlowCollector) { check(!consumed.getAndSet(true)) { "RequestFlow can be collected just once" } diff --git a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/handler/FrameHandler.kt b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/handler/FrameHandler.kt index 4d2fcf559..9e828fa9c 100644 --- a/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/handler/FrameHandler.kt +++ b/rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/internal/handler/FrameHandler.kt @@ -24,8 +24,8 @@ import io.rsocket.kotlin.payload.* import kotlinx.coroutines.* internal abstract class FrameHandler(pool: ObjectPool) : Closeable { - private val data = BytePacketBuilder(0, pool) - private val metadata = BytePacketBuilder(0, pool) + private val data = BytePacketBuilder(pool) + private val metadata = BytePacketBuilder(pool) protected abstract var hasMetadata: Boolean fun handleRequest(frame: RequestFrame) { diff --git a/rsocket-test/rsocket-test-server/build.gradle.kts b/rsocket-test/rsocket-test-server/build.gradle.kts index 638bbfee0..a6724c534 100644 --- a/rsocket-test/rsocket-test-server/build.gradle.kts +++ b/rsocket-test/rsocket-test-server/build.gradle.kts @@ -30,7 +30,8 @@ kotlin { main { dependencies { implementation(projects.rsocketTest) - implementation(projects.rsocketTransportKtorServer) + implementation(projects.rsocketTransportKtor.rsocketTransportKtorTcp) + implementation(projects.rsocketTransportKtor.rsocketTransportKtorWebsocketServer) implementation(libs.ktor.server.cio) } @@ -73,7 +74,7 @@ val testTasks = setOf( ) rootProject.allprojects { - if (name == "rsocket-transport-ktor") { + if (name == "rsocket-transport-ktor-websocket") { tasks.matching { it.name in testTasks }.all { dependsOn(startTestServer) } diff --git a/rsocket-test/rsocket-test-server/src/jvmMain/kotlin/io/rsocket/kotlin/test/server/App.kt b/rsocket-test/rsocket-test-server/src/jvmMain/kotlin/io/rsocket/kotlin/test/server/App.kt index 904b77c5d..5e0cc789b 100644 --- a/rsocket-test/rsocket-test-server/src/jvmMain/kotlin/io/rsocket/kotlin/test/server/App.kt +++ b/rsocket-test/rsocket-test-server/src/jvmMain/kotlin/io/rsocket/kotlin/test/server/App.kt @@ -16,15 +16,15 @@ package io.rsocket.kotlin.test.server -import io.ktor.application.* -import io.ktor.routing.* +import io.ktor.server.application.* import io.ktor.server.cio.* import io.ktor.server.engine.* -import io.ktor.websocket.* +import io.ktor.server.routing.* +import io.ktor.server.websocket.* import io.rsocket.kotlin.core.* import io.rsocket.kotlin.test.* -import io.rsocket.kotlin.transport.ktor.* -import io.rsocket.kotlin.transport.ktor.server.* +import io.rsocket.kotlin.transport.ktor.tcp.* +import io.rsocket.kotlin.transport.ktor.websocket.server.* import kotlinx.coroutines.* import java.io.* diff --git a/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/InUseTrackingPool.kt b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/InUseTrackingPool.kt index 279542821..865c242fc 100644 --- a/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/InUseTrackingPool.kt +++ b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/InUseTrackingPool.kt @@ -22,7 +22,6 @@ import io.ktor.utils.io.core.internal.* import io.ktor.utils.io.pool.* import kotlin.test.* -@Suppress("DEPRECATION", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "UNCHECKED_CAST") object InUseTrackingPool : ObjectPool { override val capacity: Int get() = BufferPool.capacity private val inUse = TrackingSet() @@ -35,7 +34,7 @@ object InUseTrackingPool : ObjectPool { override fun recycle(instance: ChunkBuffer) { inUse.remove(instance) - BufferPool.recycle(instance as IoBuffer) + BufferPool.recycle(instance) } override fun dispose() { @@ -80,21 +79,21 @@ object InUseTrackingPool : ObjectPool { // that there are no leaked buffers // used only on tests, so it's more or less safe // copy of io.ktor.utils.io.core.DefaultBufferPool with changed parent pool!!! - private object BufferPool : DefaultPool(1000) { - override fun produceInstance(): IoBuffer { - return IoBuffer(DefaultAllocator.alloc(DEFAULT_BUFFER_SIZE), null, InUseTrackingPool as ObjectPool) + @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + private object BufferPool : DefaultPool(1000) { + override fun produceInstance(): ChunkBuffer { + return ChunkBuffer(DefaultAllocator.alloc(DEFAULT_BUFFER_SIZE), null, InUseTrackingPool) } - override fun disposeInstance(instance: IoBuffer) { + override fun disposeInstance(instance: ChunkBuffer) { DefaultAllocator.free(instance.memory) super.disposeInstance(instance) instance.unlink() } - override fun validateInstance(instance: IoBuffer) { + override fun validateInstance(instance: ChunkBuffer) { super.validateInstance(instance) - check(instance !== IoBuffer.Empty) { "Empty instance couldn't be recycled" } check(instance !== Buffer.Empty) { "Empty instance couldn't be recycled" } check(instance !== ChunkBuffer.Empty) { "Empty instance couldn't be recycled" } @@ -103,7 +102,7 @@ object InUseTrackingPool : ObjectPool { check(instance.origin == null) { "Recycled instance shouldn't be a view or another buffer." } } - override fun clearInstance(instance: IoBuffer): IoBuffer { + override fun clearInstance(instance: ChunkBuffer): ChunkBuffer { return super.clearInstance(instance).apply { unpark() reset() diff --git a/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/Packets.kt b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/Packets.kt index 85635f4e2..18857a6df 100644 --- a/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/Packets.kt +++ b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/Packets.kt @@ -38,7 +38,7 @@ fun assertBytesEquals(expected: ByteArray?, actual: ByteArray?) { } private inline fun buildPacket(pool: ObjectPool, block: BytePacketBuilder.() -> Unit): ByteReadPacket { - val builder = BytePacketBuilder(0, pool) + val builder = BytePacketBuilder(pool) try { block(builder) return builder.build() diff --git a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/PortProvider.kt b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/PortProvider.kt similarity index 81% rename from rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/PortProvider.kt rename to rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/PortProvider.kt index 33f9de457..4f6c2798f 100644 --- a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/PortProvider.kt +++ b/rsocket-test/src/commonMain/kotlin/io/rsocket/kotlin/test/PortProvider.kt @@ -1,4 +1,4 @@ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.test import kotlinx.atomicfu.* import kotlin.random.* diff --git a/rsocket-transport-ktor/build.gradle.kts b/rsocket-transport-ktor/build.gradle.kts index 5d098dc1c..5e2acd72f 100644 --- a/rsocket-transport-ktor/build.gradle.kts +++ b/rsocket-transport-ktor/build.gradle.kts @@ -23,35 +23,12 @@ kotlin { main { dependencies { api(projects.rsocketCore) - - api(libs.ktor.network) - api(libs.ktor.http.cio) - } - } - test { - dependencies { - implementation(projects.rsocketTransportKtorClient) - } - } - } - configureJvm { - test { - dependencies { - implementation(projects.rsocketTransportKtorServer) - - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.okhttp) - - implementation(libs.ktor.server.cio) - implementation(libs.ktor.server.netty) - implementation(libs.ktor.server.jetty) } } } + configureJvm() configureJs() - configureNative(NativeTargets.Nix) + configureNative() } description = "Ktor RSocket transport implementations (TCP, Websocket)" - -evaluationDependsOn(":rsocket-test-server") diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-client/build.gradle.kts b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/build.gradle.kts similarity index 84% rename from rsocket-transport-ktor/rsocket-transport-ktor-client/build.gradle.kts rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/build.gradle.kts index 33e5b985b..998f83f0b 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-client/build.gradle.kts +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/build.gradle.kts @@ -22,16 +22,13 @@ kotlin { configureCommon { main { dependencies { - api(projects.rsocketCore) api(projects.rsocketTransportKtor) - - api(libs.ktor.client.core) + api(libs.ktor.network) } } } configureJvm() - configureJs() configureNative(NativeTargets.Nix) } -description = "Ktor installments for RSocket client transport" \ No newline at end of file +description = "Ktor TCP RSocket transport implementation" diff --git a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpClientTransport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpClientTransport.kt similarity index 87% rename from rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpClientTransport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpClientTransport.kt index 70ef6742e..06d8d20c5 100644 --- a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpClientTransport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpClientTransport.kt @@ -17,12 +17,10 @@ @file:OptIn(TransportApi::class) @file:Suppress("FunctionName") -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp import io.ktor.network.selector.* import io.ktor.network.sockets.* -import io.ktor.util.* -import io.ktor.util.network.* import io.ktor.utils.io.core.internal.* import io.ktor.utils.io.pool.* import io.rsocket.kotlin.* @@ -41,10 +39,10 @@ public fun TcpClientTransport( pool: ObjectPool = ChunkBuffer.Pool, intercept: (Socket) -> Socket = { it }, //f.e. for tls, which is currently supported by ktor only on JVM configure: SocketOptions.TCPClientSocketOptions.() -> Unit = {} -): ClientTransport = TcpClientTransport(NetworkAddress(hostname, port), context, pool, intercept, configure) +): ClientTransport = TcpClientTransport(InetSocketAddress(hostname, port), context, pool, intercept, configure) public fun TcpClientTransport( - remoteAddress: NetworkAddress, + remoteAddress: InetSocketAddress, context: CoroutineContext = EmptyCoroutineContext, pool: ObjectPool = ChunkBuffer.Pool, intercept: (Socket) -> Socket = { it }, //f.e. for tls, which is currently supported by ktor only on JVM @@ -52,7 +50,7 @@ public fun TcpClientTransport( ): ClientTransport { val transportJob = SupervisorJob(context[Job]) val transportContext = defaultDispatcher + context + transportJob + CoroutineName("rSocket-tcp-client") - val selector = @OptIn(InternalAPI::class) SelectorManager(transportContext) + val selector = SelectorManager(transportContext) Job(transportJob).invokeOnCompletion { selector.close() } return ClientTransport(transportContext) { val socket = aSocket(selector).tcp().connect(remoteAddress, configure) diff --git a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpConnection.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpConnection.kt similarity index 98% rename from rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpConnection.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpConnection.kt index 6c3fb42be..9aa677390 100644 --- a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpConnection.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpConnection.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp import io.ktor.network.sockets.* import io.ktor.util.cio.* diff --git a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTransport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTransport.kt similarity index 88% rename from rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTransport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTransport.kt index 12e80cc65..a338da0b0 100644 --- a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTransport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTransport.kt @@ -17,12 +17,10 @@ @file:OptIn(TransportApi::class) @file:Suppress("FunctionName") -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp import io.ktor.network.selector.* import io.ktor.network.sockets.* -import io.ktor.util.* -import io.ktor.util.network.* import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* import io.ktor.utils.io.pool.* @@ -39,16 +37,16 @@ public fun TcpServerTransport( hostname: String = "0.0.0.0", port: Int = 0, pool: ObjectPool = ChunkBuffer.Pool, configure: SocketOptions.AcceptorOptions.() -> Unit = {}, -): ServerTransport = TcpServerTransport(NetworkAddress(hostname, port), pool, configure) +): ServerTransport = TcpServerTransport(InetSocketAddress(hostname, port), pool, configure) public fun TcpServerTransport( - localAddress: NetworkAddress? = null, + localAddress: InetSocketAddress? = null, pool: ObjectPool = ChunkBuffer.Pool, configure: SocketOptions.AcceptorOptions.() -> Unit = {}, ): ServerTransport = ServerTransport { accept -> val serverSocketDeferred = CompletableDeferred() val handlerJob = launch(defaultDispatcher + coroutineContext) { - @OptIn(InternalAPI::class) SelectorManager(coroutineContext).use { selector -> + SelectorManager(coroutineContext).use { selector -> aSocket(selector).tcp().bind(localAddress, configure).use { serverSocket -> serverSocketDeferred.complete(serverSocket) val connectionScope = diff --git a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTest.kt similarity index 94% rename from rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTest.kt index 3202dccfc..828e8a684 100644 --- a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpServerTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpServerTest.kt @@ -14,19 +14,19 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp -import io.ktor.util.network.* +import io.ktor.network.sockets.* import io.rsocket.kotlin.* import io.rsocket.kotlin.core.* import io.rsocket.kotlin.test.* import kotlinx.coroutines.* import kotlin.test.* -abstract class TcpServerTest : SuspendTest, TestWithLeakCheck { +class TcpServerTest : SuspendTest, TestWithLeakCheck { private val testJob = Job() private val testContext = testJob + CoroutineExceptionHandler { c, e -> println("$c -> $e") } - private val address = NetworkAddress("0.0.0.0", PortProvider.next()) + private val address = InetSocketAddress("0.0.0.0", PortProvider.next()) private val serverTransport = TcpServerTransport(address, InUseTrackingPool) private val clientTransport = TcpClientTransport(address, testContext, InUseTrackingPool) diff --git a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpTransportTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpTransportTest.kt similarity index 73% rename from rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpTransportTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpTransportTest.kt index 5d87df2db..0a6594d62 100644 --- a/rsocket-transport-ktor/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/TcpTransportTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/commonTest/kotlin/io/rsocket/kotlin/transport/ktor/tcp/TcpTransportTest.kt @@ -14,19 +14,23 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp -import io.ktor.util.network.* +import io.ktor.network.sockets.* import io.rsocket.kotlin.test.* import kotlinx.coroutines.* -abstract class TcpTransportTest : TransportTest() { +class TcpTransportTest : TransportTest() { private val testJob = Job() override suspend fun before() { - val address = NetworkAddress("0.0.0.0", PortProvider.next()) + val address = InetSocketAddress("0.0.0.0", PortProvider.next()) val context = testJob + CoroutineExceptionHandler { c, e -> println("$c -> $e") } - SERVER.bindIn(CoroutineScope(context), TcpServerTransport(address, InUseTrackingPool), ACCEPTOR).serverSocket.await() + SERVER.bindIn( + CoroutineScope(context), + TcpServerTransport(address, InUseTrackingPool), + ACCEPTOR + ).serverSocket.await() client = CONNECTOR.connect(TcpClientTransport(address, context, InUseTrackingPool)) } diff --git a/rsocket-transport-ktor/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt similarity index 71% rename from rsocket-transport-ktor/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt index 42b0e8fc5..cca4a108b 100644 --- a/rsocket-transport-ktor/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt @@ -1,4 +1,4 @@ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp import kotlinx.coroutines.* diff --git a/rsocket-transport-ktor/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt similarity index 72% rename from rsocket-transport-ktor/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt index 1ec04304a..fbd7cd52a 100644 --- a/rsocket-transport-ktor/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-tcp/src/nativeMain/kotlin/io/rsocket/kotlin/transport/ktor/tcp/defaultDispatcher.kt @@ -1,4 +1,4 @@ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.tcp import kotlinx.coroutines.* diff --git a/rsocket-transport-ktor/src/nativeTest/kotlin/io/rsocket/kotlin/transport/ktor/NativeTcpTransportTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/build.gradle.kts similarity index 55% rename from rsocket-transport-ktor/src/nativeTest/kotlin/io/rsocket/kotlin/transport/ktor/NativeTcpTransportTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/build.gradle.kts index a370916e7..36ec34f08 100644 --- a/rsocket-transport-ktor/src/nativeTest/kotlin/io/rsocket/kotlin/transport/ktor/NativeTcpTransportTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/build.gradle.kts @@ -14,7 +14,24 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +plugins { + rsocket.template.library +} -class NativeTcpTransportTest : TcpTransportTest() -class NativeTcpServerTest : TcpServerTest() +kotlin { + configureCommon { + main { + dependencies { + api(projects.rsocketCore) + api(projects.rsocketTransportKtor.rsocketTransportKtorWebsocket) + api(libs.ktor.client.core) + api(libs.ktor.client.websockets) + } + } + } + configureJvm() + configureJs() + configureNative() +} + +description = "Ktor WebSocket Client RSocket transport implementation" diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/Builders.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/Builders.kt similarity index 90% rename from rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/Builders.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/Builders.kt index b72bffbf6..f4d108732 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/Builders.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/Builders.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor.client +package io.rsocket.kotlin.transport.ktor.websocket.client import io.ktor.client.* -import io.ktor.client.features.* +import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.http.* import io.rsocket.kotlin.* @@ -38,7 +38,6 @@ public suspend fun HttpClient.rSocket( secure: Boolean = false, ): RSocket = rSocket(WebSocketClientTransport(this, host, port, path, secure)) - private suspend fun HttpClient.rSocket( transport: ClientTransport, -): RSocket = get(RSocketSupport).connector.connect(transport) +): RSocket = plugin(RSocketSupport).connector.connect(transport) diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/RSocketSupport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/RSocketSupport.kt similarity index 73% rename from rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/RSocketSupport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/RSocketSupport.kt index e1f82b3c1..48d2e26ba 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/RSocketSupport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/RSocketSupport.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor.client +package io.rsocket.kotlin.transport.ktor.websocket.client import io.ktor.client.* -import io.ktor.client.features.* -import io.ktor.client.features.websocket.* +import io.ktor.client.plugins.* +import io.ktor.client.plugins.websocket.* import io.ktor.util.* import io.rsocket.kotlin.core.* @@ -30,15 +30,16 @@ public class RSocketSupport( public var connector: RSocketConnector = RSocketConnector() } - public companion object Feature : HttpClientFeature { + public companion object Feature : HttpClientPlugin { override val key: AttributeKey = AttributeKey("RSocket") override fun prepare(block: Config.() -> Unit): RSocketSupport { val connector = Config().apply(block).connector return RSocketSupport(connector) } - override fun install(feature: RSocketSupport, scope: HttpClient) { - scope.feature(WebSockets) ?: error("RSocket require WebSockets to work. You must install WebSockets feature first.") + override fun install(plugin: RSocketSupport, scope: HttpClient) { + scope.pluginOrNull(WebSockets) + ?: error("RSocket require WebSockets to work. You must install WebSockets plugin first.") } } } diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/WebSocketClientTransport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/WebSocketClientTransport.kt similarity index 91% rename from rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/WebSocketClientTransport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/WebSocketClientTransport.kt index 4a0209058..41e084e18 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/client/WebSocketClientTransport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-client/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/client/WebSocketClientTransport.kt @@ -17,15 +17,15 @@ @file:OptIn(TransportApi::class) @file:Suppress("FunctionName") -package io.rsocket.kotlin.transport.ktor.client +package io.rsocket.kotlin.transport.ktor.websocket.client import io.ktor.client.* -import io.ktor.client.features.websocket.* +import io.ktor.client.plugins.websocket.* import io.ktor.client.request.* import io.ktor.http.* import io.rsocket.kotlin.* import io.rsocket.kotlin.transport.* -import io.rsocket.kotlin.transport.ktor.* +import io.rsocket.kotlin.transport.ktor.websocket.* import kotlinx.coroutines.* public fun WebSocketClientTransport( @@ -33,7 +33,7 @@ public fun WebSocketClientTransport( request: HttpRequestBuilder.() -> Unit, ): ClientTransport = ClientTransport(httpClient.coroutineContext + SupervisorJob(httpClient.coroutineContext[Job])) { val session = httpClient.webSocketSession(request) - @Suppress("INVISIBLE_MEMBER") WebSocketConnection(session) + WebSocketConnection(session) } public fun WebSocketClientTransport( diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-server/build.gradle.kts b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/build.gradle.kts similarity index 85% rename from rsocket-transport-ktor/rsocket-transport-ktor-server/build.gradle.kts rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/build.gradle.kts index fe5074c2d..4f0ff5857 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-server/build.gradle.kts +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/build.gradle.kts @@ -23,8 +23,7 @@ kotlin { main { dependencies { api(projects.rsocketCore) - api(projects.rsocketTransportKtor) - + api(projects.rsocketTransportKtor.rsocketTransportKtorWebsocket) api(libs.ktor.server.core) api(libs.ktor.server.websockets) } @@ -32,4 +31,4 @@ kotlin { } } -description = "Ktor installments for RSocket server transport" +description = "Ktor WebSocket Server RSocket transport implementation" diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/RSocketSupport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/RSocketSupport.kt similarity index 75% rename from rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/RSocketSupport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/RSocketSupport.kt index fdbbbd4e9..364f446dd 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/RSocketSupport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/RSocketSupport.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor.server +package io.rsocket.kotlin.transport.ktor.websocket.server -import io.ktor.application.* +import io.ktor.server.application.* +import io.ktor.server.websocket.* import io.ktor.util.* -import io.ktor.websocket.* import io.rsocket.kotlin.core.* public class RSocketSupport( @@ -28,10 +28,11 @@ public class RSocketSupport( public var server: RSocketServer = RSocketServer() } - public companion object Feature : ApplicationFeature { + public companion object Feature : ApplicationPlugin { override val key: AttributeKey = AttributeKey("RSocket") override fun install(pipeline: Application, configure: Config.() -> Unit): RSocketSupport { - pipeline.featureOrNull(WebSockets) ?: error("RSocket require WebSockets to work. You must install WebSockets feature first.") + pipeline.pluginOrNull(WebSockets) + ?: error("RSocket require WebSockets to work. You must install WebSockets plugin first.") val server = Config().apply(configure).server return RSocketSupport(server) } diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/Routing.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/Routing.kt similarity index 83% rename from rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/Routing.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/Routing.kt index 3ba0fee6c..7959dab3f 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/Routing.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/Routing.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor.server +package io.rsocket.kotlin.transport.ktor.websocket.server -import io.ktor.application.* -import io.ktor.routing.* +import io.ktor.server.application.* +import io.ktor.server.routing.* import io.rsocket.kotlin.* import kotlinx.coroutines.* @@ -28,7 +28,7 @@ public fun Route.rSocket( acceptor: ConnectionAcceptor, ) { val serverTransport = serverTransport(path, protocol) - val server = application.feature(RSocketSupport).server + val server = application.plugin(RSocketSupport).server server.bind(serverTransport, acceptor) } diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/WebSocketServerTransport.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/WebSocketServerTransport.kt similarity index 76% rename from rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/WebSocketServerTransport.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/WebSocketServerTransport.kt index d89fe7ad8..026333524 100644 --- a/rsocket-transport-ktor/rsocket-transport-ktor-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/server/WebSocketServerTransport.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket-server/src/jvmMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/server/WebSocketServerTransport.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor.server +package io.rsocket.kotlin.transport.ktor.websocket.server -import io.ktor.routing.* -import io.ktor.websocket.* +import io.ktor.server.routing.* +import io.ktor.server.websocket.* import io.rsocket.kotlin.* import io.rsocket.kotlin.transport.* -import io.rsocket.kotlin.transport.ktor.* +import io.rsocket.kotlin.transport.ktor.websocket.* @OptIn(TransportApi::class) internal fun Route.serverTransport( @@ -29,11 +29,11 @@ internal fun Route.serverTransport( ): ServerTransport = ServerTransport { acceptor -> when (path) { null -> webSocket(protocol) { - val connection = @Suppress("INVISIBLE_MEMBER") WebSocketConnection(this) + val connection = WebSocketConnection(this) acceptor(connection) } else -> webSocket(path, protocol) { - val connection = @Suppress("INVISIBLE_MEMBER") WebSocketConnection(this) + val connection = WebSocketConnection(this) acceptor(connection) } } diff --git a/rsocket-transport-ktor/rsocket-transport-ktor-websocket/build.gradle.kts b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/build.gradle.kts new file mode 100644 index 000000000..2eef9fcf5 --- /dev/null +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/build.gradle.kts @@ -0,0 +1,55 @@ +/* + * Copyright 2015-2020 the original author or authors. + * + * 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. + */ + +plugins { + rsocket.template.library +} + +kotlin { + configureCommon { + main { + dependencies { + api(projects.rsocketTransportKtor) + api(libs.ktor.websockets) + } + } + test { + dependencies { + implementation(projects.rsocketTransportKtor.rsocketTransportKtorWebsocketClient) + } + } + } + configureJvm { + test { + dependencies { + implementation(projects.rsocketTransportKtor.rsocketTransportKtorWebsocketServer) + + implementation(libs.ktor.client.cio) + implementation(libs.ktor.client.okhttp) + + implementation(libs.ktor.server.cio) + implementation(libs.ktor.server.netty) + implementation(libs.ktor.server.jetty) + } + } + } + configureJs() + configureNative() +} + +description = "Ktor WebSocket RSocket transport implementation" + +evaluationDependsOn(":rsocket-test-server") diff --git a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnection.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnection.kt similarity index 83% rename from rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnection.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnection.kt index 460b656fc..5fa7c9c88 100644 --- a/rsocket-transport-ktor/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnection.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/commonMain/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnection.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.websocket -import io.ktor.http.cio.websocket.* import io.ktor.utils.io.core.* +import io.ktor.websocket.* import io.rsocket.kotlin.* import kotlinx.coroutines.* @TransportApi -internal class WebSocketConnection(private val session: WebSocketSession) : Connection, CoroutineScope by session { +public class WebSocketConnection(private val session: WebSocketSession) : Connection, CoroutineScope by session { override suspend fun send(packet: ByteReadPacket) { session.send(packet.readBytes()) } diff --git a/rsocket-transport-ktor/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/ClientWebSocketTransportTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/ClientWebSocketTransportTest.kt similarity index 87% rename from rsocket-transport-ktor/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/ClientWebSocketTransportTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/ClientWebSocketTransportTest.kt index 2285574a1..ca87d33e8 100644 --- a/rsocket-transport-ktor/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/ClientWebSocketTransportTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jsTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/ClientWebSocketTransportTest.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.websocket import io.ktor.client.* import io.ktor.client.engine.js.* -import io.ktor.client.features.websocket.* +import io.ktor.client.plugins.websocket.* import io.rsocket.kotlin.test.* -import io.rsocket.kotlin.transport.ktor.client.* +import io.rsocket.kotlin.transport.ktor.websocket.client.* import kotlinx.coroutines.* class ClientWebSocketTransportTest : TransportTest() { @@ -36,7 +36,6 @@ class ClientWebSocketTransportTest : TransportTest() { override suspend fun after() { super.after() - httpClient.close() httpClient.coroutineContext.job.cancelAndJoin() } diff --git a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnectionTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnectionTest.kt similarity index 82% rename from rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnectionTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnectionTest.kt index 2ddc8f46a..50939fa11 100644 --- a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketConnectionTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketConnectionTest.kt @@ -14,28 +14,28 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.websocket -import io.ktor.application.* import io.ktor.client.* -import io.ktor.routing.* +import io.ktor.server.application.* import io.ktor.server.engine.* +import io.ktor.server.routing.* import io.rsocket.kotlin.* import io.rsocket.kotlin.core.* import io.rsocket.kotlin.keepalive.* import io.rsocket.kotlin.payload.* import io.rsocket.kotlin.test.* -import io.rsocket.kotlin.transport.ktor.client.* -import io.rsocket.kotlin.transport.ktor.server.* +import io.rsocket.kotlin.transport.ktor.websocket.client.* +import io.rsocket.kotlin.transport.ktor.websocket.server.* import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlin.test.* import io.ktor.client.engine.cio.CIO as ClientCIO -import io.ktor.client.features.websocket.WebSockets as ClientWebSockets +import io.ktor.client.plugins.websocket.WebSockets as ClientWebSockets import io.ktor.server.cio.CIO as ServerCIO -import io.ktor.websocket.WebSockets as ServerWebSockets -import io.rsocket.kotlin.transport.ktor.client.RSocketSupport as ClientRSocketSupport -import io.rsocket.kotlin.transport.ktor.server.RSocketSupport as ServerRSocketSupport +import io.ktor.server.websocket.WebSockets as ServerWebSockets +import io.rsocket.kotlin.transport.ktor.websocket.client.RSocketSupport as ClientRSocketSupport +import io.rsocket.kotlin.transport.ktor.websocket.server.RSocketSupport as ServerRSocketSupport class WebSocketConnectionTest : SuspendTest, TestWithLeakCheck { private val port = PortProvider.next() diff --git a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTest.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTest.kt similarity index 77% rename from rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTest.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTest.kt index 758f950f4..55251adb4 100644 --- a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTest.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTest.kt @@ -14,21 +14,21 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.websocket -import io.ktor.application.* import io.ktor.client.* import io.ktor.client.engine.* -import io.ktor.routing.* +import io.ktor.server.application.* import io.ktor.server.engine.* +import io.ktor.server.routing.* import io.rsocket.kotlin.test.* -import io.rsocket.kotlin.transport.ktor.client.* -import io.rsocket.kotlin.transport.ktor.server.* +import io.rsocket.kotlin.transport.ktor.websocket.client.* +import io.rsocket.kotlin.transport.ktor.websocket.server.* import kotlinx.coroutines.* -import io.ktor.client.features.websocket.WebSockets as ClientWebSockets -import io.ktor.websocket.WebSockets as ServerWebSockets -import io.rsocket.kotlin.transport.ktor.client.RSocketSupport as ClientRSocketSupport -import io.rsocket.kotlin.transport.ktor.server.RSocketSupport as ServerRSocketSupport +import io.ktor.client.plugins.websocket.WebSockets as ClientWebSockets +import io.ktor.server.websocket.WebSockets as ServerWebSockets +import io.rsocket.kotlin.transport.ktor.websocket.client.RSocketSupport as ClientRSocketSupport +import io.rsocket.kotlin.transport.ktor.websocket.server.RSocketSupport as ServerRSocketSupport abstract class WebSocketTransportTest( clientEngine: HttpClientEngineFactory<*>, @@ -46,21 +46,16 @@ abstract class WebSocketTransportTest( install(ServerWebSockets) install(ServerRSocketSupport) { server = SERVER } install(Routing) { rSocket(acceptor = ACCEPTOR) } - } + }.apply { start() } override suspend fun before() { super.before() - - server.start() client = trySeveralTimes { httpClient.rSocket(port = port) } } override suspend fun after() { super.after() - - server.stop(200, 1000) testJob.cancelAndJoin() - httpClient.close() httpClient.coroutineContext.job.cancelAndJoin() } diff --git a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTests.kt b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTests.kt similarity index 95% rename from rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTests.kt rename to rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTests.kt index 005a5b292..2035f6f15 100644 --- a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/WebSocketTransportTests.kt +++ b/rsocket-transport-ktor/rsocket-transport-ktor-websocket/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/websocket/WebSocketTransportTests.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.kotlin.transport.ktor +package io.rsocket.kotlin.transport.ktor.websocket import io.ktor.client.engine.okhttp.* import io.ktor.server.jetty.* diff --git a/rsocket-transport-ktor/src/jsMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt b/rsocket-transport-ktor/src/jsMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt deleted file mode 100644 index 360633462..000000000 --- a/rsocket-transport-ktor/src/jsMain/kotlin/io/rsocket/kotlin/transport/ktor/defaultDispatcher.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.rsocket.kotlin.transport.ktor - -import kotlinx.coroutines.* - -internal actual val defaultDispatcher: CoroutineDispatcher get() = Dispatchers.Default diff --git a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/JvmTcpTransportTest.kt b/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/JvmTcpTransportTest.kt deleted file mode 100644 index 21bda15d2..000000000 --- a/rsocket-transport-ktor/src/jvmTest/kotlin/io/rsocket/kotlin/transport/ktor/JvmTcpTransportTest.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2015-2020 the original author or authors. - * - * 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. - */ - -package io.rsocket.kotlin.transport.ktor - -class JvmTcpTransportTest : TcpTransportTest() -class JvmTcpServerTest : TcpServerTest() diff --git a/settings.gradle.kts b/settings.gradle.kts index 5b2612c55..c7d3b3c8d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,12 +21,15 @@ pluginManagement { repositories { gradlePluginPortal() mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } } dependencyResolutionManagement { repositories { mavenCentral() + maven("https://maven.pkg.jetbrains.space/public/p/ktor/eap") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } } @@ -53,10 +56,13 @@ project(":rsocket-test-server").projectDir = file("rsocket-test/rsocket-test-ser include("rsocket-transport-local") -include("rsocket-transport-ktor") -include("rsocket-transport-ktor-client") -include("rsocket-transport-ktor-server") -project(":rsocket-transport-ktor-client").projectDir = file("rsocket-transport-ktor/rsocket-transport-ktor-client") -project(":rsocket-transport-ktor-server").projectDir = file("rsocket-transport-ktor/rsocket-transport-ktor-server") +//ktor transport modules +include( + "rsocket-transport-ktor", + "rsocket-transport-ktor:rsocket-transport-ktor-tcp", + "rsocket-transport-ktor:rsocket-transport-ktor-websocket", + "rsocket-transport-ktor:rsocket-transport-ktor-websocket-client", + "rsocket-transport-ktor:rsocket-transport-ktor-websocket-server", +) include("rsocket-transport-nodejs-tcp")