diff --git a/README.md b/README.md index 4bf2e9d50..809e4fc09 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Also, metadata can be associated with stream or RSocket itself ```groovy dependencies { - compile 'io.rsocket.android:rsocket-core:0.9-SNAPSHOT' + compile 'io.rsocket.kotlin:rsocket-core:0.9-SNAPSHOT' } ``` ### Transports @@ -33,8 +33,8 @@ Also, metadata can be associated with stream or RSocket itself `OkHttp` based Websockets transport (`Client` only) ```groovy dependencies { - compile 'io.rsocket.android:rsocket-transport-netty:0.9-SNAPSHOT' - compile 'io.rsocket.android:rsocket-transport-okhttp:0.9-SNAPSHOT' + compile 'io.rsocket.kotlin:rsocket-transport-netty:0.9-SNAPSHOT' + compile 'io.rsocket.kotlin:rsocket-transport-okhttp:0.9-SNAPSHOT' } ``` ### Usage @@ -51,16 +51,16 @@ Stream Metadata is optional val request = PayloadImpl.textPayload("data") ``` #### Interactions - Fire and Forget - `RSocket.fireAndForget(payload: Payload): Completable` - Request-Response - `RSocket.requestResponse(payload: Payload): Single` - Request-Stream - `RSocket.requestStream(payload: Payload): Flowable` - Request-Channel - `RSocket.requestChannel(payload: Publisher): Flowable` - Metadata-Push - `fun metadataPush(payload: Payload): Completable` + Fire and Forget + `RSocket.fireAndForget(payload: Payload): Completable` + Request-Response + `RSocket.requestResponse(payload: Payload): Single` + Request-Stream + `RSocket.requestStream(payload: Payload): Flowable` + Request-Channel + `RSocket.requestChannel(payload: Publisher): Flowable` + Metadata-Push + `fun metadataPush(payload: Payload): Completable` #### Client Client is initiator of `Connections` diff --git a/build.gradle b/build.gradle index 58a13a06d..aa262e931 100644 --- a/build.gradle +++ b/build.gradle @@ -26,10 +26,8 @@ subprojects { apply plugin: 'java-library' apply plugin: 'kotlin' apply plugin: 'maven-publish' - apply plugin: 'com.jfrog.bintray' - apply plugin: 'com.jfrog.artifactory' - group = 'io.rsocket.android' + group = 'io.rsocket.kotlin' version = '0.9-SNAPSHOT' task sourcesJar(type: Jar, dependsOn: classes) { @@ -42,9 +40,6 @@ subprojects { from javadoc.destinationDir } - tasks.bintrayUpload.dependsOn tasks.jar, tasks.sourcesJar, tasks.javadocJar - - // add javadoc/source jar tasks as artifacts artifacts { archives sourcesJar, javadocJar, jar } @@ -82,81 +77,75 @@ subprojects { } } } +} - artifactory { - publish { - contextUrl = 'https://oss.jfrog.org' - - repository { - repoKey = 'oss-snapshot-local' - //The Artifactory repository key to publish to - //when using oss.jfrog.org the credentials are from Bintray. - // For local build we expect them to be found in - //~/.gradle/gradle.properties, otherwise to be set in the build server - // Conditionalize for the users who don't have bintray credentials setup - if (project.hasProperty('bintrayUser')) { - username = project.property('bintrayUser') - password = project.property('bintrayKey') +if (project.hasProperty('bintrayUser') && project.hasProperty('bintrayKey')) { + + subprojects { + plugins.withId('com.jfrog.bintray') { + bintray { + user = project.property('bintrayUser') + key = project.property('bintrayKey') + + publications = ['maven'] + publish = true + + pkg { + repo = 'RSocket' + name = 'rsocket-kotlin' + licenses = ['Apache-2.0'] + + issueTrackerUrl = 'https://github.com/rsocket/rsocket-kotlin/issues' + websiteUrl = 'https://github.com/rsocket/rsocket-kotlin' + vcsUrl = 'https://github.com/rsocket/rsocket-kotlin.git' + githubRepo = 'rsocket/rsocket-kotlin' + githubReleaseNotesFile = 'README.md' + + version { + name = project.version + released = new Date() + vcsTag = project.version + + gpg { + sign = true + } + + mavenCentralSync { + user = project.property('sonatypeUsername') + password = project.property('sonatypePassword') + } + } } } - publications('mavenJava') - - defaults { - // Reference to Gradle publications defined in the build script. - // This is how we tell the Artifactory Plugin which artifacts should be - // published to Artifactory. - publications('mavenJava') - publishArtifacts = true - } + tasks.bintrayUpload.dependsOn tasks.jar, tasks.sourcesJar, tasks.javadocJar } - } - artifactoryPublish { - dependsOn jar - } + plugins.withId('com.jfrog.artifactory') { + artifactory { + publish { + contextUrl = 'https://oss.jfrog.org' - bintray { - if (project.hasProperty('bintrayUser')) { - user = project.property('bintrayUser') - key = project.property('bintrayKey') - } - publications = ['mavenJava'] - dryRun = false - publish = true - override = false - pkg { - repo = 'RSocket' - name = 'rsocket-android' - desc = 'RSocket' - websiteUrl = 'https://github.com/rsocket/rsocket-android' - issueTrackerUrl = 'https://github.com/rsocket/rsocket-android' - vcsUrl = 'https://github.com/rsocket/rsocket-android.git' - licenses = ['Apache-2.0'] - githubRepo = 'rsocket/rsocket-android' //Optional Github repository - githubReleaseNotesFile = 'README.md' //Optional Github readme file - if (project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')) { - def sonatypeUsername = project.property('sonatypeUsername') - def sonatypePassword = project.property('sonatypePassword') - version { - name = "v${project.version}" - vcsTag = "${project.version}" - mavenCentralSync { - sync = false - user = sonatypeUsername - password = sonatypePassword + repository { + repoKey = 'oss-snapshot-local' + username = project.property('bintrayUser') + password = project.property('bintrayKey') + } + + defaults { + publications('maven') } } } + + artifactoryPublish { + dependsOn jar + } } } } -repositories { - jcenter() -} - -description = 'RSocket-Android: stream oriented messaging passing with Reactive Stream semantics, for Android' +description = 'RSocket-kotlin: Reactive Streams over network boundary with Kotlin/Rxjava' buildScan { licenseAgreementUrl = 'https://gradle.com/terms-of-service' diff --git a/rsocket-core/build.gradle b/rsocket-core/build.gradle index 44b04fff4..53f20d79d 100644 --- a/rsocket-core/build.gradle +++ b/rsocket-core/build.gradle @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +apply plugin: 'com.jfrog.bintray' +apply plugin: 'com.jfrog.artifactory' targetCompatibility = 1.7 sourceCompatibility = 1.7 diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/Exceptions.kt b/rsocket-core/src/main/java/io/rsocket/android/exceptions/Exceptions.kt deleted file mode 100644 index 8a5f046c6..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/Exceptions.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.exceptions - -import io.rsocket.android.frame.ErrorFrameFlyweight.* - -import io.rsocket.android.Frame - -object Exceptions { - - fun from(frame: Frame): RuntimeException { - val errorCode = Frame.Error.errorCode(frame) - - val message = frame.dataUtf8 - when (errorCode) { - APPLICATION_ERROR -> return ApplicationException(message) - CANCELED -> return CancelException(message) - CONNECTION_CLOSE -> return ConnectionCloseException(message) - CONNECTION_ERROR -> return ConnectionException(message) - INVALID -> return InvalidRequestException(message) - INVALID_SETUP -> return InvalidSetupException(message) - REJECTED -> return RejectedException(message) - REJECTED_RESUME -> return RejectedResumeException(message) - REJECTED_SETUP -> return RejectedSetupException(message) - UNSUPPORTED_SETUP -> return UnsupportedSetupException(message) - else -> return InvalidRequestException( - "Invalid Error frame: $errorCode '$message'") - } - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/ErrorFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/ErrorFrameFlyweight.java deleted file mode 100644 index 884f96aed..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/ErrorFrameFlyweight.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.INTEGER_BYTES; - -import io.netty.buffer.ByteBuf; -import io.rsocket.android.FrameType; -import io.rsocket.android.exceptions.RSocketException; -import java.nio.charset.StandardCharsets; - -public class ErrorFrameFlyweight { - - private ErrorFrameFlyweight() {} - - // defined error codes - public static final int INVALID_SETUP = 0x00000001; - public static final int UNSUPPORTED_SETUP = 0x00000002; - public static final int REJECTED_SETUP = 0x00000003; - public static final int REJECTED_RESUME = 0x00000004; - public static final int CONNECTION_ERROR = 0x00000101; - public static final int CONNECTION_CLOSE = 0x00000102; - public static final int APPLICATION_ERROR = 0x00000201; - public static final int REJECTED = 0x00000202; - public static final int CANCELED = 0x00000203; - public static final int INVALID = 0x00000204; - - // relative to start of passed offset - private static final int ERROR_CODE_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - private static final int PAYLOAD_OFFSET = ERROR_CODE_FIELD_OFFSET + INTEGER_BYTES; - - public static int computeFrameLength(final int dataLength) { - int length = FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.ERROR, null, dataLength); - return length + INTEGER_BYTES; - } - - public static int encode( - final ByteBuf byteBuf, final int streamId, final int errorCode, final ByteBuf data) { - final int frameLength = computeFrameLength(data.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, 0, FrameType.ERROR, streamId); - - byteBuf.setInt(ERROR_CODE_FIELD_OFFSET, errorCode); - length += INTEGER_BYTES; - - length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); - - return length; - } - - public static int errorCodeFromException(Throwable ex) { - if (ex instanceof RSocketException) { - return ((RSocketException) ex).errorCode(); - } - - return APPLICATION_ERROR; - } - - public static int errorCode(final ByteBuf byteBuf) { - return byteBuf.getInt(ERROR_CODE_FIELD_OFFSET); - } - - public static int payloadOffset(final ByteBuf byteBuf) { - return FrameHeaderFlyweight.FRAME_HEADER_LENGTH + INTEGER_BYTES; - } - - public static String message(ByteBuf content) { - return FrameHeaderFlyweight.sliceFrameData(content).toString(StandardCharsets.UTF_8); - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/FrameHeaderFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/FrameHeaderFlyweight.java deleted file mode 100644 index 5f0162e73..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/FrameHeaderFlyweight.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.INTEGER_BYTES; -import static io.rsocket.android.frame.Utils.SHORT_BYTES; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.rsocket.android.Frame; -import io.rsocket.android.FrameType; -import javax.annotation.Nullable; - -/** - * Per connection frame flyweight. - * - *

Not the latest frame layout, but close. Does not include - fragmentation / reassembly - encode - * should remove Type param and have it as part of method name (1 encode per type?) - * - *

Not thread-safe. Assumed to be used single-threaded - */ -public class FrameHeaderFlyweight { - - private FrameHeaderFlyweight() {} - - public static final int FRAME_HEADER_LENGTH; - - private static final int FRAME_TYPE_BITS = 6; - private static final int FRAME_TYPE_SHIFT = 16 - FRAME_TYPE_BITS; - private static final int FRAME_FLAGS_MASK = 0b0000_0011_1111_1111; - - public static final int FRAME_LENGTH_SIZE = 3; - public static final int FRAME_LENGTH_MASK = 0xFFFFFF; - - private static final int FRAME_LENGTH_FIELD_OFFSET; - private static final int FRAME_TYPE_AND_FLAGS_FIELD_OFFSET; - private static final int STREAM_ID_FIELD_OFFSET; - private static final int PAYLOAD_OFFSET; - - public static final int FLAGS_I = 0b10_0000_0000; - public static final int FLAGS_M = 0b01_0000_0000; - - public static final int FLAGS_F = 0b00_1000_0000; - public static final int FLAGS_C = 0b00_0100_0000; - public static final int FLAGS_N = 0b00_0010_0000; - - static { - FRAME_LENGTH_FIELD_OFFSET = 0; - STREAM_ID_FIELD_OFFSET = FRAME_LENGTH_FIELD_OFFSET + FRAME_LENGTH_SIZE; - FRAME_TYPE_AND_FLAGS_FIELD_OFFSET = STREAM_ID_FIELD_OFFSET + INTEGER_BYTES; - PAYLOAD_OFFSET = FRAME_TYPE_AND_FLAGS_FIELD_OFFSET + SHORT_BYTES; - FRAME_HEADER_LENGTH = PAYLOAD_OFFSET; - } - - public static int computeFrameHeaderLength( - final FrameType frameType, @Nullable Integer metadataLength, final int dataLength) { - return PAYLOAD_OFFSET + computeMetadataLength(frameType, metadataLength) + dataLength; - } - - public static int encodeFrameHeader( - final ByteBuf byteBuf, - final int frameLength, - final int flags, - final FrameType frameType, - final int streamId) { - if ((frameLength & ~FRAME_LENGTH_MASK) != 0) { - throw new IllegalArgumentException("Frame length is larger than 24 bits"); - } - - // frame length field needs to be excluded from the length - encodeLength(byteBuf, FRAME_LENGTH_FIELD_OFFSET, frameLength - FRAME_LENGTH_SIZE); - - byteBuf.setInt(STREAM_ID_FIELD_OFFSET, streamId); - short typeAndFlags = (short) (frameType.getEncodedType() << FRAME_TYPE_SHIFT | (short) flags); - byteBuf.setShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET, typeAndFlags); - - return FRAME_HEADER_LENGTH; - } - - public static int encodeMetadata( - final ByteBuf byteBuf, - final FrameType frameType, - final int metadataOffset, - final @Nullable ByteBuf metadata) { - int length = 0; - - if (metadata != null) { - final int metadataLength = metadata.readableBytes(); - - int typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET); - typeAndFlags |= FLAGS_M; - byteBuf.setShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET, (short) typeAndFlags); - - if (hasMetadataLengthField(frameType)) { - encodeLength(byteBuf, metadataOffset, metadataLength); - length += FRAME_LENGTH_SIZE; - } - byteBuf.setBytes(metadataOffset + length, metadata); - length += metadataLength; - } - - return length; - } - - public static int encodeData(final ByteBuf byteBuf, final int dataOffset, final ByteBuf data) { - int length = 0; - final int dataLength = data.readableBytes(); - - if (0 < dataLength) { - byteBuf.setBytes(dataOffset, data); - length += dataLength; - } - - return length; - } - - // only used for types simple enough that they don't have their own FrameFlyweights - public static int encode( - final ByteBuf byteBuf, - final int streamId, - int flags, - final FrameType frameType, - final @Nullable ByteBuf metadata, - final ByteBuf data) { - if (Frame.Companion.isFlagSet(flags, FLAGS_M) != (metadata != null)) { - throw new IllegalStateException("bad value for metadata flag"); - } - - final int frameLength = - computeFrameHeaderLength( - frameType, metadata != null ? metadata.readableBytes() : null, data.readableBytes()); - - final FrameType outFrameType; - switch (frameType) { - case PAYLOAD: - throw new IllegalArgumentException( - "Don't encode raw PAYLOAD frames, use NEXT_COMPLETE, COMPLETE or NEXT"); - case NEXT_COMPLETE: - outFrameType = FrameType.PAYLOAD; - flags |= FLAGS_C | FLAGS_N; - break; - case COMPLETE: - outFrameType = FrameType.PAYLOAD; - flags |= FLAGS_C; - break; - case NEXT: - outFrameType = FrameType.PAYLOAD; - flags |= FLAGS_N; - break; - default: - outFrameType = frameType; - break; - } - - int length = encodeFrameHeader(byteBuf, frameLength, flags, outFrameType, streamId); - - length += encodeMetadata(byteBuf, frameType, length, metadata); - length += encodeData(byteBuf, length, data); - - return length; - } - - public static int flags(final ByteBuf byteBuf) { - short typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET); - return typeAndFlags & FRAME_FLAGS_MASK; - } - - public static FrameType frameType(final ByteBuf byteBuf) { - int typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET); - FrameType result = FrameType.Companion.from(typeAndFlags >> FRAME_TYPE_SHIFT); - - if (FrameType.PAYLOAD == result) { - final int flags = typeAndFlags & FRAME_FLAGS_MASK; - - boolean complete = FLAGS_C == (flags & FLAGS_C); - boolean next = FLAGS_N == (flags & FLAGS_N); - if (next && complete) { - result = FrameType.NEXT_COMPLETE; - } else if (complete) { - result = FrameType.COMPLETE; - } else if (next) { - result = FrameType.NEXT; - } else { - throw new IllegalArgumentException("Payload must set either or both of NEXT and COMPLETE."); - } - } - - return result; - } - - public static int streamId(final ByteBuf byteBuf) { - return byteBuf.getInt(STREAM_ID_FIELD_OFFSET); - } - - public static ByteBuf sliceFrameData(final ByteBuf byteBuf) { - final FrameType frameType = frameType(byteBuf); - final int frameLength = frameLength(byteBuf); - final int dataLength = dataLength(byteBuf, frameType); - final int dataOffset = dataOffset(byteBuf, frameType, frameLength); - ByteBuf result = Unpooled.EMPTY_BUFFER; - - if (0 < dataLength) { - result = byteBuf.slice(dataOffset, dataLength); - } - - return result; - } - - public static @Nullable ByteBuf sliceFrameMetadata(final ByteBuf byteBuf) { - final FrameType frameType = frameType(byteBuf); - final int frameLength = frameLength(byteBuf); - final @Nullable Integer metadataLength = metadataLength(byteBuf, frameType, frameLength); - - if (metadataLength == null) { - return null; - } - - int metadataOffset = metadataOffset(byteBuf); - if (hasMetadataLengthField(frameType)) { - metadataOffset += FRAME_LENGTH_SIZE; - } - ByteBuf result = Unpooled.EMPTY_BUFFER; - - if (0 < metadataLength) { - result = byteBuf.slice(metadataOffset, metadataLength); - } - - return result; - } - - public static int frameLength(final ByteBuf byteBuf) { - // frame length field was excluded from the length so we will add it to represent - // the entire block - return decodeLength(byteBuf, FRAME_LENGTH_FIELD_OFFSET) + FRAME_LENGTH_SIZE; - } - - private static int metadataFieldLength(ByteBuf byteBuf, FrameType frameType, int frameLength) { - return computeMetadataLength(frameType, metadataLength(byteBuf, frameType, frameLength)); - } - - public static @Nullable Integer metadataLength( - ByteBuf byteBuf, FrameType frameType, int frameLength) { - if (!hasMetadataLengthField(frameType)) { - return frameLength - metadataOffset(byteBuf); - } else { - return decodeMetadataLength(byteBuf, metadataOffset(byteBuf)); - } - } - - static @Nullable Integer decodeMetadataLength(final ByteBuf byteBuf, final int metadataOffset) { - int flags = flags(byteBuf); - if (FLAGS_M == (FLAGS_M & flags)) { - return decodeLength(byteBuf, metadataOffset); - } else { - return null; - } - } - - private static int computeMetadataLength(FrameType frameType, final @Nullable Integer length) { - if (!hasMetadataLengthField(frameType)) { - // Frames with only metadata does not need metadata length field - return length != null ? length : 0; - } else { - return length == null ? 0 : length + FRAME_LENGTH_SIZE; - } - } - - public static boolean hasMetadataLengthField(FrameType frameType) { - return frameType.canHaveData(); - } - - public static void encodeLength(final ByteBuf byteBuf, final int offset, final int length) { - if ((length & ~FRAME_LENGTH_MASK) != 0) { - throw new IllegalArgumentException("Length is larger than 24 bits"); - } - // Write each byte separately in reverse order, this mean we can write 1 << 23 without overflowing. - byteBuf.setByte(offset, length >> 16); - byteBuf.setByte(offset + 1, length >> 8); - byteBuf.setByte(offset + 2, length); - } - - private static int decodeLength(final ByteBuf byteBuf, final int offset) { - int length = (byteBuf.getByte(offset) & 0xFF) << 16; - length |= (byteBuf.getByte(offset + 1) & 0xFF) << 8; - length |= byteBuf.getByte(offset + 2) & 0xFF; - return length; - } - - public static int dataLength(final ByteBuf byteBuf, final FrameType frameType) { - return dataLength(byteBuf, frameType, payloadOffset(byteBuf)); - } - - static int dataLength(final ByteBuf byteBuf, final FrameType frameType, final int payloadOffset) { - final int frameLength = frameLength(byteBuf); - final int metadataLength = metadataFieldLength(byteBuf, frameType, frameLength); - - return frameLength - metadataLength - payloadOffset; - } - - public static int payloadLength(final ByteBuf byteBuf) { - final int frameLength = frameLength(byteBuf); - final int payloadOffset = payloadOffset(byteBuf); - - return frameLength - payloadOffset; - } - - private static int payloadOffset(final ByteBuf byteBuf) { - int typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET); - FrameType frameType = FrameType.Companion.from(typeAndFlags >> FRAME_TYPE_SHIFT); - int result = PAYLOAD_OFFSET; - - switch (frameType) { - case SETUP: - result = SetupFrameFlyweight.payloadOffset(byteBuf); - break; - case ERROR: - result = ErrorFrameFlyweight.payloadOffset(byteBuf); - break; - case LEASE: - result = LeaseFrameFlyweight.payloadOffset(byteBuf); - break; - case KEEPALIVE: - result = KeepaliveFrameFlyweight.payloadOffset(byteBuf); - break; - case REQUEST_RESPONSE: - case FIRE_AND_FORGET: - case REQUEST_STREAM: - case REQUEST_CHANNEL: - result = RequestFrameFlyweight.payloadOffset(frameType, byteBuf); - break; - case REQUEST_N: - result = RequestNFrameFlyweight.payloadOffset(byteBuf); - break; - } - - return result; - } - - public static int metadataOffset(final ByteBuf byteBuf) { - return payloadOffset(byteBuf); - } - - public static int dataOffset(ByteBuf byteBuf, FrameType frameType, int frameLength) { - return payloadOffset(byteBuf) + metadataFieldLength(byteBuf, frameType, frameLength); - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/KeepaliveFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/KeepaliveFrameFlyweight.java deleted file mode 100644 index 01d3bf9f6..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/KeepaliveFrameFlyweight.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.*; - -import io.netty.buffer.ByteBuf; -import io.rsocket.android.FrameType; - -public class KeepaliveFrameFlyweight { - public static final int FLAGS_KEEPALIVE_R = 0b00_1000_0000; - - private KeepaliveFrameFlyweight() {} - - private static final int LAST_POSITION_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - private static final int PAYLOAD_OFFSET = LAST_POSITION_OFFSET + LONG_BYTES; - - public static int computeFrameLength(final int dataLength) { - return FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.SETUP, null, dataLength) - + LONG_BYTES; - } - - public static int encode(final ByteBuf byteBuf, int flags, final ByteBuf data) { - final int frameLength = computeFrameLength(data.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, FrameType.KEEPALIVE, 0); - - // We don't support resumability, last position is always zero - byteBuf.setLong(length, 0); - length += LONG_BYTES; - - length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); - - return length; - } - - public static int payloadOffset(final ByteBuf byteBuf) { - return PAYLOAD_OFFSET; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/LeaseFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/LeaseFrameFlyweight.java deleted file mode 100644 index a7afa0225..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/LeaseFrameFlyweight.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.*; - -import io.netty.buffer.ByteBuf; -import io.rsocket.android.FrameType; - -public class LeaseFrameFlyweight { - private LeaseFrameFlyweight() {} - - // relative to start of passed offset - private static final int TTL_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - private static final int NUM_REQUESTS_FIELD_OFFSET = TTL_FIELD_OFFSET + INTEGER_BYTES; - private static final int PAYLOAD_OFFSET = NUM_REQUESTS_FIELD_OFFSET + INTEGER_BYTES; - - public static int computeFrameLength(final int metadataLength) { - int length = FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.LEASE, metadataLength, 0); - return length + INTEGER_BYTES * 2; - } - - public static int encode( - final ByteBuf byteBuf, final int ttl, final int numRequests, final ByteBuf metadata) { - final int frameLength = computeFrameLength(metadata.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, 0, FrameType.LEASE, 0); - - byteBuf.setInt(TTL_FIELD_OFFSET, ttl); - byteBuf.setInt(NUM_REQUESTS_FIELD_OFFSET, numRequests); - - length += INTEGER_BYTES * 2; - length += FrameHeaderFlyweight.encodeMetadata(byteBuf, FrameType.LEASE, length, metadata); - - return length; - } - - public static int ttl(final ByteBuf byteBuf) { - return byteBuf.getInt(TTL_FIELD_OFFSET); - } - - public static int numRequests(final ByteBuf byteBuf) { - return byteBuf.getInt(NUM_REQUESTS_FIELD_OFFSET); - } - - public static int payloadOffset(final ByteBuf byteBuf) { - return PAYLOAD_OFFSET; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/RequestFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/RequestFrameFlyweight.java deleted file mode 100644 index 01cd1e1fc..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/RequestFrameFlyweight.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.INTEGER_BYTES; - -import io.netty.buffer.ByteBuf; -import io.rsocket.android.Frame; -import io.rsocket.android.FrameType; -import javax.annotation.Nullable; - -public class RequestFrameFlyweight { - - private RequestFrameFlyweight() {} - - // relative to start of passed offset - private static final int INITIAL_REQUEST_N_FIELD_OFFSET = - FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - - public static int computeFrameLength( - final FrameType type, final @Nullable Integer metadataLength, final int dataLength) { - int length = FrameHeaderFlyweight.computeFrameHeaderLength(type, metadataLength, dataLength); - - if (type.hasInitialRequestN()) { - length += INTEGER_BYTES; - } - - return length; - } - - public static int encode( - final ByteBuf byteBuf, - final int streamId, - int flags, - final FrameType type, - final int initialRequestN, - final @Nullable ByteBuf metadata, - final ByteBuf data) { - if (Frame.Companion.isFlagSet(flags, FrameHeaderFlyweight.FLAGS_M) != (metadata != null)) { - throw new IllegalArgumentException("metadata flag set incorrectly"); - } - - final int frameLength = - computeFrameLength( - type, metadata != null ? metadata.readableBytes() : null, data.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, type, streamId); - - byteBuf.setInt(INITIAL_REQUEST_N_FIELD_OFFSET, initialRequestN); - length += INTEGER_BYTES; - - length += FrameHeaderFlyweight.encodeMetadata(byteBuf, type, length, metadata); - length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); - - return length; - } - - public static int encode( - final ByteBuf byteBuf, - final int streamId, - final int flags, - final FrameType type, - final @Nullable ByteBuf metadata, - final ByteBuf data) { - if (Frame.Companion.isFlagSet(flags, FrameHeaderFlyweight.FLAGS_M) != (metadata != null)) { - throw new IllegalArgumentException("metadata flag set incorrectly"); - } - if (type.hasInitialRequestN()) { - throw new AssertionError(type + " must not be encoded without initial request N"); - } - final int frameLength = - computeFrameLength( - type, metadata != null ? metadata.readableBytes() : null, data.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, type, streamId); - - length += FrameHeaderFlyweight.encodeMetadata(byteBuf, type, length, metadata); - length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); - - return length; - } - - public static int initialRequestN(final ByteBuf byteBuf) { - return byteBuf.getInt(INITIAL_REQUEST_N_FIELD_OFFSET); - } - - public static int payloadOffset(final FrameType type, final ByteBuf byteBuf) { - int result = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - - if (type.hasInitialRequestN()) { - result += INTEGER_BYTES; - } - - return result; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/RequestNFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/RequestNFrameFlyweight.java deleted file mode 100644 index c43dbd981..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/RequestNFrameFlyweight.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.Utils.*; - -import io.netty.buffer.ByteBuf; -import io.rsocket.android.FrameType; - -public class RequestNFrameFlyweight { - private RequestNFrameFlyweight() {} - - // relative to start of passed offset - private static final int REQUEST_N_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - - public static int computeFrameLength() { - int length = FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.REQUEST_N, 0, 0); - - return length + INTEGER_BYTES; - } - - public static int encode(final ByteBuf byteBuf, final int streamId, final int requestN) { - final int frameLength = computeFrameLength(); - - int length = - FrameHeaderFlyweight.encodeFrameHeader( - byteBuf, frameLength, 0, FrameType.REQUEST_N, streamId); - - byteBuf.setInt(REQUEST_N_FIELD_OFFSET, requestN); - - return length + INTEGER_BYTES; - } - - public static int requestN(final ByteBuf byteBuf) { - return byteBuf.getInt(REQUEST_N_FIELD_OFFSET); - } - - public static int payloadOffset(final ByteBuf byteBuf) { - return FrameHeaderFlyweight.FRAME_HEADER_LENGTH + INTEGER_BYTES; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/SetupFrameFlyweight.java b/rsocket-core/src/main/java/io/rsocket/android/frame/SetupFrameFlyweight.java deleted file mode 100644 index b8344860b..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/SetupFrameFlyweight.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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.android.frame; - -import static io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_M; -import static io.rsocket.android.frame.Utils.INTEGER_BYTES; -import static io.rsocket.android.frame.Utils.SHORT_BYTES; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.rsocket.android.FrameType; -import java.nio.charset.StandardCharsets; - -public class SetupFrameFlyweight { - private SetupFrameFlyweight() {} - - public static final int FLAGS_RESUME_ENABLE = 0b00_1000_0000; - public static final int FLAGS_WILL_HONOR_LEASE = 0b00_0100_0000; - - public static final int VALID_FLAGS = - FLAGS_RESUME_ENABLE | FLAGS_WILL_HONOR_LEASE | FLAGS_M; - - public static final int CURRENT_VERSION = VersionFlyweight.encode(1, 0); - - // relative to start of passed offset - private static final int VERSION_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH; - private static final int KEEPALIVE_INTERVAL_FIELD_OFFSET = VERSION_FIELD_OFFSET + INTEGER_BYTES; - private static final int MAX_LIFETIME_FIELD_OFFSET = - KEEPALIVE_INTERVAL_FIELD_OFFSET + INTEGER_BYTES; - private static final int VARIABLE_DATA_OFFSET = MAX_LIFETIME_FIELD_OFFSET + INTEGER_BYTES; - - public static int computeFrameLength( - final int flags, - final String metadataMimeType, - final String dataMimeType, - final int metadataLength, - final int dataLength) { - return computeFrameLength(flags, 0, metadataMimeType, dataMimeType, metadataLength, dataLength); - } - - private static int computeFrameLength( - final int flags, - final int resumeTokenLength, - final String metadataMimeType, - final String dataMimeType, - final int metadataLength, - final int dataLength) { - int length = - FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.SETUP, metadataLength, dataLength); - - length += INTEGER_BYTES * 3; - - if ((flags & FLAGS_RESUME_ENABLE) != 0) { - length += SHORT_BYTES + resumeTokenLength; - } - - length += 1 + metadataMimeType.getBytes(StandardCharsets.UTF_8).length; - length += 1 + dataMimeType.getBytes(StandardCharsets.UTF_8).length; - - return length; - } - - public static int encode( - final ByteBuf byteBuf, - int flags, - int version, - final int keepaliveInterval, - final int maxLifetime, - final String metadataMimeType, - final String dataMimeType, - final ByteBuf metadata, - final ByteBuf data) { - - return encode( - byteBuf, - flags, - version, - keepaliveInterval, - maxLifetime, - Unpooled.EMPTY_BUFFER, - metadataMimeType, - dataMimeType, - metadata, - data); - } - - // Only exposed for testing, other code shouldn't create frames with resumption tokens for now - static int encode( - final ByteBuf byteBuf, - int flags, - int version, - final int keepaliveInterval, - final int maxLifetime, - final ByteBuf resumeToken, - final String metadataMimeType, - final String dataMimeType, - final ByteBuf metadata, - final ByteBuf data) { - final int frameLength = - computeFrameLength( - flags, - resumeToken.readableBytes(), - metadataMimeType, - dataMimeType, - metadata.readableBytes(), - data.readableBytes()); - - int length = - FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, FrameType.SETUP, 0); - - byteBuf.setInt(VERSION_FIELD_OFFSET, version); - byteBuf.setInt(KEEPALIVE_INTERVAL_FIELD_OFFSET, keepaliveInterval); - byteBuf.setInt(MAX_LIFETIME_FIELD_OFFSET, maxLifetime); - - length += INTEGER_BYTES * 3; - - if ((flags & FLAGS_RESUME_ENABLE) != 0) { - byteBuf.setShort(length, resumeToken.readableBytes()); - length += SHORT_BYTES; - int resumeTokenLength = resumeToken.readableBytes(); - byteBuf.setBytes(length, resumeToken, resumeTokenLength); - length += resumeTokenLength; - } - - length += putMimeType(byteBuf, length, metadataMimeType); - length += putMimeType(byteBuf, length, dataMimeType); - - length += FrameHeaderFlyweight.encodeMetadata(byteBuf, FrameType.SETUP, length, metadata); - length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); - - return length; - } - - public static int version(final ByteBuf byteBuf) { - return byteBuf.getInt(VERSION_FIELD_OFFSET); - } - - public static int keepaliveInterval(final ByteBuf byteBuf) { - return byteBuf.getInt(KEEPALIVE_INTERVAL_FIELD_OFFSET); - } - - public static int maxLifetime(final ByteBuf byteBuf) { - return byteBuf.getInt(MAX_LIFETIME_FIELD_OFFSET); - } - - public static String metadataMimeType(final ByteBuf byteBuf) { - final byte[] bytes = getMimeType(byteBuf, metadataMimetypeOffset(byteBuf)); - return new String(bytes, StandardCharsets.UTF_8); - } - - public static String dataMimeType(final ByteBuf byteBuf) { - int fieldOffset = metadataMimetypeOffset(byteBuf); - - fieldOffset += 1 + byteBuf.getByte(fieldOffset); - - final byte[] bytes = getMimeType(byteBuf, fieldOffset); - return new String(bytes, StandardCharsets.UTF_8); - } - - public static int payloadOffset(final ByteBuf byteBuf) { - int fieldOffset = metadataMimetypeOffset(byteBuf); - - final int metadataMimeTypeLength = byteBuf.getByte(fieldOffset); - fieldOffset += 1 + metadataMimeTypeLength; - - final int dataMimeTypeLength = byteBuf.getByte(fieldOffset); - fieldOffset += 1 + dataMimeTypeLength; - - return fieldOffset; - } - - private static int metadataMimetypeOffset(final ByteBuf byteBuf) { - return VARIABLE_DATA_OFFSET + resumeTokenTotalLength(byteBuf); - } - - private static int resumeTokenTotalLength(final ByteBuf byteBuf) { - if ((FrameHeaderFlyweight.flags(byteBuf) & FLAGS_RESUME_ENABLE) == 0) { - return 0; - } else { - return SHORT_BYTES + byteBuf.getShort(VARIABLE_DATA_OFFSET); - } - } - - private static int putMimeType( - final ByteBuf byteBuf, final int fieldOffset, final String mimeType) { - byte[] bytes = mimeType.getBytes(StandardCharsets.UTF_8); - - byteBuf.setByte(fieldOffset, (byte) bytes.length); - byteBuf.setBytes(fieldOffset + 1, bytes); - - return 1 + bytes.length; - } - - private static byte[] getMimeType(final ByteBuf byteBuf, final int fieldOffset) { - final int length = byteBuf.getByte(fieldOffset); - final byte[] bytes = new byte[length]; - - byteBuf.getBytes(fieldOffset + 1, bytes); - return bytes; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/Utils.java b/rsocket-core/src/main/java/io/rsocket/android/frame/Utils.java deleted file mode 100644 index 62418785d..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/Utils.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.rsocket.android.frame; - -class Utils { - static final int SHORT_BYTES = toBytes(Short.SIZE); - static final int INTEGER_BYTES = toBytes(Integer.SIZE); - static final int LONG_BYTES = toBytes(Long.SIZE); - - private static int toBytes(int size) { - return size / Byte.SIZE; - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/package-info.java b/rsocket-core/src/main/java/io/rsocket/android/frame/package-info.java deleted file mode 100644 index fa836167f..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2016 Netflix, Inc. - * - * 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. - */ - -@javax.annotation.ParametersAreNonnullByDefault -package io.rsocket.android.frame; diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/ExceptionUtil.kt b/rsocket-core/src/main/java/io/rsocket/android/util/ExceptionUtil.kt deleted file mode 100644 index 05b106500..000000000 --- a/rsocket-core/src/main/java/io/rsocket/android/util/ExceptionUtil.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.rsocket.android.util - -object ExceptionUtil { - fun noStacktrace(ex: T): T { - ex.stackTrace = arrayOf(StackTraceElement(ex.javaClass.name, "", null, -1)) - return ex - } -} diff --git a/rsocket-core/src/main/java/io/rsocket/android/Availability.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Availability.kt similarity index 96% rename from rsocket-core/src/main/java/io/rsocket/android/Availability.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Availability.kt index 220aa0795..ba5db8e17 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Availability.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Availability.kt @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin interface Availability { diff --git a/rsocket-core/src/main/java/io/rsocket/android/Closeable.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Closeable.kt similarity index 98% rename from rsocket-core/src/main/java/io/rsocket/android/Closeable.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Closeable.kt index edf12a00e..2b615960d 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Closeable.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Closeable.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/PayloadImpl.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/DefaultPayload.kt similarity index 76% rename from rsocket-core/src/main/java/io/rsocket/android/util/PayloadImpl.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/DefaultPayload.kt index f5bbd2de3..d17883681 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/PayloadImpl.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/DefaultPayload.kt @@ -14,10 +14,8 @@ * limitations under the License. */ -package io.rsocket.android.util +package io.rsocket.kotlin -import io.rsocket.android.Frame -import io.rsocket.android.Payload import java.nio.ByteBuffer import java.nio.charset.Charset import java.nio.charset.StandardCharsets @@ -26,11 +24,14 @@ import java.nio.charset.StandardCharsets * An implementation of [Payload]. This implementation is **not** thread-safe, and hence * any method can not be invoked concurrently. */ -class PayloadImpl @JvmOverloads constructor(data: ByteBuffer, - private val _metadata: ByteBuffer?, - private val reusable: Boolean = true) : Payload { +class DefaultPayload @JvmOverloads constructor(data: ByteBuffer, + private val _metadata: ByteBuffer?, + private val reusable: Boolean = true) + : Payload { private val dataStartPosition: Int = if (reusable) data.position() else 0 - private val metadataStartPosition: Int = if (reusable && _metadata != null) _metadata.position() else 0 + private val metadataStartPosition: Int = + if (reusable && _metadata != null) + _metadata.position() else 0 constructor(frame: Frame) : this( frame.data, @@ -42,9 +43,9 @@ class PayloadImpl @JvmOverloads constructor(data: ByteBuffer, metadata, StandardCharsets.UTF_8) - @JvmOverloads constructor(data: String, dataCharset: Charset = Charset.defaultCharset()) : this( - dataCharset.encode(data), - null) + @JvmOverloads constructor(data: String, + dataCharset: Charset = Charset.defaultCharset()) + : this(dataCharset.encode(data), null) constructor( data: String, @@ -84,25 +85,27 @@ class PayloadImpl @JvmOverloads constructor(data: ByteBuffer, companion object { - val EMPTY = PayloadImpl( + val EMPTY = DefaultPayload( Frame.NULL_BYTEBUFFER, Frame.NULL_BYTEBUFFER, false) /** - * Static factory method for a text payload. Mainly looks better than "new PayloadImpl(data)" + * Static factory method for a text payload. Mainly looks better than + * "new DefaultPayload(data)" * * @param data the data of the payload. * @return a payload. */ - fun textPayload(data: String): Payload = PayloadImpl(data) + fun textPayload(data: String): Payload = DefaultPayload(data) /** - * Static factory method for a text payload. Mainly looks better than "new PayloadImpl(data, - * metadata)" + * Static factory method for a text payload. Mainly looks better than + * "new DefaultPayload(data, metadata)" * * @param data the data of the payload. * @param metadata the metadata for the payload. * @return a payload. */ - fun textPayload(data: String, metadata: String?): Payload = PayloadImpl(data, metadata) + fun textPayload(data: String, metadata: String?): Payload = + DefaultPayload(data, metadata) } } diff --git a/rsocket-core/src/main/java/io/rsocket/android/DuplexConnection.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/DuplexConnection.kt similarity index 99% rename from rsocket-core/src/main/java/io/rsocket/android/DuplexConnection.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/DuplexConnection.kt index 637b0d254..e2f719f59 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/DuplexConnection.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/DuplexConnection.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Flowable diff --git a/rsocket-core/src/main/java/io/rsocket/android/Duration.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Duration.kt similarity index 68% rename from rsocket-core/src/main/java/io/rsocket/android/Duration.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Duration.kt index 7666780a6..701699847 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Duration.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Duration.kt @@ -1,4 +1,4 @@ -package io.rsocket.android +package io.rsocket.kotlin import java.util.concurrent.TimeUnit @@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit * Created by Maksym Ostroverkhov on 27.10.17. */ -data class Duration(val value: Long, val unit: TimeUnit) { +data class Duration(private val value: Long, val unit: TimeUnit) { val millis = unit.toMillis(value) @@ -18,6 +18,10 @@ data class Duration(val value: Long, val unit: TimeUnit) { fun ofSeconds(n: Int) = Duration(n.toLong(), TimeUnit.SECONDS) + fun ofMinutes(n: Long) = Duration(n, TimeUnit.MINUTES) + + fun ofMinutes(n: Int) = Duration(n.toLong(), TimeUnit.MINUTES) + fun ofMillis(n: Long) = Duration(n, TimeUnit.MILLISECONDS) fun ofMillis(n: Int) = Duration(n.toLong(), TimeUnit.MILLISECONDS) diff --git a/rsocket-core/src/main/java/io/rsocket/android/Frame.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Frame.kt similarity index 99% rename from rsocket-core/src/main/java/io/rsocket/android/Frame.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Frame.kt index 86dee8175..5921cce41 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Frame.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Frame.kt @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin -import com.sun.org.apache.xpath.internal.operations.Bool import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBufAllocator import io.netty.buffer.ByteBufHolder @@ -24,8 +23,8 @@ import io.netty.util.IllegalReferenceCountException import io.netty.util.Recycler import io.netty.util.Recycler.Handle import io.netty.util.ResourceLeakDetector -import io.rsocket.android.frame.* -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_M +import io.rsocket.kotlin.internal.frame.* +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_M import org.slf4j.LoggerFactory import java.nio.ByteBuffer import java.nio.charset.StandardCharsets diff --git a/rsocket-core/src/main/java/io/rsocket/android/FrameType.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/FrameType.kt similarity index 99% rename from rsocket-core/src/main/java/io/rsocket/android/FrameType.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/FrameType.kt index 9900be92d..3b2a7a3b4 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/FrameType.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/FrameType.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin /** Types of [Frame] that can be sent. */ enum class FrameType(val encodedType: Int, private val flags: Int = 0) { diff --git a/rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorOptions.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/InterceptorOptions.kt similarity index 56% rename from rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorOptions.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/InterceptorOptions.kt index bc9cbe8fa..9c73d7cb6 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorOptions.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/InterceptorOptions.kt @@ -1,4 +1,7 @@ -package io.rsocket.android.plugins +package io.rsocket.kotlin + +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor +import io.rsocket.kotlin.interceptors.RSocketInterceptor interface InterceptorOptions { diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/KeepAlive.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAlive.kt similarity index 60% rename from rsocket-core/src/main/java/io/rsocket/android/util/KeepAlive.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAlive.kt index d67b6c633..6013ceff4 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/KeepAlive.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAlive.kt @@ -1,6 +1,4 @@ -package io.rsocket.android.util - -import io.rsocket.android.Duration +package io.rsocket.kotlin interface KeepAlive { diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/KeepAliveOptions.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAliveOptions.kt similarity index 93% rename from rsocket-core/src/main/java/io/rsocket/android/util/KeepAliveOptions.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAliveOptions.kt index 6518b3398..ab92825d3 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/KeepAliveOptions.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/KeepAliveOptions.kt @@ -1,6 +1,4 @@ -package io.rsocket.android.util - -import io.rsocket.android.Duration +package io.rsocket.kotlin class KeepAliveOptions : KeepAlive { private var interval: Duration = Duration.ofMillis(100) diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/MediaType.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaType.kt similarity index 74% rename from rsocket-core/src/main/java/io/rsocket/android/util/MediaType.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaType.kt index deda17871..bbe67045e 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/MediaType.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaType.kt @@ -1,4 +1,4 @@ -package io.rsocket.android.util +package io.rsocket.kotlin interface MediaType { diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/MediaTypeOptions.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaTypeOptions.kt similarity index 96% rename from rsocket-core/src/main/java/io/rsocket/android/util/MediaTypeOptions.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaTypeOptions.kt index 6d2b260d9..01a6d7bab 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/MediaTypeOptions.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/MediaTypeOptions.kt @@ -1,4 +1,4 @@ -package io.rsocket.android.util +package io.rsocket.kotlin class MediaTypeOptions : MediaType { private var dataMimeType: String = "application/binary" diff --git a/rsocket-core/src/main/java/io/rsocket/android/Payload.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Payload.kt similarity index 91% rename from rsocket-core/src/main/java/io/rsocket/android/Payload.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Payload.kt index 4d1e7ad8d..782976cb3 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Payload.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Payload.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin import java.nio.ByteBuffer import java.nio.charset.StandardCharsets @@ -21,15 +21,16 @@ import java.nio.charset.StandardCharsets /** Payload of a [Frame]. */ interface Payload { /** - * Returns whether the payload has metadata, useful for tell if metadata is empty or not present. + * Returns whether the payload has metadata, useful for tell if metadata is + * empty or not present. * * @return whether payload has non-null (possibly empty) metadata */ fun hasMetadata(): Boolean /** - * Returns the Payload metadata. Always non-null, check [.hasMetadata] to differentiate - * null from "". + * Returns the Payload metadata. Always non-null, check [.hasMetadata] to + * differentiate null from "". * * @return payload metadata. */ diff --git a/rsocket-core/src/main/java/io/rsocket/android/RSocket.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocket.kt similarity index 95% rename from rsocket-core/src/main/java/io/rsocket/android/RSocket.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocket.kt index ea2f6fe66..9d3a9da10 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/RSocket.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocket.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Flowable @@ -22,7 +22,8 @@ import io.reactivex.Single import org.reactivestreams.Publisher /** - * A contract providing different interaction models for [RSocket protocol](https://github.com/RSocket/reactivesocket/blob/master/Protocol.md). + * A contract providing different interaction models for [RSocket protocol] + * (https://github.com/RSocket/reactivesocket/blob/master/Protocol.md). */ interface RSocket : Availability, Closeable { diff --git a/rsocket-core/src/main/java/io/rsocket/android/RSocketFactory.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocketFactory.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/RSocketFactory.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocketFactory.kt index c25124db6..4a682886e 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/RSocketFactory.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/RSocketFactory.kt @@ -14,21 +14,16 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Single -import io.rsocket.android.fragmentation.FragmentationInterceptor -import io.rsocket.android.internal.* -import io.rsocket.android.plugins.GlobalInterceptors -import io.rsocket.android.plugins.InterceptorOptions -import io.rsocket.android.plugins.InterceptorRegistry -import io.rsocket.android.transport.ClientTransport -import io.rsocket.android.transport.ServerTransport -import io.rsocket.android.util.KeepAlive -import io.rsocket.android.util.KeepAliveOptions -import io.rsocket.android.util.MediaTypeOptions -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.interceptors.GlobalInterceptors +import io.rsocket.kotlin.internal.* +import io.rsocket.kotlin.internal.fragmentation.FragmentationInterceptor +import io.rsocket.kotlin.transport.ClientTransport +import io.rsocket.kotlin.transport.ServerTransport +import io.rsocket.kotlin.util.AbstractRSocket /** Factory for creating RSocket clients and servers. */ object RSocketFactory { @@ -54,7 +49,7 @@ object RSocketFactory { private var mtu = 0 private val interceptors = GlobalInterceptors.create() private var flags = 0 - private var setupPayload: Payload = PayloadImpl.EMPTY + private var setupPayload: Payload = DefaultPayload.EMPTY private val keepAlive = KeepAliveOptions() private val mediaType = MediaTypeOptions() private var streamRequestLimit = defaultStreamRequestLimit diff --git a/rsocket-core/src/main/java/io/rsocket/android/Setup.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Setup.kt similarity index 92% rename from rsocket-core/src/main/java/io/rsocket/android/Setup.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/Setup.kt index dc9f75742..291946a54 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/Setup.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/Setup.kt @@ -13,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_M +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_M -import io.rsocket.android.frame.SetupFrameFlyweight -import io.rsocket.android.util.KeepAlive +import io.rsocket.kotlin.internal.frame.SetupFrameFlyweight import java.nio.ByteBuffer /** - * Exposed to server for determination of RequestHandler based on mime types and SETUP metadata/data + * Exposed to server for determination of RequestHandler based on mime types + * and SETUP metadata/data */ abstract class Setup : Payload, KeepAlive { diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ApplicationException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ApplicationException.kt similarity index 85% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/ApplicationException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ApplicationException.kt index b58ed7edb..79855fcf1 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ApplicationException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ApplicationException.kt @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class ApplicationException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.APPLICATION_ERROR diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/CancelException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/CancelException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/CancelException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/CancelException.kt index 7c4c7587a..87af9095e 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/CancelException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/CancelException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class CancelException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.CANCELED diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ChannelRequestException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ChannelRequestException.kt similarity index 86% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/ChannelRequestException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ChannelRequestException.kt index 78d0519d2..ede7ac4f7 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ChannelRequestException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ChannelRequestException.kt @@ -1,4 +1,4 @@ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions class ChannelRequestException(message: String, cause: Throwable) : RuntimeException(message, cause) { diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionCloseException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionCloseException.kt similarity index 57% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionCloseException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionCloseException.kt index fdd04b470..4eb97e851 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionCloseException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionCloseException.kt @@ -1,11 +1,11 @@ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class ConnectionCloseException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.CONNECTION_CLOSE diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionException.kt index 66b8676e3..3b7e3acbd 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/ConnectionException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/ConnectionException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class ConnectionException : RSocketException, Retryable { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.CONNECTION_ERROR diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Exceptions.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Exceptions.kt new file mode 100644 index 000000000..b8f8b06fa --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Exceptions.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.exceptions + +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.APPLICATION_ERROR +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CANCELED +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CONNECTION_CLOSE +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CONNECTION_ERROR +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.INVALID +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.INVALID_SETUP +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED_RESUME +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED_SETUP +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.UNSUPPORTED_SETUP + +object Exceptions { + + fun from(frame: Frame): RuntimeException { + val message = frame.dataUtf8 + val errorCode = Frame.Error.errorCode(frame) + return when (errorCode) { + APPLICATION_ERROR -> ApplicationException(message) + CANCELED -> CancelException(message) + CONNECTION_CLOSE -> ConnectionCloseException(message) + CONNECTION_ERROR -> ConnectionException(message) + INVALID -> InvalidRequestException(message) + INVALID_SETUP -> InvalidSetupException(message) + REJECTED -> RejectedException(message) + REJECTED_RESUME -> RejectedResumeException(message) + REJECTED_SETUP -> RejectedSetupException(message) + UNSUPPORTED_SETUP -> UnsupportedSetupException(message) + else -> InvalidRequestException( + "Invalid Error frame: $errorCode '$message'") + } + } +} diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidRequestException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidRequestException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidRequestException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidRequestException.kt index 17e44c37c..d7b4131a2 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidRequestException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidRequestException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class InvalidRequestException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.INVALID diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidSetupException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidSetupException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidSetupException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidSetupException.kt index 8c0a0c789..d40851181 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/InvalidSetupException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/InvalidSetupException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class InvalidSetupException : SetupException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.INVALID_SETUP diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/NoAvailableRSocketException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/NoAvailableRSocketException.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/NoAvailableRSocketException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/NoAvailableRSocketException.kt index 1d8cc5879..81687ccee 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/NoAvailableRSocketException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/NoAvailableRSocketException.kt @@ -13,6 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions class NoAvailableRSocketException : Exception() diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RSocketException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RSocketException.kt similarity index 59% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/RSocketException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RSocketException.kt index e19af8362..ecb355906 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RSocketException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RSocketException.kt @@ -1,9 +1,9 @@ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions abstract class RSocketException : RuntimeException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) abstract fun errorCode(): Int } diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedException.kt index 9e8e76ff9..42e23f82c 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class RejectedException : RSocketException, Retryable { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.REJECTED diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedResumeException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedResumeException.kt similarity index 57% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedResumeException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedResumeException.kt index d9c0113f8..4e26a56bf 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedResumeException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedResumeException.kt @@ -1,11 +1,11 @@ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class RejectedResumeException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.REJECTED_RESUME diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedSetupException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedSetupException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedSetupException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedSetupException.kt index dedc73e94..126e6ebea 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/RejectedSetupException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/RejectedSetupException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class RejectedSetupException : SetupException, Retryable { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.REJECTED_SETUP diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/Retryable.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Retryable.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/Retryable.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Retryable.kt index 1d51e3277..89ee3dee5 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/Retryable.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/Retryable.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions /** Marker interface only */ interface Retryable diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/SetupException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/SetupException.kt similarity index 87% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/SetupException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/SetupException.kt index eae63ae3d..4075ebe16 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/SetupException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/SetupException.kt @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions abstract class SetupException : RSocketException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) } diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/TimeoutException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TimeoutException.kt similarity index 95% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/TimeoutException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TimeoutException.kt index ce558580e..7b0c72a44 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/TimeoutException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TimeoutException.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions class TimeoutException : Exception() { companion object { diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/TransportException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TransportException.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/TransportException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TransportException.kt index 68510720d..a99494746 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/TransportException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/TransportException.kt @@ -13,6 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions class TransportException(t: Throwable) : Throwable(t) diff --git a/rsocket-core/src/main/java/io/rsocket/android/exceptions/UnsupportedSetupException.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/UnsupportedSetupException.kt similarity index 83% rename from rsocket-core/src/main/java/io/rsocket/android/exceptions/UnsupportedSetupException.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/UnsupportedSetupException.kt index 26c440e69..a25735fd7 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/exceptions/UnsupportedSetupException.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/exceptions/UnsupportedSetupException.kt @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.exceptions +package io.rsocket.kotlin.exceptions -import io.rsocket.android.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight class UnsupportedSetupException : SetupException { - constructor(message: String) : super(message) {} + constructor(message: String) : super(message) - constructor(message: String, cause: Throwable) : super(message, cause) {} + constructor(message: String, cause: Throwable) : super(message, cause) override fun errorCode(): Int { return ErrorFrameFlyweight.UNSUPPORTED_SETUP diff --git a/rsocket-core/src/main/java/io/rsocket/android/plugins/DuplexConnectionInterceptor.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/DuplexConnectionInterceptor.kt similarity index 91% rename from rsocket-core/src/main/java/io/rsocket/android/plugins/DuplexConnectionInterceptor.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/DuplexConnectionInterceptor.kt index f7e298e75..4afa18a83 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/plugins/DuplexConnectionInterceptor.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/DuplexConnectionInterceptor.kt @@ -14,9 +14,9 @@ * limitations under the License. */ -package io.rsocket.android.plugins +package io.rsocket.kotlin.interceptors -import io.rsocket.android.DuplexConnection +import io.rsocket.kotlin.DuplexConnection interface DuplexConnectionInterceptor : (DuplexConnectionInterceptor.Type, DuplexConnection) -> DuplexConnection { diff --git a/rsocket-core/src/main/java/io/rsocket/android/plugins/GlobalInterceptors.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/GlobalInterceptors.kt similarity index 86% rename from rsocket-core/src/main/java/io/rsocket/android/plugins/GlobalInterceptors.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/GlobalInterceptors.kt index deec54e3b..96a5a52a1 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/plugins/GlobalInterceptors.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/GlobalInterceptors.kt @@ -14,9 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.plugins +package io.rsocket.kotlin.interceptors -/** JVM wide plugins for RSocket */ +import io.rsocket.kotlin.InterceptorOptions +import io.rsocket.kotlin.internal.InterceptorRegistry + +/** JVM wide interceptors for RSocket */ object GlobalInterceptors : InterceptorOptions { private val DEFAULT = InterceptorRegistry() diff --git a/rsocket-core/src/main/java/io/rsocket/android/plugins/RSocketInterceptor.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/RSocketInterceptor.kt similarity index 90% rename from rsocket-core/src/main/java/io/rsocket/android/plugins/RSocketInterceptor.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/RSocketInterceptor.kt index edf76faaf..f207835d5 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/plugins/RSocketInterceptor.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/interceptors/RSocketInterceptor.kt @@ -14,8 +14,8 @@ * limitations under the License. */ -package io.rsocket.android.plugins +package io.rsocket.kotlin.interceptors -import io.rsocket.android.RSocket +import io.rsocket.kotlin.RSocket interface RSocketInterceptor : (RSocket) -> RSocket diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/ClientServiceHandler.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ClientServiceHandler.kt similarity index 90% rename from rsocket-core/src/main/java/io/rsocket/android/internal/ClientServiceHandler.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ClientServiceHandler.kt index e71e54b71..ae5bf1d94 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/ClientServiceHandler.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ClientServiceHandler.kt @@ -1,13 +1,13 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.netty.buffer.Unpooled import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.disposables.Disposable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.exceptions.ConnectionException -import io.rsocket.android.util.KeepAlive +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.exceptions.ConnectionException +import io.rsocket.kotlin.KeepAlive import java.util.concurrent.TimeUnit internal class ClientServiceHandler(serviceConnection: DuplexConnection, diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/ConnectionDemuxer.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxer.kt similarity index 88% rename from rsocket-core/src/main/java/io/rsocket/android/internal/ConnectionDemuxer.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxer.kt index 55fe6fb6d..3a0384972 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/ConnectionDemuxer.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxer.kt @@ -14,18 +14,17 @@ * limitations under the License. */ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.processors.BehaviorProcessor -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.FrameType.* -import io.rsocket.android.FrameType.SETUP -import io.rsocket.android.plugins.DuplexConnectionInterceptor.Type -import io.rsocket.android.plugins.DuplexConnectionInterceptor.Type.* -import io.rsocket.android.plugins.InterceptorRegistry +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType.* +import io.rsocket.kotlin.FrameType.SETUP +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor.Type +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor.Type.* import org.reactivestreams.Publisher import org.slf4j.LoggerFactory @@ -98,7 +97,7 @@ sealed class ConnectionDemuxer(private val source: DuplexConnection, } connection.accept(inboundFrames) }, - { /*noop - errors are handled by demuxed frame streams*/ }) + { /*errors are handled by demuxed frame streams*/ }) } abstract fun demux(frame: Frame): Type @@ -126,7 +125,8 @@ sealed class ConnectionDemuxer(private val source: DuplexConnection, override fun send(frame: Publisher): Completable { val frames = if (debugEnabled) { Flowable.fromPublisher(frame) - .doOnNext { f -> LOGGER.debug("sending -> " + f.toString()) } + .doOnNext { f -> + LOGGER.debug("sending -> " + f.toString()) } } else { frame } @@ -147,7 +147,10 @@ sealed class ConnectionDemuxer(private val source: DuplexConnection, override fun receive(): Flowable { return receiver.flatMapPublisher { f -> if (debugEnabled) - f.doOnNext { frame -> LOGGER.debug("receiving -> " + frame.toString()) } + f + .doOnNext { frame -> + LOGGER.debug("receiving -> " + frame.toString()) + } else f } } diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ExceptionUtil.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ExceptionUtil.kt new file mode 100644 index 000000000..f9a0ccd26 --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ExceptionUtil.kt @@ -0,0 +1,12 @@ +package io.rsocket.kotlin.internal + +internal object ExceptionUtil { + fun noStacktrace(ex: T): T { + ex.stackTrace = arrayOf(StackTraceElement( + ex.javaClass.name, + "", + null, + -1)) + return ex + } +} diff --git a/rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorRegistry.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/InterceptorRegistry.kt similarity index 89% rename from rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorRegistry.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/InterceptorRegistry.kt index f2987d65e..8e3df235d 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/plugins/InterceptorRegistry.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/InterceptorRegistry.kt @@ -14,10 +14,13 @@ * limitations under the License. */ -package io.rsocket.android.plugins +package io.rsocket.kotlin.internal -import io.rsocket.android.DuplexConnection -import io.rsocket.android.RSocket +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.RSocket +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor +import io.rsocket.kotlin.InterceptorOptions +import io.rsocket.kotlin.interceptors.RSocketInterceptor import java.util.ArrayList internal class InterceptorRegistry : InterceptorOptions { diff --git a/rsocket-core/src/main/java/io/rsocket/android/RSocketRequester.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketRequester.kt similarity index 96% rename from rsocket-core/src/main/java/io/rsocket/android/RSocketRequester.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketRequester.kt index c117998dd..576ead426 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/RSocketRequester.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketRequester.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin.internal import io.reactivex.Completable import io.reactivex.Flowable @@ -23,13 +23,12 @@ import io.reactivex.Single import io.reactivex.processors.FlowableProcessor import io.reactivex.processors.PublishProcessor import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.exceptions.ApplicationException -import io.rsocket.android.exceptions.ChannelRequestException -import io.rsocket.android.exceptions.Exceptions -import io.rsocket.android.internal.RequestingPublisher -import io.rsocket.android.internal.StreamReceiver -import io.rsocket.android.util.ExceptionUtil.noStacktrace -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.* +import io.rsocket.kotlin.exceptions.ApplicationException +import io.rsocket.kotlin.exceptions.ChannelRequestException +import io.rsocket.kotlin.exceptions.Exceptions +import io.rsocket.kotlin.internal.ExceptionUtil.noStacktrace +import io.rsocket.kotlin.DefaultPayload import org.reactivestreams.Publisher import org.reactivestreams.Subscriber import org.reactivestreams.Subscription @@ -247,7 +246,7 @@ internal class RSocketRequester( receiver.onError(Exceptions.from(frame)) } FrameType.NEXT_COMPLETE -> { - receiver.onNext(PayloadImpl(frame)) + receiver.onNext(DefaultPayload(frame)) receiver.onComplete() } FrameType.CANCEL -> { @@ -255,7 +254,7 @@ internal class RSocketRequester( sender?.cancel() receivers -= streamId } - FrameType.NEXT -> receiver.onNext(PayloadImpl(frame)) + FrameType.NEXT -> receiver.onNext(DefaultPayload(frame)) FrameType.REQUEST_N -> { val sender = senders[streamId] sender?.let { diff --git a/rsocket-core/src/main/java/io/rsocket/android/RSocketResponder.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketResponder.kt similarity index 91% rename from rsocket-core/src/main/java/io/rsocket/android/RSocketResponder.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketResponder.kt index 1225f4222..b3ee2d3ba 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/RSocketResponder.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RSocketResponder.kt @@ -14,22 +14,21 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin.internal import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.Single import io.reactivex.disposables.Disposable import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.Frame.Request.initialRequestN -import io.rsocket.android.RSocketResponder.DisposableSubscription.Companion.subscription -import io.rsocket.android.exceptions.ApplicationException -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_C -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_M -import io.rsocket.android.internal.RequestingPublisher -import io.rsocket.android.internal.StreamReceiver -import io.rsocket.android.util.ExceptionUtil.noStacktrace -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.* +import io.rsocket.kotlin.Frame.Request.initialRequestN +import io.rsocket.kotlin.internal.RSocketResponder.DisposableSubscription.Companion.subscription +import io.rsocket.kotlin.exceptions.ApplicationException +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_C +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_M +import io.rsocket.kotlin.internal.ExceptionUtil.noStacktrace +import io.rsocket.kotlin.DefaultPayload import org.reactivestreams.Publisher import org.reactivestreams.Subscriber import org.reactivestreams.Subscription @@ -121,13 +120,13 @@ internal class RSocketResponder( return try { val streamId = frame.streamId when (frame.type) { - FrameType.FIRE_AND_FORGET -> handleFireAndForget(streamId, fireAndForget(PayloadImpl(frame))) - FrameType.REQUEST_RESPONSE -> handleRequestResponse(streamId, requestResponse(PayloadImpl(frame))) + FrameType.FIRE_AND_FORGET -> handleFireAndForget(streamId, fireAndForget(DefaultPayload(frame))) + FrameType.REQUEST_RESPONSE -> handleRequestResponse(streamId, requestResponse(DefaultPayload(frame))) FrameType.CANCEL -> handleCancel(streamId) FrameType.REQUEST_N -> handleRequestN(streamId, frame) - FrameType.REQUEST_STREAM -> handleStream(streamId, requestStream(PayloadImpl(frame)), initialRequestN(frame)) + FrameType.REQUEST_STREAM -> handleStream(streamId, requestStream(DefaultPayload(frame)), initialRequestN(frame)) FrameType.REQUEST_CHANNEL -> handleChannel(streamId, frame) - FrameType.METADATA_PUSH -> metadataPush(PayloadImpl(frame)) + FrameType.METADATA_PUSH -> metadataPush(DefaultPayload(frame)) FrameType.NEXT -> handleNext(streamId, frame) FrameType.COMPLETE -> handleComplete(streamId) FrameType.ERROR -> handleError(streamId, frame) @@ -146,7 +145,7 @@ internal class RSocketResponder( private fun handleNextComplete(streamId: Int, frame: Frame): Completable { val receiver = channelReceivers[streamId] - receiver?.onNext(PayloadImpl(frame)) + receiver?.onNext(DefaultPayload(frame)) receiver?.onComplete() return Completable.complete() } @@ -165,7 +164,7 @@ internal class RSocketResponder( private fun handleNext(streamId: Int, frame: Frame): Completable { val receiver = channelReceivers[streamId] - receiver?.onNext(PayloadImpl(frame)) + receiver?.onNext(DefaultPayload(frame)) return Completable.complete() } @@ -227,7 +226,7 @@ internal class RSocketResponder( .doOnError { t -> sentFrames.onNext(Frame.Error.from(streamId, t)) } .doFinally { channelReceivers -= streamId } - receiver.onNext(PayloadImpl(firstFrame)) + receiver.onNext(DefaultPayload(firstFrame)) return handleStream( streamId, diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/RequestingPublisher.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RequestingPublisher.kt similarity index 87% rename from rsocket-core/src/main/java/io/rsocket/android/internal/RequestingPublisher.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RequestingPublisher.kt index b9c8e9fb8..94855f50e 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/RequestingPublisher.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/RequestingPublisher.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.Flowable import io.reactivex.disposables.Disposable @@ -24,7 +24,8 @@ import org.reactivestreams.Publisher import org.reactivestreams.Subscriber import org.reactivestreams.Subscription -class RequestingPublisher private constructor(private val source: Publisher) +internal class RequestingPublisher private constructor( + private val source: Publisher) : Flowable(), Subscription, Disposable { private val canceled: AtomicBoolean = AtomicBoolean() @@ -78,14 +79,16 @@ class RequestingPublisher private constructor(private val source: Publisher) : Subscriber { + private inner class InnerSubscriber ( + private var destination: Subscriber) : Subscriber { override fun onSubscribe(s: Subscription) { val parent = this@RequestingPublisher @@ -122,7 +125,8 @@ class RequestingPublisher private constructor(private val source: Publisher private constructor(private val source: Publisher wrap(source: Publisher): RequestingPublisher = RequestingPublisher(source) + fun wrap(source: Publisher): RequestingPublisher = + RequestingPublisher(source) } } diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/ServerContractInterceptor.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerContractInterceptor.kt similarity index 86% rename from rsocket-core/src/main/java/io/rsocket/android/internal/ServerContractInterceptor.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerContractInterceptor.kt index 9316e4f62..8fc867cb2 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/ServerContractInterceptor.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerContractInterceptor.kt @@ -1,18 +1,18 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.Flowable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.FrameType.RESUME -import io.rsocket.android.FrameType.SETUP -import io.rsocket.android.exceptions.InvalidSetupException -import io.rsocket.android.exceptions.RSocketException -import io.rsocket.android.exceptions.RejectedResumeException -import io.rsocket.android.exceptions.RejectedSetupException -import io.rsocket.android.frame.SetupFrameFlyweight -import io.rsocket.android.plugins.DuplexConnectionInterceptor -import io.rsocket.android.plugins.DuplexConnectionInterceptor.Type -import io.rsocket.android.util.DuplexConnectionProxy +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType.RESUME +import io.rsocket.kotlin.FrameType.SETUP +import io.rsocket.kotlin.exceptions.InvalidSetupException +import io.rsocket.kotlin.exceptions.RSocketException +import io.rsocket.kotlin.exceptions.RejectedResumeException +import io.rsocket.kotlin.exceptions.RejectedSetupException +import io.rsocket.kotlin.internal.frame.SetupFrameFlyweight +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor.Type +import io.rsocket.kotlin.util.DuplexConnectionProxy internal class ServerContractInterceptor( private val errorConsumer: (Throwable) -> Unit, diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/ServerServiceHandler.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerServiceHandler.kt similarity index 90% rename from rsocket-core/src/main/java/io/rsocket/android/internal/ServerServiceHandler.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerServiceHandler.kt index a1dbc45e4..46a70ee70 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/ServerServiceHandler.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServerServiceHandler.kt @@ -1,13 +1,13 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.netty.buffer.Unpooled import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.disposables.Disposable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.exceptions.ConnectionException -import io.rsocket.android.util.KeepAlive +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.exceptions.ConnectionException +import io.rsocket.kotlin.KeepAlive import java.util.concurrent.TimeUnit internal class ServerServiceHandler(serviceConnection: DuplexConnection, diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/ServiceHandler.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServiceHandler.kt similarity index 87% rename from rsocket-core/src/main/java/io/rsocket/android/internal/ServiceHandler.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServiceHandler.kt index 6815942f0..1b71018df 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/ServiceHandler.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/ServiceHandler.kt @@ -1,10 +1,10 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.exceptions.Exceptions +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.exceptions.Exceptions internal abstract class ServiceHandler(private val serviceConnection: DuplexConnection, private val errorConsumer: (Throwable) -> Unit) { diff --git a/rsocket-core/src/main/java/io/rsocket/android/StreamIds.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamIds.kt similarity index 96% rename from rsocket-core/src/main/java/io/rsocket/android/StreamIds.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamIds.kt index 0bb8f31f4..39decc0d7 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/StreamIds.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamIds.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin.internal internal sealed class StreamIds(private var streamId: Int) { diff --git a/rsocket-core/src/main/java/io/rsocket/android/internal/StreamReceiver.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamReceiver.kt similarity index 89% rename from rsocket-core/src/main/java/io/rsocket/android/internal/StreamReceiver.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamReceiver.kt index cfdc92648..f82f79b6c 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/internal/StreamReceiver.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/StreamReceiver.kt @@ -1,13 +1,13 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.Flowable import io.reactivex.processors.FlowableProcessor import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.Payload +import io.rsocket.kotlin.Payload import org.reactivestreams.Subscriber import org.reactivestreams.Subscription -class StreamReceiver private constructor() : FlowableProcessor() { +internal class StreamReceiver private constructor() : FlowableProcessor() { private var cancelled = false private val delegate: FlowableProcessor = UnicastProcessor .create(128) { cancelled = true } diff --git a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationDuplexConnection.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnection.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationDuplexConnection.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnection.kt index c4b7f762f..dcdd87ae3 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationDuplexConnection.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnection.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.reactivex.Completable import io.reactivex.Flowable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.reactivestreams.Publisher /** Fragments and Re-assembles frames. MTU is number of bytes per fragment.*/ diff --git a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationInterceptor.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationInterceptor.kt similarity index 71% rename from rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationInterceptor.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationInterceptor.kt index 526ccfd8a..735088276 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FragmentationInterceptor.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationInterceptor.kt @@ -1,7 +1,7 @@ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation -import io.rsocket.android.DuplexConnection -import io.rsocket.android.plugins.DuplexConnectionInterceptor +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.interceptors.DuplexConnectionInterceptor internal class FragmentationInterceptor(private val mtu: Int) : DuplexConnectionInterceptor { override fun invoke(type: DuplexConnectionInterceptor.Type, diff --git a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FrameFragmenter.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenter.kt similarity index 91% rename from rsocket-core/src/main/java/io/rsocket/android/fragmentation/FrameFragmenter.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenter.kt index 2ff94f190..4d1d13c4a 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FrameFragmenter.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenter.kt @@ -14,15 +14,18 @@ * limitations under the License. */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.netty.buffer.ByteBuf import io.netty.buffer.Unpooled import io.reactivex.Emitter import io.reactivex.Flowable import io.reactivex.disposables.Disposable -import io.rsocket.android.Frame -import io.rsocket.android.frame.FrameHeaderFlyweight.* +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_F +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.payloadLength +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.sliceFrameData +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.sliceFrameMetadata import java.util.concurrent.atomic.AtomicBoolean internal class FrameFragmenter(private val mtu: Int) { diff --git a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FramesReassembler.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FramesReassembler.kt similarity index 91% rename from rsocket-core/src/main/java/io/rsocket/android/fragmentation/FramesReassembler.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FramesReassembler.kt index a59439ad2..27d5db231 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/FramesReassembler.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/FramesReassembler.kt @@ -1,9 +1,9 @@ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.reactivex.Flowable import io.reactivex.disposables.Disposable -import io.rsocket.android.Frame -import io.rsocket.android.frame.FrameHeaderFlyweight +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean diff --git a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/StreamFramesReassembler.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassembler.kt similarity index 93% rename from rsocket-core/src/main/java/io/rsocket/android/fragmentation/StreamFramesReassembler.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassembler.kt index c6d740d40..860c26a1a 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/fragmentation/StreamFramesReassembler.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassembler.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.netty.buffer.PooledByteBufAllocator import io.reactivex.disposables.Disposable -import io.rsocket.android.Frame -import io.rsocket.android.frame.FrameHeaderFlyweight +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight import java.util.concurrent.atomic.AtomicBoolean /** Assembles Fragmented frames. */ @@ -30,7 +30,7 @@ internal class StreamFramesReassembler(frame: Frame) : Disposable { private val dataBuffer = PooledByteBufAllocator.DEFAULT.compositeBuffer() private val metadataBuffer = PooledByteBufAllocator.DEFAULT.compositeBuffer() - fun append(frame: Frame):StreamFramesReassembler { + fun append(frame: Frame): StreamFramesReassembler { val byteBuf = frame.content() val frameType = FrameHeaderFlyweight.frameType(byteBuf) val frameLength = FrameHeaderFlyweight.frameLength(byteBuf) diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/ErrorFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/ErrorFrameFlyweight.kt new file mode 100644 index 000000000..a333ea850 --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/ErrorFrameFlyweight.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.exceptions.RSocketException +import io.rsocket.kotlin.internal.frame.Utils.INTEGER_BYTES +import java.nio.charset.StandardCharsets + +internal object ErrorFrameFlyweight { + + // defined error codes + const val INVALID_SETUP = 0x00000001 + const val UNSUPPORTED_SETUP = 0x00000002 + const val REJECTED_SETUP = 0x00000003 + const val REJECTED_RESUME = 0x00000004 + const val CONNECTION_ERROR = 0x00000101 + const val CONNECTION_CLOSE = 0x00000102 + const val APPLICATION_ERROR = 0x00000201 + const val REJECTED = 0x00000202 + const val CANCELED = 0x00000203 + const val INVALID = 0x00000204 + + // relative to start of passed offset + private val ERROR_CODE_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + private val PAYLOAD_OFFSET = ERROR_CODE_FIELD_OFFSET + INTEGER_BYTES + + fun computeFrameLength(dataLength: Int): Int { + val length = FrameHeaderFlyweight.computeFrameHeaderLength( + FrameType.ERROR, + null, + dataLength) + return length + INTEGER_BYTES + } + + fun encode( + byteBuf: ByteBuf, + streamId: Int, + errorCode: Int, + data: ByteBuf): Int { + val frameLength = computeFrameLength(data.readableBytes()) + + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + 0, + FrameType.ERROR, + streamId) + + byteBuf.setInt(ERROR_CODE_FIELD_OFFSET, errorCode) + length += INTEGER_BYTES + + length += FrameHeaderFlyweight.encodeData(byteBuf, length, data) + + return length + } + + fun errorCodeFromException(ex: Throwable): Int { + return (ex as? RSocketException)?.errorCode() ?: APPLICATION_ERROR + + } + + fun errorCode(byteBuf: ByteBuf): Int { + return byteBuf.getInt(ERROR_CODE_FIELD_OFFSET) + } + + fun payloadOffset(): Int { + return FrameHeaderFlyweight.FRAME_HEADER_LENGTH + INTEGER_BYTES + } + + fun message(content: ByteBuf): String { + return FrameHeaderFlyweight.sliceFrameData(content) + .toString(StandardCharsets.UTF_8) + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/FrameHeaderFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/FrameHeaderFlyweight.kt new file mode 100644 index 000000000..1ed38aa1d --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/FrameHeaderFlyweight.kt @@ -0,0 +1,368 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.Utils.INTEGER_BYTES +import io.rsocket.kotlin.internal.frame.Utils.SHORT_BYTES + +/** + * Per connection frame flyweight. + * + * + * Not the latest frame layout, but close. Does not + * include - fragmentation / reassembly - encode should remove Type param and + * have it as part of method name (1 encode per type?) + * + * Not thread-safe. Assumed to be used single-threaded + */ +internal object FrameHeaderFlyweight { + + val FRAME_HEADER_LENGTH: Int + + private const val FRAME_TYPE_BITS = 6 + private const val FRAME_TYPE_SHIFT = 16 - FRAME_TYPE_BITS + private const val FRAME_FLAGS_MASK = 1023 + + val FRAME_LENGTH_SIZE = 3 + val FRAME_LENGTH_MASK = 0xFFFFFF + + private const val FRAME_LENGTH_FIELD_OFFSET: Int = 0 + private val FRAME_TYPE_AND_FLAGS_FIELD_OFFSET: Int + private val STREAM_ID_FIELD_OFFSET: Int + private val PAYLOAD_OFFSET: Int + + val FLAGS_I = 512 + const val FLAGS_M = 256 + + const val FLAGS_F = 128 + const val FLAGS_C = 64 + const val FLAGS_N = 32 + + init { + STREAM_ID_FIELD_OFFSET = FRAME_LENGTH_FIELD_OFFSET + FRAME_LENGTH_SIZE + FRAME_TYPE_AND_FLAGS_FIELD_OFFSET = STREAM_ID_FIELD_OFFSET + INTEGER_BYTES + PAYLOAD_OFFSET = FRAME_TYPE_AND_FLAGS_FIELD_OFFSET + SHORT_BYTES + FRAME_HEADER_LENGTH = PAYLOAD_OFFSET + } + + fun computeFrameHeaderLength( + frameType: FrameType, + metadataLength: Int?, + dataLength: Int): Int { + return PAYLOAD_OFFSET + + computeMetadataLength(frameType, metadataLength) + + dataLength + } + + fun encodeFrameHeader( + byteBuf: ByteBuf, + frameLength: Int, + flags: Int, + frameType: FrameType, + streamId: Int): Int { + if (frameLength and FRAME_LENGTH_MASK.inv() != 0) { + throw IllegalArgumentException( + "Frame length is larger than 24 bits") + } + + // frame length field needs to be excluded from the length + encodeLength(byteBuf, + FRAME_LENGTH_FIELD_OFFSET, + frameLength - FRAME_LENGTH_SIZE) + + byteBuf.setInt(STREAM_ID_FIELD_OFFSET, streamId) + val typeAndFlags = (frameType.encodedType shl FRAME_TYPE_SHIFT or flags) + byteBuf.setShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET, typeAndFlags) + + return FRAME_HEADER_LENGTH + } + + fun encodeMetadata( + byteBuf: ByteBuf, + frameType: FrameType, + metadataOffset: Int, + metadata: ByteBuf?): Int { + var length = 0 + + if (metadata != null) { + val metadataLength = metadata.readableBytes() + + var typeAndFlags = byteBuf + .getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET).toInt() + typeAndFlags = typeAndFlags or FLAGS_M + byteBuf.setShort( + FRAME_TYPE_AND_FLAGS_FIELD_OFFSET, + typeAndFlags.toShort().toInt()) + + if (hasMetadataLengthField(frameType)) { + encodeLength(byteBuf, metadataOffset, metadataLength) + length += FRAME_LENGTH_SIZE + } + byteBuf.setBytes(metadataOffset + length, metadata) + length += metadataLength + } + + return length + } + + fun encodeData(byteBuf: ByteBuf, + dataOffset: Int, + data: ByteBuf): Int { + var length = 0 + val dataLength = data.readableBytes() + + if (0 < dataLength) { + byteBuf.setBytes(dataOffset, data) + length += dataLength + } + return length + } + + // only used for types simple enough that they don't have their + // own FrameFlyweights + fun encode( + byteBuf: ByteBuf, + streamId: Int, + flags: Int, + frameType: FrameType, + metadata: ByteBuf?, + data: ByteBuf): Int { + var f = flags + if (Frame.isFlagSet(f, FLAGS_M) != (metadata != null)) { + throw IllegalStateException("bad value for metadata flag") + } + + val frameLength = computeFrameHeaderLength( + frameType, metadata?.readableBytes(), data.readableBytes()) + + val outFrameType: FrameType + when (frameType) { + FrameType.PAYLOAD -> throw IllegalArgumentException( + "Don't encode raw PAYLOAD frames, " + + "use NEXT_COMPLETE, COMPLETE or NEXT") + FrameType.NEXT_COMPLETE -> { + outFrameType = FrameType.PAYLOAD + f = f or (FLAGS_C or FLAGS_N) + } + FrameType.COMPLETE -> { + outFrameType = FrameType.PAYLOAD + f = f or FLAGS_C + } + FrameType.NEXT -> { + outFrameType = FrameType.PAYLOAD + f = f or FLAGS_N + } + else -> outFrameType = frameType + } + var length = encodeFrameHeader( + byteBuf, + frameLength, + f, + outFrameType, + streamId) + + length += encodeMetadata(byteBuf, frameType, length, metadata) + length += encodeData(byteBuf, length, data) + + return length + } + + fun flags(byteBuf: ByteBuf): Int { + val typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET) + return typeAndFlags.toInt() and FRAME_FLAGS_MASK + } + + fun frameType(byteBuf: ByteBuf): FrameType { + val typeAndFlags = byteBuf + .getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET).toInt() + var result = FrameType.from(typeAndFlags shr FRAME_TYPE_SHIFT)!! + + if (FrameType.PAYLOAD === result) { + val flags = typeAndFlags and FRAME_FLAGS_MASK + + val complete = FLAGS_C == flags and FLAGS_C + val next = FLAGS_N == flags and FLAGS_N + result = if (next && complete) { + FrameType.NEXT_COMPLETE + } else if (complete) { + FrameType.COMPLETE + } else if (next) { + FrameType.NEXT + } else { + throw IllegalArgumentException( + "Payload must set either or both of NEXT and COMPLETE.") + } + } + return result + } + + fun streamId(byteBuf: ByteBuf): Int { + return byteBuf.getInt(STREAM_ID_FIELD_OFFSET) + } + + fun sliceFrameData(byteBuf: ByteBuf): ByteBuf { + val frameType = frameType(byteBuf) + val frameLength = frameLength(byteBuf) + val dataLength = dataLength(byteBuf, frameType) + val dataOffset = dataOffset(byteBuf, frameType, frameLength) + var result = Unpooled.EMPTY_BUFFER + + if (0 < dataLength) { + result = byteBuf.slice(dataOffset, dataLength) + } + return result + } + + fun sliceFrameMetadata(byteBuf: ByteBuf): ByteBuf? { + val frameType = frameType(byteBuf) + val frameLength = frameLength(byteBuf) + val metadataLength = metadataLength(byteBuf, frameType, frameLength) + ?: return null + + var metadataOffset = metadataOffset(byteBuf) + if (hasMetadataLengthField(frameType)) { + metadataOffset += FRAME_LENGTH_SIZE + } + var result = Unpooled.EMPTY_BUFFER + + if (0 < metadataLength) { + result = byteBuf.slice(metadataOffset, metadataLength) + } + return result + } + + fun frameLength(byteBuf: ByteBuf): Int { + // frame length field was excluded from the length so we + // will add it to represent the entire block + return decodeLength( + byteBuf, + FRAME_LENGTH_FIELD_OFFSET) + FRAME_LENGTH_SIZE + } + + private fun metadataFieldLength(byteBuf: ByteBuf, + frameType: FrameType, + frameLength: Int): Int { + return computeMetadataLength( + frameType, + metadataLength(byteBuf, frameType, frameLength)) + } + + fun metadataLength( + byteBuf: ByteBuf, + frameType: FrameType, + frameLength: Int): Int? { + return if (!hasMetadataLengthField(frameType)) { + frameLength - metadataOffset(byteBuf) + } else { + decodeMetadataLength(byteBuf, metadataOffset(byteBuf)) + } + } + + internal fun decodeMetadataLength(byteBuf: ByteBuf, + metadataOffset: Int): Int? { + val flags = flags(byteBuf) + return if (FLAGS_M == FLAGS_M and flags) { + decodeLength(byteBuf, metadataOffset) + } else { + null + } + } + + private fun computeMetadataLength(frameType: FrameType, + length: Int?): Int { + return if (!hasMetadataLengthField(frameType)) { + // Frames with only metadata does not need metadata length field + length ?: 0 + } else { + if (length == null) 0 else length + FRAME_LENGTH_SIZE + } + } + + fun hasMetadataLengthField(frameType: FrameType): Boolean { + return frameType.canHaveData() + } + + fun encodeLength(byteBuf: ByteBuf, offset: Int, length: Int) { + if (length and FRAME_LENGTH_MASK.inv() != 0) { + throw IllegalArgumentException("Length is larger than 24 bits") + } + // Write each byte separately in reverse order, this mean we + // can write 1 << 23 without overflowing. + byteBuf.setByte(offset, length shr 16) + byteBuf.setByte(offset + 1, length shr 8) + byteBuf.setByte(offset + 2, length) + } + + private fun decodeLength(byteBuf: ByteBuf, offset: Int): Int { + var length = byteBuf.getByte(offset).toInt() and 0xFF shl 16 + length = length or (byteBuf.getByte(offset + 1).toInt() and 0xFF shl 8) + length = length or (byteBuf.getByte(offset + 2).toInt() and 0xFF) + return length + } + + fun dataLength(byteBuf: ByteBuf, frameType: FrameType): Int { + return dataLength(byteBuf, frameType, payloadOffset(byteBuf)) + } + + internal fun dataLength(byteBuf: ByteBuf, + frameType: FrameType, + payloadOffset: Int): Int { + val frameLength = frameLength(byteBuf) + val metadataLength = metadataFieldLength( + byteBuf, + frameType, + frameLength) + return frameLength - metadataLength - payloadOffset + } + + fun payloadLength(byteBuf: ByteBuf): Int { + val frameLength = frameLength(byteBuf) + val payloadOffset = payloadOffset(byteBuf) + return frameLength - payloadOffset + } + + private fun payloadOffset(byteBuf: ByteBuf): Int { + val typeAndFlags = byteBuf + .getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET).toInt() + val frameType = FrameType.from(typeAndFlags shr FRAME_TYPE_SHIFT) + + return when (frameType) { + FrameType.SETUP -> SetupFrameFlyweight.payloadOffset(byteBuf) + FrameType.ERROR -> ErrorFrameFlyweight.payloadOffset() + FrameType.LEASE -> LeaseFrameFlyweight.payloadOffset() + FrameType.KEEPALIVE -> KeepaliveFrameFlyweight.payloadOffset() + FrameType.REQUEST_RESPONSE, + FrameType.FIRE_AND_FORGET, + FrameType.REQUEST_STREAM, + FrameType.REQUEST_CHANNEL -> RequestFrameFlyweight.payloadOffset(frameType) + FrameType.REQUEST_N -> RequestNFrameFlyweight.payloadOffset() + else -> PAYLOAD_OFFSET + } + } + + fun metadataOffset(byteBuf: ByteBuf): Int = payloadOffset(byteBuf) + + fun dataOffset(byteBuf: ByteBuf, + frameType: FrameType, + frameLength: Int): Int { + return payloadOffset(byteBuf) + + metadataFieldLength(byteBuf, frameType, frameLength) + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/KeepaliveFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/KeepaliveFrameFlyweight.kt new file mode 100644 index 000000000..cf5665702 --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/KeepaliveFrameFlyweight.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.Utils.LONG_BYTES + +internal object KeepaliveFrameFlyweight { + const val FLAGS_KEEPALIVE_R = 128 + + private val LAST_POSITION_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + private val PAYLOAD_OFFSET = LAST_POSITION_OFFSET + LONG_BYTES + + fun computeFrameLength(dataLength: Int): Int { + return FrameHeaderFlyweight.computeFrameHeaderLength( + FrameType.SETUP, + null, + dataLength) + LONG_BYTES + } + + fun encode(byteBuf: ByteBuf, + flags: Int, + data: ByteBuf): Int { + val frameLength = computeFrameLength(data.readableBytes()) + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + flags, + FrameType.KEEPALIVE, + 0) + + // We don't support resumability, last position is always zero + byteBuf.setLong(length, 0) + length += LONG_BYTES + length += FrameHeaderFlyweight.encodeData(byteBuf, length, data) + return length + } + + fun payloadOffset(): Int { + return PAYLOAD_OFFSET + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/LeaseFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/LeaseFrameFlyweight.kt new file mode 100644 index 000000000..44b24ac0d --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/LeaseFrameFlyweight.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.Utils.INTEGER_BYTES + +internal object LeaseFrameFlyweight { + + // relative to start of passed offset + private val TTL_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + private val NUM_REQUESTS_FIELD_OFFSET = TTL_FIELD_OFFSET + INTEGER_BYTES + private val PAYLOAD_OFFSET = NUM_REQUESTS_FIELD_OFFSET + INTEGER_BYTES + + fun computeFrameLength(metadataLength: Int): Int { + val length = FrameHeaderFlyweight.computeFrameHeaderLength( + FrameType.LEASE, metadataLength, + 0) + return length + INTEGER_BYTES * 2 + } + + fun encode( + byteBuf: ByteBuf, + ttl: Int, + numRequests: Int, + metadata: ByteBuf): Int { + val frameLength = computeFrameLength(metadata.readableBytes()) + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + 0, + FrameType.LEASE, + 0) + + byteBuf.setInt(TTL_FIELD_OFFSET, ttl) + byteBuf.setInt(NUM_REQUESTS_FIELD_OFFSET, numRequests) + + length += INTEGER_BYTES * 2 + length += FrameHeaderFlyweight.encodeMetadata( + byteBuf, + FrameType.LEASE, + length, + metadata) + + return length + } + + fun ttl(byteBuf: ByteBuf): Int { + return byteBuf.getInt(TTL_FIELD_OFFSET) + } + + fun numRequests(byteBuf: ByteBuf): Int { + return byteBuf.getInt(NUM_REQUESTS_FIELD_OFFSET) + } + + fun payloadOffset(): Int { + return PAYLOAD_OFFSET + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestFrameFlyweight.kt new file mode 100644 index 000000000..f8dd6765b --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestFrameFlyweight.kt @@ -0,0 +1,139 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.rsocket.kotlin.internal.frame.Utils.INTEGER_BYTES + +import io.netty.buffer.ByteBuf +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType + +internal object RequestFrameFlyweight { + + // relative to start of passed offset + private val INITIAL_REQUEST_N_FIELD_OFFSET = + FrameHeaderFlyweight.FRAME_HEADER_LENGTH + + fun computeFrameLength( + type: FrameType, + metadataLength: Int?, + dataLength: Int): Int { + + var length = FrameHeaderFlyweight.computeFrameHeaderLength( + type, + metadataLength, + dataLength) + + if (type.hasInitialRequestN()) { + length += INTEGER_BYTES + } + return length + } + + fun encode( + byteBuf: ByteBuf, + streamId: Int, + flags: Int, + type: FrameType, + initialRequestN: Int, + metadata: ByteBuf?, + data: ByteBuf): Int { + if (Frame.isFlagSet( + flags, + FrameHeaderFlyweight.FLAGS_M) != (metadata != null)) { + throw IllegalArgumentException("metadata flag set incorrectly") + } + val frameLength = computeFrameLength( + type, + metadata?.readableBytes(), + data.readableBytes()) + + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + flags, + type, + streamId) + + byteBuf.setInt(INITIAL_REQUEST_N_FIELD_OFFSET, initialRequestN) + length += INTEGER_BYTES + + length += FrameHeaderFlyweight.encodeMetadata( + byteBuf, + type, + length, + metadata) + + length += FrameHeaderFlyweight.encodeData( + byteBuf, + length, + data) + + return length + } + + fun encode( + byteBuf: ByteBuf, + streamId: Int, + flags: Int, + type: FrameType, + metadata: ByteBuf?, + data: ByteBuf): Int { + if (Frame.isFlagSet(flags, FrameHeaderFlyweight.FLAGS_M) != + (metadata != null)) { + throw IllegalArgumentException("metadata flag set incorrectly") + } + if (type.hasInitialRequestN()) { + throw AssertionError( + "$type must not be encoded without initial request N") + } + val frameLength = computeFrameLength( + type, metadata?.readableBytes(), data.readableBytes()) + + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + flags, + type, + streamId) + + length += FrameHeaderFlyweight.encodeMetadata( + byteBuf, + type, + length, + metadata) + + length += FrameHeaderFlyweight.encodeData( + byteBuf, + length, + data) + + return length + } + + fun initialRequestN(byteBuf: ByteBuf): Int { + return byteBuf.getInt(INITIAL_REQUEST_N_FIELD_OFFSET) + } + + fun payloadOffset(type: FrameType): Int { + var result = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + + if (type.hasInitialRequestN()) { + result += INTEGER_BYTES + } + return result + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestNFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestNFrameFlyweight.kt new file mode 100644 index 000000000..dd3942177 --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/RequestNFrameFlyweight.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.Utils.INTEGER_BYTES + +internal object RequestNFrameFlyweight { + + // relative to start of passed offset + private val REQUEST_N_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + + fun computeFrameLength(): Int { + val length = FrameHeaderFlyweight.computeFrameHeaderLength( + FrameType.REQUEST_N, + 0, + 0) + + return length + INTEGER_BYTES + } + + fun encode(byteBuf: ByteBuf, + streamId: Int, + requestN: Int): Int { + val frameLength = computeFrameLength() + + val length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + 0, + FrameType.REQUEST_N, + streamId) + + byteBuf.setInt(REQUEST_N_FIELD_OFFSET, requestN) + + return length + INTEGER_BYTES + } + + fun requestN(byteBuf: ByteBuf): Int { + return byteBuf.getInt(REQUEST_N_FIELD_OFFSET) + } + + fun payloadOffset(): Int { + return FrameHeaderFlyweight.FRAME_HEADER_LENGTH + INTEGER_BYTES + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/SetupFrameFlyweight.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/SetupFrameFlyweight.kt new file mode 100644 index 000000000..330e81faf --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/SetupFrameFlyweight.kt @@ -0,0 +1,228 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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.internal.frame + +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_M +import java.nio.charset.StandardCharsets + +internal object SetupFrameFlyweight { + + const val FLAGS_RESUME_ENABLE = 128 + const val FLAGS_WILL_HONOR_LEASE = 64 + + val VALID_FLAGS = FLAGS_RESUME_ENABLE or + FLAGS_WILL_HONOR_LEASE or + FLAGS_M + + val CURRENT_VERSION = VersionFlyweight.encode(1, 0) + + // relative to start of passed offset + private val VERSION_FIELD_OFFSET = FrameHeaderFlyweight.FRAME_HEADER_LENGTH + private val KEEPALIVE_INTERVAL_FIELD_OFFSET = VERSION_FIELD_OFFSET + + Utils.INTEGER_BYTES + private val MAX_LIFETIME_FIELD_OFFSET = KEEPALIVE_INTERVAL_FIELD_OFFSET + + Utils.INTEGER_BYTES + private val VARIABLE_DATA_OFFSET = MAX_LIFETIME_FIELD_OFFSET + + Utils.INTEGER_BYTES + + fun computeFrameLength( + flags: Int, + metadataMimeType: String, + dataMimeType: String, + metadataLength: Int, + dataLength: Int): Int = + + computeFrameLength( + flags, + 0, + metadataMimeType, + dataMimeType, + metadataLength, + dataLength) + + private fun computeFrameLength( + flags: Int, + resumeTokenLength: Int, + metadataMimeType: String, + dataMimeType: String, + metadataLength: Int, + dataLength: Int): Int { + + var length = FrameHeaderFlyweight.computeFrameHeaderLength( + FrameType.SETUP, + metadataLength, + dataLength) + + length += Utils.INTEGER_BYTES * 3 + + if (flags and FLAGS_RESUME_ENABLE != 0) { + length += Utils.SHORT_BYTES + resumeTokenLength + } + + length += 1 + metadataMimeType.toByteArray(StandardCharsets.UTF_8).size + length += 1 + dataMimeType.toByteArray(StandardCharsets.UTF_8).size + + return length + } + + fun encode( + byteBuf: ByteBuf, + flags: Int, + version: Int, + keepaliveInterval: Int, + maxLifetime: Int, + metadataMimeType: String, + dataMimeType: String, + metadata: ByteBuf, + data: ByteBuf): Int { + + return encode( + byteBuf, + flags, + version, + keepaliveInterval, + maxLifetime, + Unpooled.EMPTY_BUFFER, + metadataMimeType, + dataMimeType, + metadata, + data) + } + + // Only exposed for testing, other code shouldn't create + // frames with resumption tokens for now + internal fun encode( + byteBuf: ByteBuf, + flags: Int, + version: Int, + keepaliveInterval: Int, + maxLifetime: Int, + resumeToken: ByteBuf, + metadataMimeType: String, + dataMimeType: String, + metadata: ByteBuf, + data: ByteBuf): Int { + val frameLength = computeFrameLength( + flags, + resumeToken.readableBytes(), + metadataMimeType, + dataMimeType, + metadata.readableBytes(), + data.readableBytes()) + + var length = FrameHeaderFlyweight.encodeFrameHeader( + byteBuf, + frameLength, + flags, + FrameType.SETUP, + 0) + + byteBuf.setInt(VERSION_FIELD_OFFSET, version) + byteBuf.setInt(KEEPALIVE_INTERVAL_FIELD_OFFSET, keepaliveInterval) + byteBuf.setInt(MAX_LIFETIME_FIELD_OFFSET, maxLifetime) + + length += Utils.INTEGER_BYTES * 3 + + if (flags and FLAGS_RESUME_ENABLE != 0) { + byteBuf.setShort(length, resumeToken.readableBytes()) + length += Utils.SHORT_BYTES + val resumeTokenLength = resumeToken.readableBytes() + byteBuf.setBytes(length, resumeToken, resumeTokenLength) + length += resumeTokenLength + } + + length += putMimeType(byteBuf, length, metadataMimeType) + length += putMimeType(byteBuf, length, dataMimeType) + + length += FrameHeaderFlyweight.encodeMetadata( + byteBuf, + FrameType.SETUP, + length, + metadata) + + length += FrameHeaderFlyweight.encodeData( + byteBuf, + length, + data) + + return length + } + + fun version(byteBuf: ByteBuf): Int = byteBuf.getInt(VERSION_FIELD_OFFSET) + + fun keepaliveInterval(byteBuf: ByteBuf): Int = + byteBuf.getInt(KEEPALIVE_INTERVAL_FIELD_OFFSET) + + fun maxLifetime(byteBuf: ByteBuf): Int = + byteBuf.getInt(MAX_LIFETIME_FIELD_OFFSET) + + fun metadataMimeType(byteBuf: ByteBuf): String { + val bytes = getMimeType(byteBuf, metadataMimetypeOffset(byteBuf)) + return String(bytes, StandardCharsets.UTF_8) + } + + fun dataMimeType(byteBuf: ByteBuf): String { + var fieldOffset = metadataMimetypeOffset(byteBuf) + + fieldOffset += 1 + byteBuf.getByte(fieldOffset) + + val bytes = getMimeType(byteBuf, fieldOffset) + return String(bytes, StandardCharsets.UTF_8) + } + + fun payloadOffset(byteBuf: ByteBuf): Int { + var fieldOffset = metadataMimetypeOffset(byteBuf) + + val metadataMimeTypeLength = byteBuf.getByte(fieldOffset).toInt() + fieldOffset += 1 + metadataMimeTypeLength + + val dataMimeTypeLength = byteBuf.getByte(fieldOffset).toInt() + fieldOffset += 1 + dataMimeTypeLength + + return fieldOffset + } + + private fun metadataMimetypeOffset(byteBuf: ByteBuf): Int { + return VARIABLE_DATA_OFFSET + resumeTokenTotalLength(byteBuf) + } + + private fun resumeTokenTotalLength(byteBuf: ByteBuf): Int = + if (FrameHeaderFlyweight.flags(byteBuf) and FLAGS_RESUME_ENABLE == 0) + 0 + else + Utils.SHORT_BYTES + byteBuf.getShort(VARIABLE_DATA_OFFSET) + + private fun putMimeType( + byteBuf: ByteBuf, fieldOffset: Int, mimeType: String): Int { + val bytes = mimeType.toByteArray(StandardCharsets.UTF_8) + + byteBuf.setByte(fieldOffset, bytes.size.toByte().toInt()) + byteBuf.setBytes(fieldOffset + 1, bytes) + + return 1 + bytes.size + } + + private fun getMimeType(byteBuf: ByteBuf, fieldOffset: Int): ByteArray { + val length = byteBuf.getByte(fieldOffset).toInt() + val bytes = ByteArray(length) + + byteBuf.getBytes(fieldOffset + 1, bytes) + return bytes + } +} diff --git a/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/Utils.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/Utils.kt new file mode 100644 index 000000000..b941ee740 --- /dev/null +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/Utils.kt @@ -0,0 +1,7 @@ +package io.rsocket.kotlin.internal.frame + +internal object Utils { + const val SHORT_BYTES = 2 + const val INTEGER_BYTES = 4 + const val LONG_BYTES = 8 +} diff --git a/rsocket-core/src/main/java/io/rsocket/android/frame/VersionFlyweight.java b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/VersionFlyweight.kt similarity index 58% rename from rsocket-core/src/main/java/io/rsocket/android/frame/VersionFlyweight.java rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/VersionFlyweight.kt index 641920356..32ad3637a 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/frame/VersionFlyweight.java +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/internal/frame/VersionFlyweight.kt @@ -14,23 +14,23 @@ * limitations under the License. */ -package io.rsocket.android.frame; +package io.rsocket.kotlin.internal.frame -public class VersionFlyweight { +internal object VersionFlyweight { - public static int encode(int major, int minor) { - return (major << 16) | (minor & 0xFFFF); - } + fun encode(major: Int, minor: Int): Int { + return major shl 16 or (minor and 0xFFFF) + } - public static int major(int version) { - return version >> 16; - } + fun major(version: Int): Int { + return version shr 16 + } - public static int minor(int version) { - return version & 0xFFFF; - } + fun minor(version: Int): Int { + return version and 0xFFFF + } - public static String toString(int version) { - return major(version) + "." + minor(version); - } + fun toString(version: Int): String { + return major(version).toString() + "." + minor(version) + } } diff --git a/rsocket-core/src/main/java/io/rsocket/android/transport/ClientTransport.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ClientTransport.kt similarity index 92% rename from rsocket-core/src/main/java/io/rsocket/android/transport/ClientTransport.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ClientTransport.kt index a5bba183a..d94864ace 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/transport/ClientTransport.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ClientTransport.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.rsocket.android.transport +package io.rsocket.kotlin.transport import io.reactivex.Single -import io.rsocket.android.DuplexConnection +import io.rsocket.kotlin.DuplexConnection /** A client contract for writing transports of RSocket. */ interface ClientTransport : Transport { diff --git a/rsocket-core/src/main/java/io/rsocket/android/transport/ServerTransport.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ServerTransport.kt similarity index 93% rename from rsocket-core/src/main/java/io/rsocket/android/transport/ServerTransport.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ServerTransport.kt index 267ff4603..1a7cc743a 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/transport/ServerTransport.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/ServerTransport.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.transport +package io.rsocket.kotlin.transport import io.reactivex.Completable import io.reactivex.Single -import io.rsocket.android.Closeable -import io.rsocket.android.DuplexConnection +import io.rsocket.kotlin.Closeable +import io.rsocket.kotlin.DuplexConnection /** A server contract for writing transports of RSocket. */ interface ServerTransport : Transport { diff --git a/rsocket-core/src/main/java/io/rsocket/android/transport/Transport.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/Transport.kt similarity index 94% rename from rsocket-core/src/main/java/io/rsocket/android/transport/Transport.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/Transport.kt index a8838c440..506ea3f33 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/transport/Transport.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/Transport.kt @@ -14,6 +14,6 @@ * limitations under the License. */ -package io.rsocket.android.transport +package io.rsocket.kotlin.transport interface Transport diff --git a/rsocket-core/src/main/java/io/rsocket/android/transport/TransportHeaderAware.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/TransportHeaderAware.kt similarity index 95% rename from rsocket-core/src/main/java/io/rsocket/android/transport/TransportHeaderAware.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/TransportHeaderAware.kt index 46c848c08..e5d69c1b0 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/transport/TransportHeaderAware.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/transport/TransportHeaderAware.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android.transport +package io.rsocket.kotlin.transport /** * Extension interface to support Transports with headers at the transport layer, e.g. Websockets, diff --git a/rsocket-core/src/main/java/io/rsocket/android/AbstractRSocket.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/AbstractRSocket.kt similarity index 60% rename from rsocket-core/src/main/java/io/rsocket/android/AbstractRSocket.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/AbstractRSocket.kt index f73b5e5b3..dd077cdce 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/AbstractRSocket.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/AbstractRSocket.kt @@ -14,36 +14,44 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin.util -import io.reactivex.* +import io.reactivex.Completable +import io.reactivex.Flowable +import io.reactivex.Single import io.reactivex.processors.AsyncProcessor +import io.rsocket.kotlin.Payload +import io.rsocket.kotlin.RSocket import org.reactivestreams.Publisher /** - * An abstract implementation of [RSocket]. All request handling methods emit [ ] and hence must be overridden to provide a valid implementation. + * An abstract implementation of [RSocket]. All request handling methods emit error + * and hence must be overridden to provide a valid implementation. * - * - * [.close] and [.onClose] returns a `Publisher` that never terminates. */ abstract class AbstractRSocket : RSocket { - private val onClose:AsyncProcessor = AsyncProcessor.create() + private val onClose: AsyncProcessor = AsyncProcessor.create() override fun fireAndForget(payload: Payload): Completable = - Completable.error(UnsupportedOperationException("Fire and forget not implemented.")) + Completable.error(UnsupportedOperationException( + "Fire and forget not implemented.")) override fun requestResponse(payload: Payload): Single = - Single.error(UnsupportedOperationException("Request-Response not implemented.")) + Single.error(UnsupportedOperationException( + "Request-Response not implemented.")) override fun requestStream(payload: Payload): Flowable = - Flowable.error(UnsupportedOperationException("Request-Stream not implemented.")) + Flowable.error(UnsupportedOperationException( + "Request-Stream not implemented.")) override fun requestChannel(payloads: Publisher): Flowable = - Flowable.error(UnsupportedOperationException("Request-Channel not implemented.")) + Flowable.error(UnsupportedOperationException( + "Request-Channel not implemented.")) override fun metadataPush(payload: Payload): Completable = - Completable.error(UnsupportedOperationException("Metadata-Push not implemented.")) + Completable.error(UnsupportedOperationException( + "Metadata-Push not implemented.")) override fun close(): Completable { return Completable.defer { diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/DuplexConnectionProxy.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/DuplexConnectionProxy.kt similarity index 58% rename from rsocket-core/src/main/java/io/rsocket/android/util/DuplexConnectionProxy.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/DuplexConnectionProxy.kt index a86f34d5d..4f9277713 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/DuplexConnectionProxy.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/DuplexConnectionProxy.kt @@ -1,6 +1,6 @@ -package io.rsocket.android.util +package io.rsocket.kotlin.util -import io.rsocket.android.DuplexConnection +import io.rsocket.kotlin.DuplexConnection open class DuplexConnectionProxy(protected val source: DuplexConnection) : DuplexConnection by source \ No newline at end of file diff --git a/rsocket-core/src/main/java/io/rsocket/android/util/RSocketProxy.kt b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/RSocketProxy.kt similarity index 76% rename from rsocket-core/src/main/java/io/rsocket/android/util/RSocketProxy.kt rename to rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/RSocketProxy.kt index 08eadd437..381cdc7e0 100644 --- a/rsocket-core/src/main/java/io/rsocket/android/util/RSocketProxy.kt +++ b/rsocket-core/src/main/kotlin/io/rsocket/kotlin/util/RSocketProxy.kt @@ -13,14 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.util +package io.rsocket.kotlin.util -import io.reactivex.Completable -import io.reactivex.Flowable -import io.reactivex.Single -import io.rsocket.android.Payload -import io.rsocket.android.RSocket -import org.reactivestreams.Publisher +import io.rsocket.kotlin.RSocket /** Wrapper/Proxy for a RSocket. This is useful when we want to override a specific method. */ open class RSocketProxy(source: RSocket) : RSocket by source \ No newline at end of file diff --git a/rsocket-core/src/test/java/io/rsocket/android/FrameTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/FrameTest.kt similarity index 65% rename from rsocket-core/src/test/java/io/rsocket/android/FrameTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/FrameTest.kt index 92de903bc..9b87d2f7d 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/FrameTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/FrameTest.kt @@ -1,16 +1,15 @@ -package io.rsocket.android +package io.rsocket.kotlin import org.junit.Assert.assertEquals -import io.rsocket.android.frame.FrameHeaderFlyweight -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight import org.junit.Test class FrameTest { @Test fun testFrameToString() { val requestFrame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl("streaming in -> 0"), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload("streaming in -> 0"), 1) assertEquals( "Frame => Stream ID: 1 Type: REQUEST_RESPONSE Payload: data: \"streaming in -> 0\" ", requestFrame.toString()) @@ -19,7 +18,7 @@ class FrameTest { @Test fun testFrameWithMetadataToString() { val requestFrame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl("streaming in -> 0", "metadata"), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload("streaming in -> 0", "metadata"), 1) assertEquals( "Frame => Stream ID: 1 Type: REQUEST_RESPONSE Payload: metadata: \"metadata\" data: \"streaming in -> 0\" ", requestFrame.toString()) @@ -28,7 +27,7 @@ class FrameTest { @Test fun testPayload() { val frame = Frame.PayloadFrame.from( - 1, FrameType.NEXT_COMPLETE, PayloadImpl("Hello"), FrameHeaderFlyweight.FLAGS_C) + 1, FrameType.NEXT_COMPLETE, DefaultPayload("Hello"), FrameHeaderFlyweight.FLAGS_C) frame.toString() } } diff --git a/rsocket-core/src/test/java/io/rsocket/android/RSocketRequesterTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketRequesterTest.kt similarity index 84% rename from rsocket-core/src/test/java/io/rsocket/android/RSocketRequesterTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketRequesterTest.kt index 4ec32b692..87afb961f 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/RSocketRequesterTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketRequesterTest.kt @@ -15,7 +15,7 @@ */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Flowable @@ -23,10 +23,11 @@ import io.reactivex.Single import io.reactivex.internal.observers.BlockingMultiObserver import io.reactivex.processors.PublishProcessor import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.exceptions.ApplicationException -import io.rsocket.android.frame.RequestFrameFlyweight -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.exceptions.ApplicationException +import io.rsocket.kotlin.internal.frame.RequestFrameFlyweight +import io.rsocket.kotlin.internal.ClientStreamIds +import io.rsocket.kotlin.internal.RSocketRequester +import io.rsocket.kotlin.test.util.LocalDuplexConnection import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.Rule @@ -59,7 +60,7 @@ class RSocketRequesterTest { @Test(timeout = 2000) fun testStreamInitialN() { - val stream = rule.requester.requestStream(PayloadImpl.EMPTY) + val stream = rule.requester.requestStream(DefaultPayload.EMPTY) Completable.timer(100, TimeUnit.MILLISECONDS) .subscribe({ val subscriber = TestSubscriber() @@ -86,7 +87,7 @@ class RSocketRequesterTest { @Test(timeout = 2000) fun testHandleApplicationException() { - val response = rule.requester.requestResponse(PayloadImpl.EMPTY).toFlowable() + val response = rule.requester.requestResponse(DefaultPayload.EMPTY).toFlowable() val responseSub = TestSubscriber.create() response.subscribe(responseSub) rule.receiver.onNext(Frame.Error.from(1, ApplicationException("error"))) @@ -96,13 +97,13 @@ class RSocketRequesterTest { @Test(timeout = 2000) fun testHandleValidFrame() { - val response = rule.requester.requestResponse(PayloadImpl.EMPTY).toFlowable() + val response = rule.requester.requestResponse(DefaultPayload.EMPTY).toFlowable() val sub = TestSubscriber.create() response.subscribe(sub) rule.receiver.onNext( Frame.PayloadFrame.from( - 1, FrameType.NEXT_COMPLETE, PayloadImpl.EMPTY)) + 1, FrameType.NEXT_COMPLETE, DefaultPayload.EMPTY)) sub.assertValueCount(1) sub.assertComplete() } @@ -112,8 +113,8 @@ class RSocketRequesterTest { val subs = TestSubscriber.create() rule.sender.filter { it.type != FrameType.KEEPALIVE } .subscribe(subs) - rule.requester.requestResponse(PayloadImpl.EMPTY).timeout(100, TimeUnit.MILLISECONDS) - .onErrorReturnItem(PayloadImpl("test")) + rule.requester.requestResponse(DefaultPayload.EMPTY).timeout(100, TimeUnit.MILLISECONDS) + .onErrorReturnItem(DefaultPayload("test")) .blockingGet() val sent = subs.values() @@ -127,7 +128,7 @@ class RSocketRequesterTest { @Test fun testLazyRequestResponse() { - val response = rule.requester.requestResponse(PayloadImpl.EMPTY).toFlowable() + val response = rule.requester.requestResponse(DefaultPayload.EMPTY).toFlowable() val framesSubs = TestSubscriber.create() rule.sender.filter { it.type != FrameType.KEEPALIVE }.subscribe(framesSubs) @@ -145,7 +146,7 @@ class RSocketRequesterTest { fun requestErrorOnConnectionClose() { Completable.timer(100, TimeUnit.MILLISECONDS) .andThen(rule.conn.close()).subscribe() - val requestStream = rule.requester.requestStream(PayloadImpl("test")) + val requestStream = rule.requester.requestStream(DefaultPayload("test")) val subs = TestSubscriber.create() requestStream.blockingSubscribe(subs) subs.assertNoValues() @@ -154,32 +155,32 @@ class RSocketRequesterTest { @Test(timeout = 5_000) fun streamErrorAfterConnectionClose() { - assertFlowableError { it.requestStream(PayloadImpl("test")) } + assertFlowableError { it.requestStream(DefaultPayload("test")) } } @Test(timeout = 5_000) fun reqStreamErrorAfterConnectionClose() { - assertFlowableError { it.requestStream(PayloadImpl("test")) } + assertFlowableError { it.requestStream(DefaultPayload("test")) } } @Test(timeout = 5_000) fun reqChannelErrorAfterConnectionClose() { - assertFlowableError { it.requestChannel(Flowable.just(PayloadImpl("test"))) } + assertFlowableError { it.requestChannel(Flowable.just(DefaultPayload("test"))) } } @Test(timeout = 5_000) fun reqResponseErrorAfterConnectionClose() { - assertSingleError { it.requestResponse(PayloadImpl("test")) } + assertSingleError { it.requestResponse(DefaultPayload("test")) } } @Test(timeout = 5_000) fun fnfErrorAfterConnectionClose() { - assertCompletableError { it.fireAndForget(PayloadImpl("test")) } + assertCompletableError { it.fireAndForget(DefaultPayload("test")) } } @Test(timeout = 5_000) fun metadataPushAfterConnectionClose() { - assertCompletableError { it.metadataPush(PayloadImpl("test")) } + assertCompletableError { it.metadataPush(DefaultPayload("test")) } } private fun assertFlowableError(f: (RSocket) -> Flowable) { diff --git a/rsocket-core/src/test/java/io/rsocket/android/RSocketResponderTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketResponderTest.kt similarity index 96% rename from rsocket-core/src/test/java/io/rsocket/android/RSocketResponderTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketResponderTest.kt index f92d20fba..ee95a26ba 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/RSocketResponderTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketResponderTest.kt @@ -15,15 +15,16 @@ */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.Single import io.reactivex.processors.PublishProcessor import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.internal.RSocketResponder +import io.rsocket.kotlin.test.util.LocalDuplexConnection +import io.rsocket.kotlin.util.AbstractRSocket import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.Rule @@ -144,7 +145,7 @@ class RSocketResponderTest { } fun sendRequest(streamId: Int, frameType: FrameType) { - val request = Frame.Request.from(streamId, frameType, PayloadImpl.EMPTY, 1) + val request = Frame.Request.from(streamId, frameType, DefaultPayload.EMPTY, 1) receiver.onNext(request) receiver.onNext(Frame.RequestN.from(streamId, 2)) } diff --git a/rsocket-core/src/test/java/io/rsocket/android/RSocketTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketTest.kt similarity index 89% rename from rsocket-core/src/test/java/io/rsocket/android/RSocketTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketTest.kt index a49df0abf..b12623324 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/RSocketTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RSocketTest.kt @@ -15,14 +15,17 @@ */ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Flowable import io.reactivex.Single import io.reactivex.processors.PublishProcessor import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.internal.ClientStreamIds +import io.rsocket.kotlin.internal.RSocketRequester +import io.rsocket.kotlin.internal.RSocketResponder +import io.rsocket.kotlin.test.util.LocalDuplexConnection +import io.rsocket.kotlin.util.AbstractRSocket import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.Rule @@ -43,7 +46,7 @@ class RSocketTest { @Test(timeout = 2000) fun testRequestReplyNoError() { val subscriber = TestSubscriber.create() - rule.crs.requestResponse(PayloadImpl("hello")).toFlowable().blockingSubscribe(subscriber) + rule.crs.requestResponse(DefaultPayload("hello")).toFlowable().blockingSubscribe(subscriber) assertThat("unexpected errors", subscriber.errorCount(), `is`(0)) assertThat("unexpected payloads", subscriber.valueCount(), `is`(1)) assertThat("unexpected completions", subscriber.completions(), `is`(1L)) @@ -59,7 +62,7 @@ class RSocketTest { .delay(100, TimeUnit.MILLISECONDS) }) val subscriber = TestSubscriber.create() - rule.crs.requestResponse(PayloadImpl.EMPTY).toFlowable().blockingSubscribe(subscriber) + rule.crs.requestResponse(DefaultPayload.EMPTY).toFlowable().blockingSubscribe(subscriber) assertThat("unexpected frames", subscriber.errorCount(), `is`(1)) assertThat("unexpected frames", subscriber.valueCount(), `is`(0)) assertThat("unexpected frames", subscriber.completions(), `is`(0L)) @@ -73,7 +76,7 @@ class RSocketTest { @Throws(Exception::class) fun testChannel() { val latch = CountDownLatch(10) - val requests = Flowable.range(0, 10).map { i -> PayloadImpl("streaming in -> " + i) } + val requests = Flowable.range(0, 10).map { i -> DefaultPayload("streaming in -> " + i) } val responses = rule.crs.requestChannel(requests) @@ -118,11 +121,11 @@ class RSocketTest { override fun requestChannel(payloads: Publisher): Flowable { Flowable.fromPublisher(payloads) - .map { payload -> PayloadImpl("server got -> [$payload]") } + .map { payload -> DefaultPayload("server got -> [$payload]") } .subscribe() return Flowable.range(1, 10) - .map { payload -> PayloadImpl("server got -> [$payload]") } + .map { payload -> DefaultPayload("server got -> [$payload]") } } } diff --git a/rsocket-core/src/test/java/io/rsocket/android/RequesterStreamWindowTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RequesterStreamWindowTest.kt similarity index 87% rename from rsocket-core/src/test/java/io/rsocket/android/RequesterStreamWindowTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/RequesterStreamWindowTest.kt index 6fb7e8358..2741c0ce0 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/RequesterStreamWindowTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/RequesterStreamWindowTest.kt @@ -1,9 +1,10 @@ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Flowable import io.reactivex.processors.PublishProcessor -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.internal.ClientStreamIds +import io.rsocket.kotlin.internal.RSocketRequester +import io.rsocket.kotlin.test.util.LocalDuplexConnection import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.equalTo import org.junit.Rule @@ -21,14 +22,14 @@ class RequesterStreamWindowTest { @Test(timeout = 3_000) fun requesterStreamInbound() { checkRequesterInbound( - rule.requester.requestStream(PayloadImpl("test")), + rule.requester.requestStream(DefaultPayload("test")), FrameType.REQUEST_STREAM) } @Test(timeout = 3_000) fun requesterChannelInbound() { checkRequesterInbound( - rule.requester.requestChannel(Flowable.just(PayloadImpl("test"))), + rule.requester.requestChannel(Flowable.just(DefaultPayload("test"))), FrameType.REQUEST_CHANNEL) } @@ -36,7 +37,7 @@ class RequesterStreamWindowTest { fun requesterChannelOutbound() { var demand = -1L val request = Flowable.just(1, 2, 3) - .map { PayloadImpl(it.toString()) as Payload } + .map { DefaultPayload(it.toString()) as Payload } .doOnRequest { demand = it } rule.requester.requestChannel(request).subscribe({}, {}) rule.receiver.onNext(Frame.RequestN.from(1, Int.MAX_VALUE)) diff --git a/rsocket-core/src/test/java/io/rsocket/android/ResponderStreamWindowTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/ResponderStreamWindowTest.kt similarity index 88% rename from rsocket-core/src/test/java/io/rsocket/android/ResponderStreamWindowTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/ResponderStreamWindowTest.kt index 9c20f644c..626aae296 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/ResponderStreamWindowTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/ResponderStreamWindowTest.kt @@ -1,10 +1,11 @@ -package io.rsocket.android +package io.rsocket.kotlin import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.processors.PublishProcessor -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.internal.RSocketResponder +import io.rsocket.kotlin.test.util.LocalDuplexConnection +import io.rsocket.kotlin.util.AbstractRSocket import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers import org.junit.Rule @@ -24,7 +25,7 @@ class ResponderStreamWindowTest { fun responderStreamInbound() { rule.receiver.onNext(Frame.Request.from(1, FrameType.REQUEST_STREAM, - PayloadImpl("test"), + DefaultPayload("test"), Int.MAX_VALUE)) assertThat("responderConnection stream is not limited", rule.responseDemand, @@ -35,7 +36,7 @@ class ResponderStreamWindowTest { fun responderChannelInbound() { rule.receiver.onNext(Frame.Request.from(1, FrameType.REQUEST_CHANNEL, - PayloadImpl("test"), + DefaultPayload("test"), Int.MAX_VALUE)) assertThat("responderConnection channel is not limited", rule.responseDemand, @@ -47,7 +48,7 @@ class ResponderStreamWindowTest { Completable.timer(100,TimeUnit.MILLISECONDS).andThen { rule.receiver.onNext(Frame.Request.from(1, FrameType.REQUEST_CHANNEL, - PayloadImpl("test"), + DefaultPayload("test"), 2)) }.delay(100, TimeUnit.MILLISECONDS) .subscribe() @@ -83,13 +84,13 @@ class ResponderStreamWindowTest { object : AbstractRSocket() { override fun requestStream(payload: Payload): Flowable = Flowable.just(1, 2, 3) - .map { PayloadImpl(it.toString()) as Payload } + .map { DefaultPayload(it.toString()) as Payload } .doOnRequest { responseDemand = it } override fun requestChannel(payloads: Publisher): Flowable { Flowable.fromPublisher(payloads).subscribe() return Flowable.just(1, 2, 3) - .map { PayloadImpl(it.toString()) as Payload } + .map { DefaultPayload(it.toString()) as Payload } .doOnRequest { responseDemand = it } } }, diff --git a/rsocket-core/src/test/java/io/rsocket/android/ServiceHandlerTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/ServiceHandlerTest.kt similarity index 90% rename from rsocket-core/src/test/java/io/rsocket/android/ServiceHandlerTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/ServiceHandlerTest.kt index f9b366e3e..b08f6c73b 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/ServiceHandlerTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/ServiceHandlerTest.kt @@ -1,15 +1,13 @@ -package io.rsocket.android +package io.rsocket.kotlin import io.netty.buffer.Unpooled import io.netty.buffer.Unpooled.EMPTY_BUFFER import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.exceptions.ConnectionException -import io.rsocket.android.exceptions.RejectedSetupException -import io.rsocket.android.internal.ClientServiceHandler -import io.rsocket.android.internal.ServerServiceHandler -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.KeepAlive -import io.rsocket.android.util.KeepAliveOptions +import io.rsocket.kotlin.exceptions.ConnectionException +import io.rsocket.kotlin.exceptions.RejectedSetupException +import io.rsocket.kotlin.internal.ClientServiceHandler +import io.rsocket.kotlin.internal.ServerServiceHandler +import io.rsocket.kotlin.test.util.LocalDuplexConnection import org.junit.After import org.junit.Assert.* import org.junit.Before diff --git a/rsocket-core/src/test/java/io/rsocket/android/StreamIdsTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/StreamIdsTest.kt similarity index 94% rename from rsocket-core/src/test/java/io/rsocket/android/StreamIdsTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/StreamIdsTest.kt index c9988d71f..1dd2560be 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/StreamIdsTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/StreamIdsTest.kt @@ -14,12 +14,13 @@ * limitations under the License. */ -package io.rsocket.android +package io.rsocket.kotlin +import io.rsocket.kotlin.internal.ClientStreamIds +import io.rsocket.kotlin.internal.ServerStreamIds import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue -import org.junit.Before import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/ErrorFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/ErrorFrameFlyweightTest.kt similarity index 75% rename from rsocket-core/src/test/java/io/rsocket/android/frame/ErrorFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/ErrorFrameFlyweightTest.kt index 4d3ec608e..8339ed2a8 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/ErrorFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/ErrorFrameFlyweightTest.kt @@ -14,16 +14,26 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame -import io.rsocket.android.frame.ErrorFrameFlyweight.* import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled -import io.rsocket.android.Frame -import io.rsocket.android.exceptions.* +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.exceptions.* +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.APPLICATION_ERROR +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CANCELED +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CONNECTION_CLOSE +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.CONNECTION_ERROR +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.INVALID +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.INVALID_SETUP +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED_RESUME +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.REJECTED_SETUP +import io.rsocket.kotlin.internal.frame.ErrorFrameFlyweight.UNSUPPORTED_SETUP import java.nio.charset.StandardCharsets import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/FrameHeaderFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/FrameHeaderFlyweightTest.kt similarity index 95% rename from rsocket-core/src/test/java/io/rsocket/android/frame/FrameHeaderFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/FrameHeaderFlyweightTest.kt index 332165853..e17f63653 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/FrameHeaderFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/FrameHeaderFlyweightTest.kt @@ -14,15 +14,16 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_M -import io.rsocket.android.frame.FrameHeaderFlyweight.FRAME_HEADER_LENGTH +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_M +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FRAME_HEADER_LENGTH import org.junit.Assert.* import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled -import io.rsocket.android.FrameType +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight import org.junit.Test class FrameHeaderFlyweightTest { diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/KeepaliveFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/KeepaliveFrameFlyweightTest.kt similarity index 91% rename from rsocket-core/src/test/java/io/rsocket/android/frame/KeepaliveFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/KeepaliveFrameFlyweightTest.kt index 7e7c212c4..9d5f6301e 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/KeepaliveFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/KeepaliveFrameFlyweightTest.kt @@ -14,10 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight +import io.rsocket.kotlin.internal.frame.KeepaliveFrameFlyweight import org.junit.Assert.assertEquals import org.junit.Test import java.nio.charset.StandardCharsets diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/LeaseFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/LeaseFrameFlyweightTest.kt similarity index 94% rename from rsocket-core/src/test/java/io/rsocket/android/frame/LeaseFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/LeaseFrameFlyweightTest.kt index 29c14459a..2fab93db6 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/LeaseFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/LeaseFrameFlyweightTest.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled +import io.rsocket.kotlin.internal.frame.LeaseFrameFlyweight import org.junit.Assert.assertEquals import org.junit.Test import java.nio.charset.StandardCharsets diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/RequestFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestFrameFlyweightTest.kt similarity index 85% rename from rsocket-core/src/test/java/io/rsocket/android/frame/RequestFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestFrameFlyweightTest.kt index a2d17c7cd..522043599 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/RequestFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestFrameFlyweightTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -22,9 +22,11 @@ import org.junit.Assert.assertFalse import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.DefaultPayload +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight +import io.rsocket.kotlin.internal.frame.RequestFrameFlyweight import java.nio.charset.StandardCharsets import org.junit.Test @@ -44,7 +46,7 @@ class RequestFrameFlyweightTest { assertEquals( "000010000000011900000000010000026d6464", ByteBufUtil.hexDump(byteBuf, 0, encoded)) - val payload = PayloadImpl( + val payload = DefaultPayload( Frame.from(stringToBuf("000010000000011900000000010000026d6464"))) assertEquals("md", StandardCharsets.UTF_8.decode(payload.metadata).toString()) @@ -62,7 +64,7 @@ class RequestFrameFlyweightTest { Unpooled.copiedBuffer("d", StandardCharsets.UTF_8)) assertEquals("00000e0000000119000000000100000064", ByteBufUtil.hexDump(byteBuf, 0, encoded)) - val payload = PayloadImpl(Frame.from(stringToBuf("00000e0000000119000000000100000064"))) + val payload = DefaultPayload(Frame.from(stringToBuf("00000e0000000119000000000100000064"))) assertEquals("", StandardCharsets.UTF_8.decode(payload.metadata).toString()) } @@ -79,7 +81,7 @@ class RequestFrameFlyweightTest { Unpooled.copiedBuffer("d", StandardCharsets.UTF_8)) assertEquals("00000b0000000118000000000164", ByteBufUtil.hexDump(byteBuf, 0, encoded)) - val payload = PayloadImpl(Frame.from(stringToBuf("00000b0000000118000000000164"))) + val payload = DefaultPayload(Frame.from(stringToBuf("00000b0000000118000000000164"))) assertFalse(payload.hasMetadata()) } diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/RequestNFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestNFrameFlyweightTest.kt similarity index 91% rename from rsocket-core/src/test/java/io/rsocket/android/frame/RequestNFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestNFrameFlyweightTest.kt index 6b577730b..b5fd38927 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/RequestNFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/RequestNFrameFlyweightTest.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled +import io.rsocket.kotlin.internal.frame.RequestNFrameFlyweight import org.junit.Assert.assertEquals import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameFlyweightTest.kt similarity index 95% rename from rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameFlyweightTest.kt index 4f7a52d3e..bb601b5c3 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameFlyweightTest.kt @@ -14,13 +14,15 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame import org.junit.Assert.* import io.netty.buffer.ByteBufUtil import io.netty.buffer.Unpooled -import io.rsocket.android.FrameType +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight +import io.rsocket.kotlin.internal.frame.SetupFrameFlyweight import java.nio.charset.StandardCharsets import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameTest.kt similarity index 77% rename from rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameTest.kt index 5f92fb3ca..eaccd470c 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/SetupFrameTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/SetupFrameTest.kt @@ -1,8 +1,8 @@ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame -import io.rsocket.android.Frame -import io.rsocket.android.Setup -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.Setup +import io.rsocket.kotlin.DefaultPayload import org.junit.Assert.assertEquals import org.junit.Test @@ -13,7 +13,7 @@ class SetupFrameTest { val setupFrame = Frame.Setup.from(0, 1, 100, 1000, "metadataMime", "dataMime", - PayloadImpl.textPayload("data", "metadata")) + DefaultPayload.textPayload("data", "metadata")) val setup = Setup.create(setupFrame) assertEquals(setup.keepAliveInterval().millis, 100) assertEquals(setup.keepAliveMaxLifeTime().millis, 1000) diff --git a/rsocket-core/src/test/java/io/rsocket/android/frame/VersionFlyweightTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/VersionFlyweightTest.kt similarity index 93% rename from rsocket-core/src/test/java/io/rsocket/android/frame/VersionFlyweightTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/VersionFlyweightTest.kt index c94bcf542..ef80331ef 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/frame/VersionFlyweightTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/frame/VersionFlyweightTest.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.rsocket.android.frame +package io.rsocket.kotlin.frame +import io.rsocket.kotlin.internal.frame.VersionFlyweight import org.junit.Assert.assertEquals import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/internal/ClientDemuxerTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ClientDemuxerTest.kt similarity index 86% rename from rsocket-core/src/test/java/io/rsocket/android/internal/ClientDemuxerTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ClientDemuxerTest.kt index 207a04867..547c5658d 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/internal/ClientDemuxerTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ClientDemuxerTest.kt @@ -1,8 +1,7 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.plugins.InterceptorRegistry +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.junit.Assert import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/internal/ConnectionDemuxerTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxerTest.kt similarity index 89% rename from rsocket-core/src/test/java/io/rsocket/android/internal/ConnectionDemuxerTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxerTest.kt index 6a51fc0e5..37a76d4cf 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/internal/ConnectionDemuxerTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ConnectionDemuxerTest.kt @@ -15,18 +15,17 @@ */ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.netty.buffer.Unpooled.EMPTY_BUFFER -import io.rsocket.android.DuplexConnection +import io.rsocket.kotlin.DuplexConnection import org.junit.Assert.assertEquals -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.frame.SetupFrameFlyweight -import io.rsocket.android.plugins.InterceptorRegistry -import io.rsocket.android.test.util.TestDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.SetupFrameFlyweight +import io.rsocket.kotlin.test.util.TestDuplexConnection +import io.rsocket.kotlin.DefaultPayload import org.junit.Before import java.util.concurrent.atomic.AtomicInteger import org.junit.Test @@ -75,7 +74,7 @@ internal abstract class ConnectionDemuxerTest { val metadata = Frame.Request.from( 0, FrameType.METADATA_PUSH, - PayloadImpl.textPayload("", "md"), + DefaultPayload.textPayload("", "md"), 1) source.addToReceivedBuffer(metadata) @@ -109,7 +108,7 @@ internal abstract class ConnectionDemuxerTest { 0, 0, "test", "test", - PayloadImpl.EMPTY) + DefaultPayload.EMPTY) source.addToReceivedBuffer(setup) assertEquals(0, responderFrames.get()) assertEquals(0, requesterFrames.get()) diff --git a/rsocket-core/src/test/java/io/rsocket/android/internal/ServerDemuxerTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ServerDemuxerTest.kt similarity index 86% rename from rsocket-core/src/test/java/io/rsocket/android/internal/ServerDemuxerTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ServerDemuxerTest.kt index a5b2ce88c..2e16188c7 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/internal/ServerDemuxerTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/ServerDemuxerTest.kt @@ -1,8 +1,7 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.plugins.InterceptorRegistry +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.junit.Assert import org.junit.Test diff --git a/rsocket-core/src/test/java/io/rsocket/android/internal/SetupContractTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/SetupContractTest.kt similarity index 91% rename from rsocket-core/src/test/java/io/rsocket/android/internal/SetupContractTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/SetupContractTest.kt index 71ae868ff..7df9e4ec1 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/internal/SetupContractTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/SetupContractTest.kt @@ -1,16 +1,15 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.processors.ReplayProcessor import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.exceptions.Exceptions -import io.rsocket.android.exceptions.InvalidSetupException -import io.rsocket.android.exceptions.RejectedSetupException -import io.rsocket.android.exceptions.SetupException -import io.rsocket.android.frame.SetupFrameFlyweight -import io.rsocket.android.test.util.LocalDuplexConnection -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.exceptions.Exceptions +import io.rsocket.kotlin.exceptions.InvalidSetupException +import io.rsocket.kotlin.exceptions.RejectedSetupException +import io.rsocket.kotlin.internal.frame.SetupFrameFlyweight +import io.rsocket.kotlin.test.util.LocalDuplexConnection +import io.rsocket.kotlin.DefaultPayload import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before @@ -46,7 +45,7 @@ class SetupContractTest { 0, "md", "d", - PayloadImpl.EMPTY) + DefaultPayload.EMPTY) val subs = TestSubscriber() receiver.onNext(frame) setupContract.receive().subscribe(subs) @@ -84,7 +83,7 @@ class SetupContractTest { 0, "md", "d", - PayloadImpl.EMPTY) + DefaultPayload.EMPTY) val subs = TestSubscriber() receiver.onNext(frame) setupContract.receive().subscribe(subs) @@ -117,7 +116,7 @@ class SetupContractTest { 0, "md", "d", - PayloadImpl.EMPTY) + DefaultPayload.EMPTY) val subs = TestSubscriber() receiver.onNext(frame) setupContract.receive().subscribe(subs) @@ -155,7 +154,7 @@ class SetupContractTest { 0, "md", "d", - PayloadImpl.EMPTY) + DefaultPayload.EMPTY) val subs = TestSubscriber() receiver.onNext(frame) setupContract.receive().subscribe(subs) diff --git a/rsocket-core/src/test/java/io/rsocket/android/internal/StreamReceiverTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/StreamReceiverTest.kt similarity index 93% rename from rsocket-core/src/test/java/io/rsocket/android/internal/StreamReceiverTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/StreamReceiverTest.kt index 4a8a11334..29d4509ba 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/internal/StreamReceiverTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/StreamReceiverTest.kt @@ -1,14 +1,14 @@ -package io.rsocket.android.internal +package io.rsocket.kotlin.internal import io.reactivex.Flowable import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.Payload +import io.rsocket.kotlin.Payload import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import java.util.concurrent.TimeUnit -class StreamReceiverTest { +internal class StreamReceiverTest { lateinit var receiver: StreamReceiver lateinit var subs: TestSubscriber @Before diff --git a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/FragmentationDuplexConnectionTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnectionTest.kt similarity index 90% rename from rsocket-core/src/test/java/io/rsocket/android/fragmentation/FragmentationDuplexConnectionTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnectionTest.kt index 40a546c8c..45084ae97 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/FragmentationDuplexConnectionTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FragmentationDuplexConnectionTest.kt @@ -15,18 +15,18 @@ */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.Schedulers import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.frame.FrameHeaderFlyweight.FLAGS_F -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.internal.frame.FrameHeaderFlyweight.FLAGS_F +import io.rsocket.kotlin.DefaultPayload import org.junit.Assert.* import org.junit.Before import org.junit.Test @@ -74,7 +74,7 @@ class FragmentationDuplexConnectionTest { val metadata = createRandomBytes(16) val frame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val mtu = 2 val duplexConnection = FragmentationDuplexConnection(mockConnection, mtu) @@ -113,7 +113,7 @@ class FragmentationDuplexConnectionTest { val metadata = createRandomBytes(1) val frame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val mtu = 2 val duplexConnection = FragmentationDuplexConnection(mockConnection, mtu) @@ -146,7 +146,7 @@ class FragmentationDuplexConnectionTest { val metadata = null val frame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val mtu = 2 val duplexConnection = FragmentationDuplexConnection(mockConnection, mtu) @@ -174,7 +174,7 @@ class FragmentationDuplexConnectionTest { val metadata = createRandomBytes(1) val frame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val mtu = 20 val duplexConnection = FragmentationDuplexConnection(mockConnection, mtu) @@ -197,7 +197,7 @@ class FragmentationDuplexConnectionTest { val metadata = createRandomBytes(1) val frame = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val mtu = 0 val duplexConnection = FragmentationDuplexConnection(mockConnection, mtu) @@ -248,11 +248,11 @@ class FragmentationDuplexConnectionTest { val metadata = createRandomBytes(16) val frame1 = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frame2 = Frame.Request.from( - 2, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 2, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frame3 = Frame.Request.from( - 3, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 3, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val duplexConnection = FragmentationDuplexConnection(mockConnection, 2) @@ -270,7 +270,7 @@ class FragmentationDuplexConnectionTest { val data = createRandomBytes(16) val metadata = createRandomBytes(16) val frame = Frame.Request.from( - 1024, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1024, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val fragmentedFrames = frameFragmenter.fragment(frame) val processor = PublishProcessor.create() diff --git a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/FrameFragmenterTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenterTest.kt similarity index 83% rename from rsocket-core/src/test/java/io/rsocket/android/fragmentation/FrameFragmenterTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenterTest.kt index 44b135996..080da0ec7 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/FrameFragmenterTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/FrameFragmenterTest.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation import io.reactivex.subscribers.TestSubscriber -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.DefaultPayload import org.junit.Assert.assertFalse import org.junit.Test import java.nio.ByteBuffer @@ -32,7 +32,7 @@ class FrameFragmenterTest { val metadata = createRandomBytes(16) val from = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val subs = TestSubscriber.create() @@ -46,7 +46,7 @@ class FrameFragmenterTest { val metadata = createRandomBytes(17) val from = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val subs = TestSubscriber.create() @@ -60,7 +60,7 @@ class FrameFragmenterTest { val metadata = createRandomBytes(16) val from = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val subs = TestSubscriber.create() @@ -74,7 +74,7 @@ class FrameFragmenterTest { val metadata = createRandomBytes(16) val frameFragmenter = FrameFragmenter(0) assertFalse(frameFragmenter.shouldFragment(Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1)) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1)) ) } @@ -84,7 +84,7 @@ class FrameFragmenterTest { val metadata = ByteBuffer.allocate(0) val from = Frame.Request.from( - 1, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val subs = TestSubscriber.create() diff --git a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/StreamFramesReassemblerTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassemblerTest.kt similarity index 73% rename from rsocket-core/src/test/java/io/rsocket/android/fragmentation/StreamFramesReassemblerTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassemblerTest.kt index 6212c399b..f69bf462e 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/fragmentation/StreamFramesReassemblerTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/internal/fragmentation/StreamFramesReassemblerTest.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.rsocket.android.fragmentation +package io.rsocket.kotlin.internal.fragmentation -import io.rsocket.android.Frame -import io.rsocket.android.FrameType -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.Frame +import io.rsocket.kotlin.FrameType +import io.rsocket.kotlin.DefaultPayload import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test @@ -33,28 +33,28 @@ class StreamFramesReassemblerTest { val metadata = createRandomBytes(16) val from = Frame.Request.from( - 1024, FrameType.REQUEST_RESPONSE, PayloadImpl(data, metadata), 1) + 1024, FrameType.REQUEST_RESPONSE, DefaultPayload(data, metadata), 1) val frameFragmenter = FrameFragmenter(2) val frameReassembler = StreamFramesReassembler(from) frameFragmenter.fragment(from) .doOnNext { frameReassembler.append(it) } .blockingLast() val reassemble = frameReassembler.reassemble() - assertEquals(reassemble.streamId, from.streamId); - assertEquals(reassemble.type, from.type); + assertEquals(reassemble.streamId, from.streamId) + assertEquals(reassemble.type, from.type) - val reassembleData = reassemble.data; - val reassembleMetadata = reassemble.metadata; + val reassembleData = reassemble.data + val reassembleMetadata = reassemble.metadata - assertTrue(reassembleData.hasRemaining()); - assertTrue(reassembleMetadata.hasRemaining()); + assertTrue(reassembleData.hasRemaining()) + assertTrue(reassembleMetadata.hasRemaining()) while (reassembleData.hasRemaining()) { - assertEquals(reassembleData.get(), data.get()); + assertEquals(reassembleData.get(), data.get()) } while (reassembleMetadata.hasRemaining()) { - assertEquals(reassembleMetadata.get(), metadata.get()); + assertEquals(reassembleMetadata.get(), metadata.get()) } } diff --git a/rsocket-core/src/test/java/io/rsocket/android/test/util/LocalDuplexConnection.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/LocalDuplexConnection.kt similarity index 94% rename from rsocket-core/src/test/java/io/rsocket/android/test/util/LocalDuplexConnection.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/LocalDuplexConnection.kt index d9c6e1a4d..8d6c7697b 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/test/util/LocalDuplexConnection.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/LocalDuplexConnection.kt @@ -15,14 +15,14 @@ */ -package io.rsocket.android.test.util +package io.rsocket.kotlin.test.util import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.processors.FlowableProcessor import io.reactivex.processors.PublishProcessor -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.reactivestreams.Publisher class LocalDuplexConnection( diff --git a/rsocket-core/src/test/java/io/rsocket/android/test/util/MockRSocket.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/MockRSocket.kt similarity index 96% rename from rsocket-core/src/test/java/io/rsocket/android/test/util/MockRSocket.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/MockRSocket.kt index 1be80b59f..c75bc3d5e 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/test/util/MockRSocket.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/MockRSocket.kt @@ -15,7 +15,7 @@ */ -package io.rsocket.android.test.util +package io.rsocket.kotlin.test.util import io.reactivex.Completable import io.reactivex.Flowable @@ -23,8 +23,8 @@ import io.reactivex.Single import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` -import io.rsocket.android.Payload -import io.rsocket.android.RSocket +import io.rsocket.kotlin.Payload +import io.rsocket.kotlin.RSocket import java.util.concurrent.atomic.AtomicInteger import org.reactivestreams.Publisher diff --git a/rsocket-core/src/test/java/io/rsocket/android/test/util/TestDuplexConnection.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestDuplexConnection.kt similarity index 96% rename from rsocket-core/src/test/java/io/rsocket/android/test/util/TestDuplexConnection.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestDuplexConnection.kt index aac2da517..0ceaa465e 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/test/util/TestDuplexConnection.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestDuplexConnection.kt @@ -15,13 +15,13 @@ */ -package io.rsocket.android.test.util +package io.rsocket.kotlin.test.util import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.processors.PublishProcessor -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.LinkedBlockingQueue import org.reactivestreams.Publisher diff --git a/rsocket-core/src/test/java/io/rsocket/android/test/util/TestSubscriber.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestSubscriber.kt similarity index 94% rename from rsocket-core/src/test/java/io/rsocket/android/test/util/TestSubscriber.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestSubscriber.kt index 13444f665..e0dd79904 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/test/util/TestSubscriber.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/test/util/TestSubscriber.kt @@ -1,9 +1,9 @@ -package io.rsocket.android.test.util +package io.rsocket.kotlin.test.util import org.mockito.ArgumentMatchers.any import org.mockito.Mockito.mock -import io.rsocket.android.Payload +import io.rsocket.kotlin.Payload import org.mockito.Mockito import org.reactivestreams.Subscriber import org.reactivestreams.Subscription diff --git a/rsocket-core/src/test/java/io/rsocket/android/util/PayloadImplTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/DefaultPayloadTest.kt similarity index 85% rename from rsocket-core/src/test/java/io/rsocket/android/util/PayloadImplTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/DefaultPayloadTest.kt index b49a14152..56ddb5091 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/util/PayloadImplTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/DefaultPayloadTest.kt @@ -11,27 +11,28 @@ * specific language governing permissions and limitations under the License. */ -package io.rsocket.android.util +package io.rsocket.kotlin.util import org.hamcrest.MatcherAssert.* import org.hamcrest.Matchers.* -import io.rsocket.android.Payload -import io.rsocket.android.util.PayloadImpl.Companion.textPayload +import io.rsocket.kotlin.Payload +import io.rsocket.kotlin.DefaultPayload +import io.rsocket.kotlin.DefaultPayload.Companion.textPayload import org.junit.Test -class PayloadImplTest { +class DefaultPayloadTest { @Test fun testReuse() { - val p = PayloadImpl(DATA_VAL, METADATA_VAL) + val p = DefaultPayload(DATA_VAL, METADATA_VAL) assertDataAndMetadata(p, DATA_VAL, METADATA_VAL) assertDataAndMetadata(p, DATA_VAL, METADATA_VAL) } @Test fun testReuseWithExternalMark() { - val p = PayloadImpl(DATA_VAL, METADATA_VAL) + val p = DefaultPayload(DATA_VAL, METADATA_VAL) assertDataAndMetadata(p, DATA_VAL, METADATA_VAL) p.data.position(2).mark() assertDataAndMetadata(p, DATA_VAL, METADATA_VAL) diff --git a/rsocket-core/src/test/java/io/rsocket/android/util/ExceptionUtilTest.kt b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/ExceptionUtilTest.kt similarity index 87% rename from rsocket-core/src/test/java/io/rsocket/android/util/ExceptionUtilTest.kt rename to rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/ExceptionUtilTest.kt index fed1d923f..0ff9092c1 100644 --- a/rsocket-core/src/test/java/io/rsocket/android/util/ExceptionUtilTest.kt +++ b/rsocket-core/src/test/kotlin/io/rsocket/kotlin/util/ExceptionUtilTest.kt @@ -1,6 +1,6 @@ -package io.rsocket.android.util +package io.rsocket.kotlin.util -import io.rsocket.android.util.ExceptionUtil.noStacktrace +import io.rsocket.kotlin.internal.ExceptionUtil.noStacktrace import org.junit.Assert.assertEquals import java.io.PrintWriter diff --git a/rsocket-transport-netty/build.gradle b/rsocket-transport-netty/build.gradle index 943efe367..69e155cec 100644 --- a/rsocket-transport-netty/build.gradle +++ b/rsocket-transport-netty/build.gradle @@ -1,6 +1,5 @@ -repositories { - maven { url 'https://repo.spring.io/libs-snapshot' } -} +apply plugin: 'com.jfrog.bintray' +apply plugin: 'com.jfrog.artifactory' dependencies { api project(":rsocket-core") diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/Ext.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/Ext.kt similarity index 77% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/Ext.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/Ext.kt index d83e6384d..532c54608 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/Ext.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/Ext.kt @@ -1,4 +1,4 @@ -package io.rsocket.android.transport.netty +package io.rsocket.kotlin.transport.netty import io.reactivex.Completable import io.reactivex.Flowable @@ -12,4 +12,8 @@ internal fun Mono.toCompletable(): Completable = Completable.fromPublisher internal fun Mono.toSingle(): Single = Single.fromPublisher(this) -internal fun Completable.toMono(): Mono = Mono.from(toFlowable()) \ No newline at end of file +internal fun Completable.toMono(): Mono = Mono.from(toFlowable()) + +internal const val frameLengthSize = 3 + +internal const val frameLengthMask = 0xFFFFFF \ No newline at end of file diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/NettyDuplexConnection.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/NettyDuplexConnection.kt similarity index 94% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/NettyDuplexConnection.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/NettyDuplexConnection.kt index 90b26afc2..5a2b49821 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/NettyDuplexConnection.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/NettyDuplexConnection.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty +package io.rsocket.kotlin.transport.netty import io.reactivex.Completable import io.reactivex.Flowable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.reactivestreams.Publisher import reactor.ipc.netty.NettyContext import reactor.ipc.netty.NettyInbound diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/RSocketLengthCodec.java b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/RSocketLengthCodec.kt similarity index 53% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/RSocketLengthCodec.java rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/RSocketLengthCodec.kt index eadb78fb2..e2d92d5b3 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/RSocketLengthCodec.java +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/RSocketLengthCodec.kt @@ -14,20 +14,17 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty; +package io.rsocket.kotlin.transport.netty -import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.buffer.ByteBuf +import io.netty.handler.codec.LengthFieldBasedFrameDecoder -import static io.rsocket.android.frame.FrameHeaderFlyweight.FRAME_LENGTH_MASK; -import static io.rsocket.android.frame.FrameHeaderFlyweight.FRAME_LENGTH_SIZE; +class RSocketLengthCodec : LengthFieldBasedFrameDecoder( + frameLengthMask, + 0, + frameLengthSize, + 0, + 0) { -public class RSocketLengthCodec extends LengthFieldBasedFrameDecoder { - public RSocketLengthCodec() { - super(FRAME_LENGTH_MASK, 0, FRAME_LENGTH_SIZE, 0, 0); - } - - public Object decode(ByteBuf in) throws Exception { - return decode(null, in); - } + fun decode(bytebuf: ByteBuf): Any = decode(null, bytebuf) } diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/WebsocketDuplexConnection.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/WebsocketDuplexConnection.kt similarity index 76% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/WebsocketDuplexConnection.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/WebsocketDuplexConnection.kt index 9a0deb568..cd504b5e2 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/WebsocketDuplexConnection.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/WebsocketDuplexConnection.kt @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.rsocket.android.transport.netty +package io.rsocket.kotlin.transport.netty +import io.netty.buffer.ByteBuf import io.netty.buffer.Unpooled.wrappedBuffer import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame import io.reactivex.Completable import io.reactivex.Flowable -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.frame.FrameHeaderFlyweight -import io.rsocket.android.frame.FrameHeaderFlyweight.FRAME_LENGTH_SIZE +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame import org.reactivestreams.Publisher import reactor.ipc.netty.NettyContext import reactor.ipc.netty.NettyInbound @@ -32,7 +31,7 @@ import reactor.ipc.netty.NettyOutbound * Implementation of a DuplexConnection for Websocket. * * - * rsocket-java strongly assumes that each Frame is encoded with the length. This is not true for + * RSocket impl strongly assumes that each Frame is encoded with the length. This is not true for * message oriented transports so this must be specifically dropped from Frames sent and stitched * back on for frames received. */ @@ -49,7 +48,7 @@ class WebsocketDuplexConnection(private val inbound: NettyInbound, override fun sendOne(frame: Frame): Completable { return outbound.sendObject( BinaryWebSocketFrame( - frame.content().skipBytes(FRAME_LENGTH_SIZE))) + frame.content().skipBytes(frameLengthSize))) .then() .toCompletable() } @@ -58,8 +57,8 @@ class WebsocketDuplexConnection(private val inbound: NettyInbound, return inbound.receive() .map { buf -> val composite = context.channel().alloc().compositeBuffer() - val length = wrappedBuffer(ByteArray(FRAME_LENGTH_SIZE)) - FrameHeaderFlyweight.encodeLength(length, 0, buf.readableBytes()) + val length = wrappedBuffer(ByteArray(frameLengthSize)) + encodeLength(length, 0, buf.readableBytes()) composite.addComponents(true, length, buf.retain()) Frame.from(composite) }.toFlowable() @@ -75,4 +74,13 @@ class WebsocketDuplexConnection(private val inbound: NettyInbound, } override fun onClose(): Completable = context.onClose().toCompletable() + + private fun encodeLength(byteBuf: ByteBuf, offset: Int, length: Int) { + if (length and frameLengthMask.inv() != 0) { + throw IllegalArgumentException("Length is larger than 24 bits") + } + byteBuf.setByte(offset, length shr 16) + byteBuf.setByte(offset + 1, length shr 8) + byteBuf.setByte(offset + 2, length) + } } diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/TcpClientTransport.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/TcpClientTransport.kt similarity index 87% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/TcpClientTransport.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/TcpClientTransport.kt index 3ce8d2465..9b72db2da 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/TcpClientTransport.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/TcpClientTransport.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.client +package io.rsocket.kotlin.transport.netty.client import io.reactivex.Single -import io.rsocket.android.DuplexConnection -import io.rsocket.android.transport.ClientTransport -import io.rsocket.android.transport.netty.NettyDuplexConnection -import io.rsocket.android.transport.netty.RSocketLengthCodec -import io.rsocket.android.transport.netty.toMono +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.transport.ClientTransport +import io.rsocket.kotlin.transport.netty.NettyDuplexConnection +import io.rsocket.kotlin.transport.netty.RSocketLengthCodec +import io.rsocket.kotlin.transport.netty.toMono import reactor.ipc.netty.tcp.TcpClient import java.net.InetSocketAddress diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/WebsocketClientTransport.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/WebsocketClientTransport.kt similarity index 92% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/WebsocketClientTransport.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/WebsocketClientTransport.kt index d42cd918c..4874cffbd 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/client/WebsocketClientTransport.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/client/WebsocketClientTransport.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.client +package io.rsocket.kotlin.transport.netty.client import io.reactivex.Single -import io.rsocket.android.DuplexConnection -import io.rsocket.android.transport.ClientTransport -import io.rsocket.android.transport.TransportHeaderAware -import io.rsocket.android.transport.netty.WebsocketDuplexConnection -import io.rsocket.android.transport.netty.toMono +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.transport.ClientTransport +import io.rsocket.kotlin.transport.TransportHeaderAware +import io.rsocket.kotlin.transport.netty.WebsocketDuplexConnection +import io.rsocket.kotlin.transport.netty.toMono import reactor.ipc.netty.http.client.HttpClient import java.net.InetSocketAddress import java.net.URI diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/NettyContextCloseable.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/NettyContextCloseable.kt similarity index 90% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/NettyContextCloseable.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/NettyContextCloseable.kt index 90b41bff8..1417f89e9 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/NettyContextCloseable.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/NettyContextCloseable.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.server +package io.rsocket.kotlin.transport.netty.server import io.reactivex.Completable -import io.rsocket.android.Closeable -import io.rsocket.android.transport.netty.toCompletable +import io.rsocket.kotlin.Closeable +import io.rsocket.kotlin.transport.netty.toCompletable import reactor.ipc.netty.NettyContext import java.net.InetSocketAddress diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/TcpServerTransport.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/TcpServerTransport.kt similarity index 88% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/TcpServerTransport.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/TcpServerTransport.kt index 071febfef..d9042b020 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/TcpServerTransport.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/TcpServerTransport.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.server +package io.rsocket.kotlin.transport.netty.server import io.reactivex.Single -import io.rsocket.android.transport.ServerTransport -import io.rsocket.android.transport.netty.NettyDuplexConnection -import io.rsocket.android.transport.netty.RSocketLengthCodec -import io.rsocket.android.transport.netty.toSingle +import io.rsocket.kotlin.transport.ServerTransport +import io.rsocket.kotlin.transport.netty.NettyDuplexConnection +import io.rsocket.kotlin.transport.netty.RSocketLengthCodec +import io.rsocket.kotlin.transport.netty.toSingle import reactor.ipc.netty.tcp.TcpServer import java.net.InetSocketAddress diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketRouteTransport.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketRouteTransport.kt similarity index 83% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketRouteTransport.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketRouteTransport.kt index 9779f37e3..df442a31e 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketRouteTransport.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketRouteTransport.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.server +package io.rsocket.kotlin.transport.netty.server import io.reactivex.Single -import io.rsocket.android.Closeable -import io.rsocket.android.transport.ServerTransport -import io.rsocket.android.transport.ServerTransport.ConnectionAcceptor -import io.rsocket.android.transport.netty.WebsocketDuplexConnection -import io.rsocket.android.transport.netty.toSingle +import io.rsocket.kotlin.Closeable +import io.rsocket.kotlin.transport.ServerTransport +import io.rsocket.kotlin.transport.ServerTransport.ConnectionAcceptor +import io.rsocket.kotlin.transport.netty.WebsocketDuplexConnection +import io.rsocket.kotlin.transport.netty.toSingle import reactor.core.publisher.Mono import reactor.ipc.netty.http.server.HttpServer import reactor.ipc.netty.http.server.HttpServerRoutes diff --git a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketServerTransport.kt b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketServerTransport.kt similarity index 89% rename from rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketServerTransport.kt rename to rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketServerTransport.kt index 492bd4ee3..218b436bd 100644 --- a/rsocket-transport-netty/src/main/java/io/rsocket/android/transport/netty/server/WebsocketServerTransport.kt +++ b/rsocket-transport-netty/src/main/kotlin/io/rsocket/kotlin/transport/netty/server/WebsocketServerTransport.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.rsocket.android.transport.netty.server +package io.rsocket.kotlin.transport.netty.server import io.reactivex.Single -import io.rsocket.android.transport.ServerTransport -import io.rsocket.android.transport.TransportHeaderAware -import io.rsocket.android.transport.netty.WebsocketDuplexConnection -import io.rsocket.android.transport.netty.toSingle +import io.rsocket.kotlin.transport.ServerTransport +import io.rsocket.kotlin.transport.TransportHeaderAware +import io.rsocket.kotlin.transport.netty.WebsocketDuplexConnection +import io.rsocket.kotlin.transport.netty.toSingle import reactor.ipc.netty.http.server.HttpServer class WebsocketServerTransport private constructor(internal var server: HttpServer) diff --git a/rsocket-transport-okhttp/build.gradle b/rsocket-transport-okhttp/build.gradle index f0f1780bf..22efb06e2 100644 --- a/rsocket-transport-okhttp/build.gradle +++ b/rsocket-transport-okhttp/build.gradle @@ -1,3 +1,6 @@ +apply plugin: 'com.jfrog.bintray' +apply plugin: 'com.jfrog.artifactory' + dependencies { api project(":rsocket-core") api 'com.squareup.okhttp3:okhttp:3.10.0' diff --git a/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkHttpWebSocketConnection.kt b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkHttpWebSocketConnection.kt new file mode 100644 index 000000000..303b61a6f --- /dev/null +++ b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkHttpWebSocketConnection.kt @@ -0,0 +1,20 @@ +package io.rsocket.transport.okhttp + +import io.reactivex.Flowable +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.Frame +import org.reactivestreams.Publisher + +class OkHttpWebSocketConnection internal constructor(private val ws: OkWebsocket) + : DuplexConnection { + + override fun availability(): Double = if (ws.isOpen) 1.0 else 0.0 + + override fun close() = ws.close() + + override fun onClose() = ws.onClose() + + override fun send(frame: Publisher) = ws.send(frame) + + override fun receive(): Flowable = ws.receive() +} \ No newline at end of file diff --git a/rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/OkhttpWebsocketConnection.kt b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkWebsocket.kt similarity index 71% rename from rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/OkhttpWebsocketConnection.kt rename to rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkWebsocket.kt index c9d35a31c..6b4e67e2d 100644 --- a/rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/OkhttpWebsocketConnection.kt +++ b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/OkWebsocket.kt @@ -7,10 +7,7 @@ import io.reactivex.Flowable import io.reactivex.Single import io.reactivex.processors.BehaviorProcessor import io.reactivex.processors.UnicastProcessor -import io.rsocket.android.DuplexConnection -import io.rsocket.android.Frame -import io.rsocket.android.frame.FrameHeaderFlyweight.* -import io.rsocket.android.util.ExceptionUtil.noStacktrace +import io.rsocket.kotlin.Frame import okhttp3.* import okio.ByteString import org.reactivestreams.Publisher @@ -19,7 +16,7 @@ import java.nio.channels.ClosedChannelException /** * Created by Maksym Ostroverkhov on 27.10.17. */ -internal class OkWebSocket(client: OkHttpClient, +internal class OkWebsocket(client: OkHttpClient, request: Request) { @Volatile internal var isOpen = false @@ -34,7 +31,7 @@ internal class OkWebSocket(client: OkHttpClient, private val listener = object : WebSocketListener() { override fun onOpen(webSocket: WebSocket?, response: Response?) { isOpen = true - connection.onNext(OkHttpWebSocketConnection(this@OkWebSocket)) + connection.onNext(OkHttpWebSocketConnection(this@OkWebsocket)) } override fun onMessage(webSocket: WebSocket?, bytes: ByteString) { @@ -46,7 +43,7 @@ internal class OkWebSocket(client: OkHttpClient, private fun writeFrame(msgBuffer: ByteBuf): ByteBuf { val msgSize = msgBuffer.readableBytes() - val frameSize = msgSize + FRAME_LENGTH_SIZE + val frameSize = msgSize + frameLengthSize val frameBuffer = Unpooled.buffer(frameSize, frameSize) frameBuffer.writeByte(msgSize shr 16) @@ -57,12 +54,16 @@ internal class OkWebSocket(client: OkHttpClient, return frameBuffer } - override fun onClosed(webSocket: WebSocket?, code: Int, reason: String?) { + override fun onClosed(webSocket: WebSocket?, + code: Int, + reason: String?) { isOpen = false connection.onComplete() } - override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { + override fun onFailure(webSocket: WebSocket, + t: Throwable, + response: Response?) { connection.onError(t) if (isOpen) { val closedChannelException = ClosedChannelException() @@ -75,7 +76,7 @@ internal class OkWebSocket(client: OkHttpClient, private val ws = client.newWebSocket(request, listener) - fun connected(): Single = connection + fun onConnect(): Single = connection .firstOrError() .doOnDispose { ws.cancel() } @@ -84,12 +85,12 @@ internal class OkWebSocket(client: OkHttpClient, fun send(frames: Publisher): Completable = Flowable.fromPublisher(frames) .map { it.content() } - .map { it.skipBytes(FRAME_LENGTH_SIZE).slice().nioBuffer() } + .map { it.skipBytes(frameLengthSize).slice().nioBuffer() } .map { ByteString.of(it) } .flatMapCompletable { ws.sendAsync(it) } fun close(): Completable = Completable.create { e -> - ws.close(NORMAL_CLOSE, "close") + ws.close(normalClose, "close") e.onComplete() } @@ -99,23 +100,25 @@ internal class OkWebSocket(client: OkHttpClient, private fun WebSocket.sendAsync(bytes: ByteString): Completable = Completable.create { e -> - if (send(bytes)) e.onComplete() else e.onError(failErr ?: defFailErr) + if (send(bytes)) + e.onComplete() + else + e.onError(failErr ?: defFailErr) } companion object { - val NORMAL_CLOSE = 1000 + private const val normalClose = 1000 + private const val frameLengthSize = 3 + + private fun noStacktrace(ex: T): T { + ex.stackTrace = arrayOf(StackTraceElement( + ex.javaClass.name, + "", + null, + -1)) + return ex + } + } } -class OkHttpWebSocketConnection internal constructor(private val ws: OkWebSocket) : DuplexConnection { - - override fun availability(): Double = if (ws.isOpen) 1.0 else 0.0 - - override fun close() = ws.close() - - override fun onClose() = ws.onClose() - - override fun send(frame: Publisher) = ws.send(frame) - - override fun receive(): Flowable = ws.receive() -} \ No newline at end of file diff --git a/rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt similarity index 51% rename from rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt rename to rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt index a7ba4093f..f2afaca75 100644 --- a/rsocket-transport-okhttp/src/main/java/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt +++ b/rsocket-transport-okhttp/src/main/kotlin/io/rsocket/transport/okhttp/client/OkhttpWebsocketClientTransport.kt @@ -1,9 +1,9 @@ package io.rsocket.transport.okhttp.client -import io.rsocket.transport.okhttp.OkWebSocket +import io.rsocket.transport.okhttp.OkWebsocket import io.reactivex.Single -import io.rsocket.android.DuplexConnection -import io.rsocket.android.transport.ClientTransport +import io.rsocket.kotlin.DuplexConnection +import io.rsocket.kotlin.transport.ClientTransport import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Request @@ -12,19 +12,24 @@ import okhttp3.Request * Created by Maksym Ostroverkhov on 28.10.17. */ class OkhttpWebsocketClientTransport private constructor(private val client: OkHttpClient, - private val request: Request) : ClientTransport { - override fun connect(): Single = Single.defer { - OkWebSocket(client, request).connected() - } + private val request: Request) + : ClientTransport { + override fun connect(): Single = + Single.defer { OkWebsocket(client, request).onConnect() } companion object { - fun create(request: Request): OkhttpWebsocketClientTransport = create(defaultClient, request) + fun create(request: Request): OkhttpWebsocketClientTransport = + create(defaultClient, request) - fun create(url: HttpUrl): OkhttpWebsocketClientTransport = create(defaultClient, request(url)) + fun create(url: HttpUrl): OkhttpWebsocketClientTransport = + create(defaultClient, request(url)) - fun create(client: OkHttpClient, url: HttpUrl): OkhttpWebsocketClientTransport = create(client, request(url)) + fun create(client: OkHttpClient, + url: HttpUrl): OkhttpWebsocketClientTransport = + create(client, request(url)) - fun create(client: OkHttpClient, request: Request): OkhttpWebsocketClientTransport = + fun create(client: OkHttpClient, request: Request) + : OkhttpWebsocketClientTransport = OkhttpWebsocketClientTransport(client, request) private val defaultClient by lazy { OkHttpClient() } diff --git a/settings.gradle b/settings.gradle index edfd49930..812a55605 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,9 +15,8 @@ include ':rsocket-transport-okhttp' * limitations under the License. */ -rootProject.name='rsocket-android' +rootProject.name='rsocket-kotlin' include 'rsocket-core' -project(':rsocket-core').name = 'rsocket-core' include 'rsocket-transport-okhttp' include 'rsocket-transport-netty' include 'test' diff --git a/test/src/test/kotlin/io/rsocket/android/test/ClientServerChannelTest.kt b/test/src/test/kotlin/io/rsocket/kotlin/test/ClientServerChannelTest.kt similarity index 84% rename from test/src/test/kotlin/io/rsocket/android/test/ClientServerChannelTest.kt rename to test/src/test/kotlin/io/rsocket/kotlin/test/ClientServerChannelTest.kt index 58195c7e9..52fcf9e23 100644 --- a/test/src/test/kotlin/io/rsocket/android/test/ClientServerChannelTest.kt +++ b/test/src/test/kotlin/io/rsocket/kotlin/test/ClientServerChannelTest.kt @@ -1,15 +1,15 @@ -package io.rsocket.android.test +package io.rsocket.kotlin.test import io.reactivex.Flowable import io.reactivex.Single -import io.rsocket.android.AbstractRSocket -import io.rsocket.android.Payload -import io.rsocket.android.RSocket -import io.rsocket.android.RSocketFactory -import io.rsocket.android.transport.netty.client.TcpClientTransport -import io.rsocket.android.transport.netty.server.NettyContextCloseable -import io.rsocket.android.transport.netty.server.TcpServerTransport -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.util.AbstractRSocket +import io.rsocket.kotlin.Payload +import io.rsocket.kotlin.RSocket +import io.rsocket.kotlin.RSocketFactory +import io.rsocket.kotlin.transport.netty.client.TcpClientTransport +import io.rsocket.kotlin.transport.netty.server.NettyContextCloseable +import io.rsocket.kotlin.transport.netty.server.TcpServerTransport +import io.rsocket.kotlin.DefaultPayload import org.junit.Before import org.junit.Test import org.reactivestreams.Publisher @@ -88,7 +88,7 @@ class ClientServerChannelTest { internal fun textStream(intervalMillis: Long) = Flowable.interval(intervalMillis, TimeUnit.MICROSECONDS) .onBackpressureDrop() - .map { PayloadImpl.textPayload(it.toString()) } + .map { DefaultPayload.textPayload(it.toString()) } internal const val intervalMillis: Long = 100 } diff --git a/test/src/test/kotlin/io/rsocket/android/test/EndToEndTest.kt b/test/src/test/kotlin/io/rsocket/kotlin/test/EndToEndTest.kt similarity index 93% rename from test/src/test/kotlin/io/rsocket/android/test/EndToEndTest.kt rename to test/src/test/kotlin/io/rsocket/kotlin/test/EndToEndTest.kt index 7fe32ced9..292fa4c2b 100644 --- a/test/src/test/kotlin/io/rsocket/android/test/EndToEndTest.kt +++ b/test/src/test/kotlin/io/rsocket/kotlin/test/EndToEndTest.kt @@ -1,14 +1,15 @@ -package io.rsocket.android.test +package io.rsocket.kotlin.test import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.Single import io.reactivex.processors.BehaviorProcessor -import io.rsocket.android.* -import io.rsocket.android.transport.ClientTransport -import io.rsocket.android.transport.ServerTransport -import io.rsocket.android.transport.netty.server.NettyContextCloseable -import io.rsocket.android.util.PayloadImpl +import io.rsocket.kotlin.* +import io.rsocket.kotlin.transport.ClientTransport +import io.rsocket.kotlin.transport.ServerTransport +import io.rsocket.kotlin.transport.netty.server.NettyContextCloseable +import io.rsocket.kotlin.util.AbstractRSocket +import io.rsocket.kotlin.DefaultPayload import org.assertj.core.api.Assertions.assertThat import org.assertj.core.data.Offset import org.junit.After @@ -106,7 +107,7 @@ abstract class EndToEndTest @Test fun clientMetadataPush() { - val payload = PayloadImpl("", "md") + val payload = DefaultPayload("", "md") client.metadataPush(payload) .andThen(Completable.timer(1, TimeUnit.SECONDS)) .timeout(10, TimeUnit.SECONDS) @@ -120,7 +121,7 @@ abstract class EndToEndTest @Test fun serverMetadataPush() { - val payload = PayloadImpl("", "md") + val payload = DefaultPayload("", "md") serverHandler.sendMetadataPush(payload) .andThen(Completable.timer(1, TimeUnit.SECONDS)) .timeout(10, TimeUnit.SECONDS) @@ -230,6 +231,6 @@ abstract class EndToEndTest internal data class Data(val data: String, val metadata: String) { constructor(payload: Payload) : this(payload.dataUtf8, payload.metadataUtf8) - fun payload(): Payload = PayloadImpl(data, metadata) + fun payload(): Payload = DefaultPayload(data, metadata) } } \ No newline at end of file diff --git a/test/src/test/kotlin/io/rsocket/android/test/NettyTcpEndToEndTest.kt b/test/src/test/kotlin/io/rsocket/kotlin/test/NettyTcpEndToEndTest.kt similarity index 51% rename from test/src/test/kotlin/io/rsocket/android/test/NettyTcpEndToEndTest.kt rename to test/src/test/kotlin/io/rsocket/kotlin/test/NettyTcpEndToEndTest.kt index 26dc705c7..a9834b372 100644 --- a/test/src/test/kotlin/io/rsocket/android/test/NettyTcpEndToEndTest.kt +++ b/test/src/test/kotlin/io/rsocket/kotlin/test/NettyTcpEndToEndTest.kt @@ -1,7 +1,7 @@ -package io.rsocket.android.test +package io.rsocket.kotlin.test -import io.rsocket.android.transport.netty.client.TcpClientTransport -import io.rsocket.android.transport.netty.server.TcpServerTransport +import io.rsocket.kotlin.transport.netty.client.TcpClientTransport +import io.rsocket.kotlin.transport.netty.server.TcpServerTransport class NettyTcpEndToEndTest : EndToEndTest( diff --git a/test/src/test/kotlin/io/rsocket/android/test/NettyWebsocketEndToEndTest.kt b/test/src/test/kotlin/io/rsocket/kotlin/test/NettyWebsocketEndToEndTest.kt similarity index 63% rename from test/src/test/kotlin/io/rsocket/android/test/NettyWebsocketEndToEndTest.kt rename to test/src/test/kotlin/io/rsocket/kotlin/test/NettyWebsocketEndToEndTest.kt index ed457bf79..eb1e1f2d8 100644 --- a/test/src/test/kotlin/io/rsocket/android/test/NettyWebsocketEndToEndTest.kt +++ b/test/src/test/kotlin/io/rsocket/kotlin/test/NettyWebsocketEndToEndTest.kt @@ -1,7 +1,7 @@ -package io.rsocket.android.test +package io.rsocket.kotlin.test -import io.rsocket.android.transport.netty.client.WebsocketClientTransport -import io.rsocket.android.transport.netty.server.WebsocketServerTransport +import io.rsocket.kotlin.transport.netty.client.WebsocketClientTransport +import io.rsocket.kotlin.transport.netty.server.WebsocketServerTransport class NettyWebsocketEndToEndTest : EndToEndTest( { WebsocketClientTransport.create(it) }, diff --git a/test/src/test/kotlin/io/rsocket/android/test/OkHttpNettyEndToEndTest.kt b/test/src/test/kotlin/io/rsocket/kotlin/test/OkHttpNettyEndToEndTest.kt similarity index 82% rename from test/src/test/kotlin/io/rsocket/android/test/OkHttpNettyEndToEndTest.kt rename to test/src/test/kotlin/io/rsocket/kotlin/test/OkHttpNettyEndToEndTest.kt index e4a9bc682..33dd9c8db 100644 --- a/test/src/test/kotlin/io/rsocket/android/test/OkHttpNettyEndToEndTest.kt +++ b/test/src/test/kotlin/io/rsocket/kotlin/test/OkHttpNettyEndToEndTest.kt @@ -1,6 +1,6 @@ -package io.rsocket.android.test +package io.rsocket.kotlin.test -import io.rsocket.android.transport.netty.server.WebsocketServerTransport +import io.rsocket.kotlin.transport.netty.server.WebsocketServerTransport import io.rsocket.transport.okhttp.client.OkhttpWebsocketClientTransport import okhttp3.HttpUrl