From 381811412151d032c326fac24b175dfeeb364bea Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 30 Sep 2025 18:21:25 -0400 Subject: [PATCH 1/2] Revert "kn: merge to main (#1423)" This reverts commit abf545fcbf7af9e24685ef23f8ab004dbf990959. --- .brazil.json | 1 - .../7ced011b-d955-4559-9a21-848a19a36a4e.json | 8 - .github/actions/setup-build/action.yml | 49 ----- .github/scripts/run-container-test.py | 152 ---------------- .github/workflows/artifact-size-metrics.yml | 24 +-- .github/workflows/changelog-verification.yml | 2 +- .github/workflows/continuous-integration.yml | 168 ++---------------- .github/workflows/jreleaser.yml | 2 +- .github/workflows/kat-transform.yml | 16 +- .github/workflows/minor-version-bump.yml | 2 +- .gitignore | 2 - CONTRIBUTING.md | 22 --- .../main/kotlin/dokka-convention.gradle.kts | 2 + gradle.properties | 3 +- gradle/libs.versions.toml | 9 +- .../auth/awssigning/AuthTokenGenerator.kt | 5 + .../auth/awssigning/AuthTokenGeneratorTest.kt | 4 + .../aws-signing-crt/api/aws-signing-crt.api | 2 +- runtime/auth/aws-signing-crt/build.gradle.kts | 4 +- .../auth/awssigning/crt/CrtAwsSigner.kt | 3 +- .../crt/CrtAwsChunkedByteReadChannelTest.kt | 0 .../awssigning/crt/CrtAwsChunkedSourceTest.kt | 0 .../awssigning/crt/CrtBasicSigningTest.kt | 0 .../awssigning/crt/CrtSigningSuiteTest.kt | 6 + .../api/aws-signing-default.api | 2 +- .../auth/aws-signing-default/build.gradle.kts | 6 - .../auth/awssigning/DefaultAwsSigner.kt | 133 +++++++++++++- .../runtime/auth/awssigning/RequestMutator.kt | 19 -- .../SigV4aSignatureCalculatorTest.kt | 2 - .../auth/awssigning/DefaultAwsSignerJVM.kt | 120 ------------- .../awssigning/DefaultAwsChunkedSourceTest.kt | 0 .../auth/awssigning/DefaultAwsSignerNative.kt | 10 -- .../tests/AwsChunkedSourceTestBase.kt | 0 runtime/auth/http-auth-aws/build.gradle.kts | 2 +- .../http/auth/AwsHttpSignerTestBase.kt | 4 - .../test/AwsHttpSignerTestBaseJvm.kt} | 0 runtime/build.gradle.kts | 82 +-------- runtime/crt-util/build.gradle.kts | 12 +- .../runtime/crt/ReadChannelBodyStream.kt | 14 -- .../src/aws/smithy/kotlin/runtime/crt/Http.kt | 0 .../runtime/crt/ReadChannelBodyStream.kt | 5 + .../runtime/crt/ReadChannelBodyStreamJvm.kt | 11 -- .../smithy/kotlin/runtime/crt/SdkDefaultIO.kt | 8 +- .../kotlin/runtime/crt/SdkSourceBodyStream.kt | 0 .../aws/smithy/kotlin/runtime/crt/HttpTest.kt | 0 .../runtime/crt/ReadChannelBodyStreamTest.kt | 0 .../runtime/crt/SdkSourceBodyStreamTest.kt | 0 .../crt/ReadChannelBodyStreamNative.kt | 14 -- .../logging-crt/build.gradle.kts | 18 -- .../logging/crt/CrtLogRecordBuilder.kt | 47 ----- .../telemetry/logging/crt/CrtLogger.kt | 27 --- .../logging/crt/CrtLoggerProvider.kt | 14 -- .../logging-slf4j2/build.gradle.kts | 2 +- .../context/TelemetryContextElementJVM.kt | 1 - .../telemetry-defaults/build.gradle.kts | 6 - .../logging/DefaultLoggerProviderNative.kt | 4 +- .../eventstream/FrameDecoderTest.kt | 1 + .../eventstream/HeaderValueTest.kt | 1 - .../awsprotocol/json/AwsJsonProtocolTest.kt | 1 + .../common/test/ClockSkewInterceptorTest.kt | 22 +-- .../http-client-engine-crt/build.gradle.kts | 6 +- .../http/engine/crt/ConnectionManager.kt | 15 +- .../runtime/http/engine/crt/CrtHttpEngine.kt | 3 +- .../http/engine/crt/CrtHttpEngineConfig.kt | 0 .../runtime/http/engine/crt/RequestUtil.kt | 0 .../engine/crt/SdkStreamResponseHandler.kt | 0 .../http/engine/crt/AsyncStressTest.kt | 7 +- .../http/engine/crt/RequestConversionTest.kt | 0 .../http/engine/crt/RequestUtilTest.kt | 0 .../crt/SdkStreamResponseHandlerTest.kt | 8 +- .../http/engine/crt/SendChunkedBodyTest.kt | 10 +- .../build.gradle.kts | 9 - .../http/engine/DefaultHttpEngineNative.kt | 10 +- .../build.gradle.kts | 2 +- .../build.gradle.kts | 2 +- .../test-suite/build.gradle.kts | 1 - .../runtime/http/test/suite/Concurrency.kt | 5 +- .../runtime/http/test/suite/Connections.kt | 0 .../runtime/http/test/suite/Downloads.kt | 15 +- .../kotlin/runtime/http/test/suite/Header.kt | 0 .../runtime/http/test/suite/Redirects.kt | 0 .../kotlin/runtime/http/test/suite/Tls.kt | 0 .../kotlin/runtime/http/test/suite/Uploads.kt | 0 .../http/test/util/AbstractEngineTestJVM.kt | 1 - .../runtime/http/test/util/TestServers.kt | 1 + .../test/util/AbstractEngineTestNative.kt | 2 +- runtime/protocol/http-client/build.gradle.kts | 1 - .../RequestCompressionInterceptorTest.kt | 3 +- .../http/operation/HttpInterceptorTest.kt | 4 +- .../RequestCompressionInterceptorTestJvm.kt | 10 ++ ...RequestCompressionInterceptorTestNative.kt | 9 + runtime/protocol/http-test/build.gradle.kts | 8 - .../runtime/httptest/TestWithLocalServer.kt | 41 ++--- .../smithy/kotlin/runtime/http/HeadersTest.kt | 1 + runtime/runtime-core/api/runtime-core.api | 32 +--- runtime/runtime-core/build.gradle.kts | 25 --- .../aws/smithy/kotlin/runtime/Annotations.kt | 6 - .../runtime/compression/GzipTestUtils.kt | 13 -- .../kotlin/runtime/content/BigDecimal.kt | 74 +------- .../kotlin/runtime/content/BigInteger.kt | 63 ------- .../kotlin/runtime/content/ByteStream.kt | 10 -- .../smithy/kotlin/runtime/hashing/Crc32.kt | 4 +- .../smithy/kotlin/runtime/hashing/Crc32c.kt | 2 +- .../kotlin/runtime/io/BufferedSinkAdapter.kt | 2 +- .../runtime/io/BuffereredSourceAdapter.kt | 65 +++---- .../smithy/kotlin/runtime/io/Exceptions.kt | 3 +- .../kotlin/runtime/io/SdkByteReadChannel.kt | 1 - .../aws/smithy/kotlin/runtime/io/SdkSource.kt | 38 +--- .../runtime/io/internal/BufferOperations.kt | 81 ++++----- .../kotlin/runtime/time/TimestampFormat.kt | 6 +- .../smithy/kotlin/runtime/util/Platform.kt | 6 - .../kotlin/runtime/compression/GzipTest.kt | 41 ----- .../kotlin/runtime/content/BigIntegerTest.kt | 1 + .../kotlin/runtime/hashing/Crc32Test.kt | 7 +- .../kotlin/runtime/hashing/Crc32cTest.kt | 5 +- .../runtime/io/GzipByteReadChannelTest.kt | 1 - .../kotlin/runtime/io/GzipSdkSourceTest.kt | 1 - .../smithy/kotlin/runtime/io/GzipTestUtils.kt | 10 ++ .../kotlin/runtime/net/HostResolverTest.kt | 82 --------- .../smithy/kotlin/runtime/time/InstantTest.kt | 113 ++++++------ .../util/SystemPlatformProviderTest.kt | 62 ------- .../smithy/kotlin/runtime/AnnotationsJvm.kt | 9 - .../runtime/compression/GzipTestUtilsJvm.kt | 16 -- .../kotlin/runtime/content/BigDecimalJVM.kt | 53 ++---- .../kotlin/runtime/content/BigIntegerJVM.kt | 37 +--- .../kotlin/runtime/content/ByteStreamJVM.kt | 9 +- .../smithy/kotlin/runtime/hashing/Crc32JVM.kt | 2 +- .../smithy/kotlin/runtime/io/ExceptionsJVM.kt | 12 +- .../smithy/kotlin/runtime/io/SdkBufferJVM.kt | 1 - .../runtime/io/SdkByteReadChannelJVM.kt | 1 + .../smithy/kotlin/runtime/io/SdkSourceJVM.kt | 42 +++++ .../smithy/kotlin/runtime/time/InstantJVM.kt | 6 +- .../kotlin/runtime/io/GzipTestUtilsJVM.kt | 13 ++ .../SystemPlatformProviderLinuxX64Test.kt | 17 -- .../util/SystemDefaultProviderMingw.kt | 28 --- .../util/SystemPlatformProviderMingwTest.kt | 19 -- .../kotlin/runtime/AnnotationsNative.kt | 8 - .../runtime/compression/GzipCompressor.kt | 129 -------------- .../kotlin/runtime/compression/GzipNative.kt | 39 +--- .../compression/GzipTestUtilsNative.kt | 78 -------- .../runtime/content/BigDecimalNative.kt | 65 +++---- .../runtime/content/BigIntegerNative.kt | 59 +++--- .../kotlin/runtime/hashing/Crc32Native.kt | 18 +- .../kotlin/runtime/hashing/EcdsaNative.kt | 5 +- .../kotlin/runtime/hashing/Md5Native.kt | 16 +- .../kotlin/runtime/hashing/Sha1Native.kt | 15 +- .../kotlin/runtime/hashing/Sha256Native.kt | 8 +- .../runtime/io/BufferedSinkAdapterNative.kt | 67 ++++++- .../runtime/io/BufferedSourceAdapterNative.kt | 87 ++++++++- .../kotlin/runtime/io/ExceptionsNative.kt | 5 +- .../runtime/io/GzipByteReadChannelNative.kt | 52 +----- .../kotlin/runtime/io/GzipSdkSourceNative.kt | 41 +---- .../kotlin/runtime/io/SdkBufferNative.kt | 162 +++++++++++------ .../kotlin/runtime/io/SdkSourceNative.kt | 27 +++ .../io/internal/SdkDispatchersNative.kt | 4 +- .../runtime/net/DefaultHostResolverNative.kt | 26 --- .../kotlin/runtime/net/HostResolverNative.kt | 22 +++ .../kotlin/runtime/time/DateTimeFormats.kt | 145 --------------- .../kotlin/runtime/time/InstantNative.kt | 101 ++++------- .../kotlin/runtime/util/PlatformNative.kt | 53 ++++++ .../runtime/util/SystemDefaultProviderBase.kt | 64 ------- .../kotlin/runtime/io/GzipTestUtilsNative.kt | 12 ++ .../util/SystemDefaultProviderPosix.kt | 53 ------ .../posix/src/posixInterop/cinterop/environ.h | 12 -- .../runtime/serde/cbor/CborSerializerTest.kt | 4 +- .../runtime/client/util/AnnotationsNative.kt | 2 - settings.gradle.kts | 1 - tests/codegen/waiter-tests/build.gradle.kts | 1 - 168 files changed, 1057 insertions(+), 2591 deletions(-) delete mode 100644 .changes/7ced011b-d955-4559-9a21-848a19a36a4e.json delete mode 100644 .github/actions/setup-build/action.yml delete mode 100755 .github/scripts/run-container-test.py rename runtime/auth/aws-signing-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt (98%) rename runtime/auth/aws-signing-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedByteReadChannelTest.kt (100%) rename runtime/auth/aws-signing-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedSourceTest.kt (100%) rename runtime/auth/aws-signing-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtBasicSigningTest.kt (100%) rename runtime/auth/aws-signing-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt (64%) delete mode 100644 runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt rename runtime/auth/aws-signing-default/{common => jvm}/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsChunkedSourceTest.kt (100%) delete mode 100644 runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt rename runtime/auth/aws-signing-tests/{common => jvm}/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedSourceTestBase.kt (100%) rename runtime/auth/http-auth-aws/{jvmAndNative/test/AwsHttpSignerTestBaseJvmAndNative.kt => jvm/test/AwsHttpSignerTestBaseJvm.kt} (100%) delete mode 100644 runtime/crt-util/common/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt rename runtime/crt-util/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/crt/Http.kt (100%) rename runtime/crt-util/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt (96%) delete mode 100644 runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt rename runtime/crt-util/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt (68%) rename runtime/crt-util/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStream.kt (100%) rename runtime/crt-util/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/crt/HttpTest.kt (100%) rename runtime/crt-util/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt (100%) rename runtime/crt-util/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt (100%) delete mode 100644 runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt delete mode 100644 runtime/observability/logging-crt/build.gradle.kts delete mode 100644 runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogRecordBuilder.kt delete mode 100644 runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogger.kt delete mode 100644 runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLoggerProvider.kt rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt (92%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt (98%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngineConfig.kt (100%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtil.kt (100%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandler.kt (100%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt (94%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt (100%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt (100%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt (96%) rename runtime/protocol/http-client-engines/http-client-engine-crt/{jvmAndNative => jvm}/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt (92%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt (88%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Connections.kt (100%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt (84%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Header.kt (100%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Redirects.kt (100%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Tls.kt (100%) rename runtime/protocol/http-client-engines/test-suite/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/http/test/suite/Uploads.kt (100%) create mode 100644 runtime/protocol/http-client/jvm/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestJvm.kt create mode 100644 runtime/protocol/http-client/native/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestNative.kt rename runtime/protocol/http-test/{jvmAndNative => jvm}/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt (63%) delete mode 100644 runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/compression/GzipTestUtils.kt delete mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/compression/GzipTest.kt create mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipTestUtils.kt delete mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/net/HostResolverTest.kt delete mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderTest.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/AnnotationsJvm.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsJvm.kt create mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt create mode 100644 runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsJVM.kt delete mode 100644 runtime/runtime-core/linuxX64/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderLinuxX64Test.kt delete mode 100644 runtime/runtime-core/mingw/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderMingw.kt delete mode 100644 runtime/runtime-core/mingw/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderMingwTest.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/AnnotationsNative.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipCompressor.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsNative.kt create mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/DefaultHostResolverNative.kt create mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/HostResolverNative.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt create mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/PlatformNative.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderBase.kt create mode 100644 runtime/runtime-core/native/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsNative.kt delete mode 100644 runtime/runtime-core/posix/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderPosix.kt delete mode 100644 runtime/runtime-core/posix/src/posixInterop/cinterop/environ.h diff --git a/.brazil.json b/.brazil.json index ad60e171a6..a347a892a7 100644 --- a/.brazil.json +++ b/.brazil.json @@ -14,7 +14,6 @@ "aws.sdk.kotlin.crt:aws-crt-kotlin:0.9.*": "AwsCrtKotlin-0.9.x", "aws.sdk.kotlin.crt:aws-crt-kotlin:0.8.*": "AwsCrtKotlin-0.8.x", "com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x", - "org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.*": "KotlinxDatetimeJvm-0.x", "software.amazon.smithy:smithy-aws-traits:1.*": "Maven-software-amazon-smithy_smithy-aws-traits-1.x", "software.amazon.smithy:smithy-aws-iam-traits:1.*": "Maven-software-amazon-smithy_smithy-aws-iam-traits-1.x", diff --git a/.changes/7ced011b-d955-4559-9a21-848a19a36a4e.json b/.changes/7ced011b-d955-4559-9a21-848a19a36a4e.json deleted file mode 100644 index 1d2889856c..0000000000 --- a/.changes/7ced011b-d955-4559-9a21-848a19a36a4e.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "7ced011b-d955-4559-9a21-848a19a36a4e", - "type": "feature", - "description": "Add support for Kotlin/Native", - "issues": [ - "https://github.com/aws/aws-sdk-kotlin/issues/229" - ] -} \ No newline at end of file diff --git a/.github/actions/setup-build/action.yml b/.github/actions/setup-build/action.yml deleted file mode 100644 index b379aa10e8..0000000000 --- a/.github/actions/setup-build/action.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Setup Build -description: > - Checkout repositories and build dependencies - -runs: - using: composite - steps: - - name: Extract aws-kotlin-repo-tools version - working-directory: ./smithy-kotlin - shell: bash - run: | - export AWS_KOTLIN_REPO_TOOLS_VERSION=$(grep '^aws-kotlin-repo-tools-version' ./gradle/libs.versions.toml | sed -E 's/.*= "(.*)"/\1/') - echo "Using aws-kotlin-repo-tools version $AWS_KOTLIN_REPO_TOOLS_VERSION" - echo "aws_kotlin_repo_tools_version=$AWS_KOTLIN_REPO_TOOLS_VERSION" >> $GITHUB_ENV - - - name: Checkout aws-kotlin-repo-tools - uses: actions/checkout@v4 - with: - path: 'aws-kotlin-repo-tools' - repository: 'aws/aws-kotlin-repo-tools' - ref: ${{ env.aws_kotlin_repo_tools_version }} - sparse-checkout: | - .github - - - name: Checkout aws-crt-kotlin - uses: ./aws-kotlin-repo-tools/.github/actions/checkout-head - with: - # checkout aws-crt-kotlin as a sibling which will automatically make it an included build - path: 'aws-crt-kotlin' - repository: 'aws/aws-crt-kotlin' - submodules: 'true' - - # Cache the Kotlin/Native toolchain based on the input Kotlin version from version catalog - # see https://kotlinlang.org/docs/native-improving-compilation-time.html - - name: Cache Kotlin Native toolchain - uses: actions/cache@v4 - with: - path: | - ~/.konan - key: ${{ runner.os }}-konan-${{ hashFiles('gradle/libs.versions.toml') }} - restore-keys: | - ${{ runner.os }}-konan- - - - name: Configure JDK - uses: actions/setup-java@v3 - with: - distribution: 'corretto' - java-version: 17 - cache: 'gradle' \ No newline at end of file diff --git a/.github/scripts/run-container-test.py b/.github/scripts/run-container-test.py deleted file mode 100755 index 56d9be34d3..0000000000 --- a/.github/scripts/run-container-test.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -""" -Run precompiled Kotlin/Native test binaries in a Docker container for a specific Linux distribution and architecture. - -This requires Docker multiarch support, see https://docs.docker.com/build/building/multi-platform/ and https://github.com/multiarch/qemu-user-static -In GitHub we use a provided action for this: https://github.com/docker/setup-qemu-action - -Locally you would need to run one of: - -`docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes` - -OR - -`docker run --privileged --rm tonistiigi/binfmt --install all` -""" - -import argparse -import os -import subprocess -import shlex -import shutil - -VERBOSE = False - -DISTRO_TO_IMAGE_NAME = { - "ubuntu-22.04": "public.ecr.aws/lts/ubuntu:22.04_stable", - "al2023": "public.ecr.aws/amazonlinux/amazonlinux:2023", - "al2": "public.ecr.aws/amazonlinux/amazonlinux:2" -} - -DOCKER_PLATFORM_BY_ARCH = { - "x64": "linux/amd64", - "arm64": "linux/arm64" -} - - -def vprint(message): - global VERBOSE - if VERBOSE: - print(message) - - -def running_in_github_action(): - """ - Test if currently running in a GitHub action or running locally - :return: True if running in GH, False otherwise - """ - return "GITHUB_WORKFLOW" in os.environ - - -def shell(command, cwd=None, check=True, capture_output=False): - """ - Run a command - :param command: command to run - :param cwd: the current working directory to change to before executing the command - :param check: flag indicating if the status code should be checked. When true an exception will be - thrown if the command exits with a non-zero exit status. - :returns: the subprocess CompletedProcess output - """ - vprint(f"running `{command}`") - return subprocess.run(command, shell=True, check=check, cwd=cwd, capture_output=capture_output) - - -def oci_executable(): - """ - Attempt to find the OCI container executor used to build and run docker containers - """ - oci_exe = os.environ.get('OCI_EXE') - if oci_exe is not None: - return oci_exe - - executors = ['finch', 'podman', 'docker'] - - for exe in executors: - if shutil.which(exe) is not None: - return exe - - print("cannot find container executor") - exit(1) - - -def run_docker_test(opts): - """ - Run a docker test for a precompiled Kotlin/Native binary - - :param opts: the parsed command line options - """ - platform = DOCKER_PLATFORM_BY_ARCH[opts.arch] - oci_exe = oci_executable() - - test_bin_dir = os.path.abspath(opts.test_bin_dir) - image_name = DISTRO_TO_IMAGE_NAME[opts.distro] - path_to_exe = f'./linux{opts.arch.capitalize()}/debugTest/test.kexe' - - cmd = [ - oci_exe, - 'run', - '--rm', - f'-v{test_bin_dir}:/test', - ] - if not opts.no_system_certs: - cmd.append(f'-v/etc/ssl:/etc/ssl') - - cmd.extend( - [ - '-w/test', - '-e DEBIAN_FRONTEND=noninteractive', - '--platform', - platform, - image_name, - path_to_exe, - ] - ) - - cmd = shlex.join(cmd) - print(cmd) - shell(cmd) - - -def create_cli(): - parser = argparse.ArgumentParser( - prog="run-container-test", - description="Run cross platform test binaries in a container", - formatter_class=argparse.ArgumentDefaultsHelpFormatter - ) - - parser.add_argument("-v", "--verbose", help="enable verbose output", action="store_true") - - parser.add_argument("--distro", required=True, choices=DISTRO_TO_IMAGE_NAME.keys(), help="the distribution name to run the task on") - parser.add_argument("--arch", required=True, choices=DOCKER_PLATFORM_BY_ARCH.keys(), help="the architecture to use") - parser.add_argument("--test-bin-dir", required=True, help="the path to the test binary directory root") - parser.add_argument("--no-system-certs", action='store_true', help="disable mounting system certificates into the container") - - return parser - - -def main(): - cli = create_cli() - opts = cli.parse_args() - if opts.verbose: - global VERBOSE - VERBOSE = True - - run_docker_test(opts) - - -if __name__ == '__main__': - main() diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index f57dde00bd..03571e1d56 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -44,43 +44,33 @@ jobs: steps: - name: Checkout Sources uses: actions/checkout@v4 + - name: Configure JDK + uses: actions/setup-java@v3 with: - path: smithy-kotlin - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - + distribution: 'corretto' + java-version: 17 + cache: 'gradle' - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} aws-region: us-west-2 - - name: Configure Gradle uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - with: - working-directory: smithy-kotlin - - name: Generate Artifact Size Metrics - run: ./gradlew -Paws.kotlin.native=false artifactSizeMetrics - working-directory: smithy-kotlin - + run: ./gradlew artifactSizeMetrics - name: Analyze Artifact Size Metrics run: ./gradlew analyzeArtifactSizeMetrics - working-directory: smithy-kotlin - name: Show Results uses: aws/aws-kotlin-repo-tools/.github/actions/artifact-size-metrics/show-results@main - with: - working-directory: smithy-kotlin - name: Evaluate if: ${{ !contains(github.event.pull_request.labels.*.name, 'acknowledge-artifact-size-increase') }} - working-directory: smithy-kotlin run: | cd build/reports/metrics cat has-significant-change.txt | grep false || { echo An artifact increased in size by more than allowed or a new artifact was created. echo If this is expected please add the 'acknowledge-artifact-size-increase' label to this pull request. exit 1 - } + } \ No newline at end of file diff --git a/.github/workflows/changelog-verification.yml b/.github/workflows/changelog-verification.yml index ca9aaa3be7..f3e6a70f47 100644 --- a/.github/workflows/changelog-verification.yml +++ b/.github/workflows/changelog-verification.yml @@ -22,4 +22,4 @@ jobs: aws-region: us-west-2 - name: Verify changelog - uses: aws/aws-kotlin-repo-tools/.github/actions/changelog-verification@main + uses: aws/aws-kotlin-repo-tools/.github/actions/changelog-verification@main \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 316c41e764..88cebb4559 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -40,12 +40,6 @@ jobs: run: printf 'timestamp=%(%s)T\n' >> "$GITHUB_OUTPUT" - name: Checkout sources uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - name: Configure JDK uses: actions/setup-java@v3 with: @@ -61,15 +55,10 @@ jobs: uses: aws/aws-kotlin-repo-tools/.github/actions/setup-kat@main - name: Configure Gradle uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - with: - working-directory: 'smithy-kotlin' - - - name: Build and Test on JVM - working-directory: ./smithy-kotlin + - name: Test shell: bash run: | - ./gradlew -Paws.kotlin.native=false -Ptest.java.version=${{ matrix.java-version }} jvmTest --stacktrace - + ./gradlew -Ptest.java.version=${{ matrix.java-version }} jvmTest --stacktrace - name: Calculate duration id: end if: always() @@ -90,102 +79,6 @@ jobs: WorkflowSucceeded:${{ job.status == 'success' && '1' || '0' }}:Count WorkflowDuration:${{ steps.end.outputs.duration }}:Seconds - # macos-14 build and test for targets: jvm, macoArm64, iosSimulatorArm64, watchosSimulatorArm65, tvosSimulatorArm64 - # macos-13 build and test for targets: jvm, macoX64, iosX64, tvosX64, watchosX64 - macos: - strategy: - fail-fast: false - matrix: - os: [macos-14, macos-13] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - - name: Build and Test on Apple platforms - working-directory: ./smithy-kotlin - shell: bash - run: | - # FIXME K2. Re-enable warnings as errors after this warning is removed: https://youtrack.jetbrains.com/issue/KT-68532 - # echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties - ./gradlew apiCheck - ./gradlew build - - - name: Save Test Reports - if: failure() - uses: actions/upload-artifact@v4 - with: - name: test-reports-${{ matrix.os }} - path: '**/build/reports' - - # build and test for targets: jvm, linuxX64 - # cross compile for: linuxX64, linuxArm64 - linux: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Configure Gradle - uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - with: - working-directory: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - - name: Configure CRT Docker Images - run: | - ./aws-crt-kotlin/docker-images/build-all.sh - - - name: Build and Test on Linux with Cross-Compile - working-directory: ./smithy-kotlin - shell: bash - run: | - # FIXME K2. Re-enable warnings as errors after this warning is removed: https://youtrack.jetbrains.com/issue/KT-68532 - # echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties - ./gradlew apiCheck - ./gradlew build - - - name: Save Test Reports - if: failure() - uses: actions/upload-artifact@v4 - with: - name: test-reports-${{ matrix.os }} - path: '**/build/reports' - - # windows JVM - windows: - runs-on: windows-2022 - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - - name: Build and Test on Windows JVM - working-directory: ./smithy-kotlin - run: | - ./gradlew apiCheck - ./gradlew -P"aws.kotlin.native=false" build - - - name: Save Test Reports - if: failure() - uses: actions/upload-artifact@v4 - with: - name: test-reports-windows - path: '**/build/reports' - all-platforms: runs-on: ${{ matrix.os }} strategy: @@ -199,12 +92,6 @@ jobs: run: echo "timestamp=$(date +%s)" >> "$GITHUB_OUTPUT" - name: Checkout sources uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - name: Configure JDK uses: actions/setup-java@v3 with: @@ -220,18 +107,12 @@ jobs: uses: aws/aws-kotlin-repo-tools/.github/actions/setup-kat@main - name: Configure Gradle uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - with: - working-directory: 'smithy-kotlin' - - name: Test - working-directory: ./smithy-kotlin shell: bash run: | - # FIXME K2. Re-enable warnings as errors after this warning is removed: https://youtrack.jetbrains.com/issue/KT-68532 - # echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties - ./gradlew -Paws.kotlin.native=false apiCheck - ./gradlew -Paws.kotlin.native=false test jvmTest - + echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties + ./gradlew apiCheck + ./gradlew test jvmTest - name: Calculate duration id: end if: always() @@ -252,7 +133,6 @@ jobs: metrics: | WorkflowSucceeded:${{ job.status == 'success' && '1' || '0' }}:Count WorkflowDuration:${{ steps.end.outputs.duration }}:Seconds - - name: Save Test Reports if: failure() uses: actions/upload-artifact@v4 @@ -268,12 +148,6 @@ jobs: run: printf 'timestamp=%(%s)T\n' >> "$GITHUB_OUTPUT" - name: Checkout sources uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - name: Configure JDK uses: actions/setup-java@v3 with: @@ -289,15 +163,11 @@ jobs: uses: aws/aws-kotlin-repo-tools/.github/actions/setup-kat@main - name: Configure Gradle uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - with: - working-directory: 'smithy-kotlin' - - name: Test - working-directory: ./smithy-kotlin shell: bash run: | - ./gradlew -Paws.kotlin.native=false publishToMavenLocal - ./gradlew -Paws.kotlin.native=false testAllProtocols + ./gradlew publishToMavenLocal + ./gradlew testAllProtocols - name: Calculate duration id: end if: always() @@ -328,10 +198,6 @@ jobs: uses: actions/checkout@v4 with: path: 'smithy-kotlin' - - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - name: Checkout tools uses: actions/checkout@v4 with: @@ -340,7 +206,6 @@ jobs: ref: '0.2.3' sparse-checkout: | .github - - name: Checkout aws-sdk-kotlin uses: ./aws-kotlin-repo-tools/.github/actions/checkout-head with: @@ -358,18 +223,21 @@ jobs: uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main with: working-directory: ./smithy-kotlin - - name: Configure Gradle - aws-sdk-kotlin uses: aws/aws-kotlin-repo-tools/.github/actions/configure-gradle@main with: working-directory: ./aws-sdk-kotlin - + - name: Configure JDK + uses: actions/setup-java@v3 + with: + distribution: 'corretto' + java-version: 17 + cache: 'gradle' - name: Build and Test aws-sdk-kotlin downstream - working-directory: ./smithy-kotlin run: | # TODO - JVM only cd $GITHUB_WORKSPACE/smithy-kotlin - ./gradlew --parallel -Paws.kotlin.native=false publishToMavenLocal + ./gradlew --parallel publishToMavenLocal SMITHY_KOTLIN_RUNTIME_VERSION=$(grep sdkVersion= gradle.properties | cut -d = -f 2) SMITHY_KOTLIN_CODEGEN_VERSION=$(grep codegenVersion= gradle.properties | cut -d = -f 2) cd $GITHUB_WORKSPACE/aws-sdk-kotlin @@ -380,9 +248,9 @@ jobs: # smithy-kotlin should be sed -i "s/smithy-kotlin-runtime-version = .*$/smithy-kotlin-runtime-version = \"$SMITHY_KOTLIN_RUNTIME_VERSION\"/" gradle/libs.versions.toml sed -i "s/smithy-kotlin-codegen-version = .*$/smithy-kotlin-codegen-version = \"$SMITHY_KOTLIN_CODEGEN_VERSION\"/" gradle/libs.versions.toml - ./gradlew --parallel -Paws.kotlin.native=false publishToMavenLocal - ./gradlew -Paws.kotlin.native=false test jvmTest - ./gradlew -Paws.kotlin.native=false testAllProtocols + ./gradlew --parallel publishToMavenLocal + ./gradlew test jvmTest + ./gradlew testAllProtocols - name: Calculate duration id: end if: always() @@ -401,4 +269,4 @@ jobs: Branch=${{ github.base_ref || github.ref_name }} metrics: | WorkflowSucceeded:${{ job.status == 'success' && '1' || '0' }}:Count - WorkflowDuration:${{ steps.end.outputs.duration }}:Seconds + WorkflowDuration:${{ steps.end.outputs.duration }}:Seconds \ No newline at end of file diff --git a/.github/workflows/jreleaser.yml b/.github/workflows/jreleaser.yml index 7c3abfb367..93c5d7df6c 100644 --- a/.github/workflows/jreleaser.yml +++ b/.github/workflows/jreleaser.yml @@ -10,4 +10,4 @@ jobs: runs-on: ubuntu-latest steps: - name: JReleaser check - uses: aws/aws-kotlin-repo-tools/.github/actions/jreleaser@main + uses: awslabs/aws-kotlin-repo-tools/.github/actions/jreleaser@main diff --git a/.github/workflows/kat-transform.yml b/.github/workflows/kat-transform.yml index 6f2dfae691..93fb0c8b34 100644 --- a/.github/workflows/kat-transform.yml +++ b/.github/workflows/kat-transform.yml @@ -29,9 +29,6 @@ jobs: with: path: 'smithy-kotlin' - - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build - - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: @@ -46,6 +43,13 @@ jobs: - name: Setup kat uses: aws/aws-kotlin-repo-tools/.github/actions/setup-kat@main + - name: Configure JDK + uses: actions/setup-java@v3 + with: + distribution: 'corretto' + java-version: 17 + cache: 'gradle' + - name: Build working-directory: ./smithy-kotlin shell: bash @@ -54,8 +58,8 @@ jobs: ls -lsa kat bump-version # Bump from `vNext-SNAPSHOT` to `vNext`. kat transform only works on non-SNAPSHOT versions kat bump-version --property codegenVersion - ./gradlew -Paws.kotlin.native=false build - ./gradlew -Paws.kotlin.native=false publishAllPublicationsToTestLocalRepository + ./gradlew build + ./gradlew publishAllPublicationsToTestLocalRepository - name: Transform working-directory: ./smithy-kotlin @@ -71,4 +75,4 @@ jobs: exit 1 fi - echo "Transformation succeeded!" + echo "Transformation succeeded!" \ No newline at end of file diff --git a/.github/workflows/minor-version-bump.yml b/.github/workflows/minor-version-bump.yml index b48d0b8907..f7a36f8153 100644 --- a/.github/workflows/minor-version-bump.yml +++ b/.github/workflows/minor-version-bump.yml @@ -8,4 +8,4 @@ jobs: runs-on: ubuntu-latest steps: - name: Minor version bump check - uses: aws/aws-kotlin-repo-tools/.github/actions/minor-version-bump@main + uses: awslabs/aws-kotlin-repo-tools/.github/actions/minor-version-bump@main diff --git a/.gitignore b/.gitignore index 824314f693..99ff20f122 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,3 @@ gradle-app.setting # MacOS .DS_Store - -*.cinteropLibraries.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abd6e50a04..b57263573d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -234,25 +234,3 @@ If you discover a potential security issue in this project we ask that you notif See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. - -## Kotlin/Native -Support for Kotlin/Native is in active development. The following sections cover how to effectively test your work. - -### Linux/Unix - -#### Testing Different Linux Distros and Architectures - -1. Build the test executable(s) for the architecture(s) you want to test. - -```sh -# build specific arch -./gradlew linuxX64TestBinaries -``` - -2. Use the `run-container-test.py` helper script to execute tests locally. Change the directory as needed. - -```sh -OCI_EXE=docker python3 .github/scripts/run-container-test.py --distro al2 --arch x64 --test-bin-dir ./runtime/runtime-core/build/bin -``` - -See the usage/help for different distributions provided: `python3 .github/scripts/run-container.py -h` diff --git a/buildSrc/src/main/kotlin/dokka-convention.gradle.kts b/buildSrc/src/main/kotlin/dokka-convention.gradle.kts index 7169bb7e87..06f6593bdb 100644 --- a/buildSrc/src/main/kotlin/dokka-convention.gradle.kts +++ b/buildSrc/src/main/kotlin/dokka-convention.gradle.kts @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import kotlin.text.set + plugins { id("org.jetbrains.dokka") } diff --git a/gradle.properties b/gradle.properties index f7dfebfe89..7e3a40f60b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,6 @@ kotlin.code.style=official kotlin.incremental.js=true kotlin.incremental.multiplatform=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableCInteropCommonization=true kotlin.native.ignoreDisabledTargets=true # atomicfu @@ -21,4 +20,4 @@ codegenVersion=0.35.11-SNAPSHOT # FIXME Remove after Dokka 2.0 Gradle plugin is stable org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled -org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d327ec720b..9891cf19aa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,11 +13,9 @@ okio-version = "3.16.0" otel-version = "1.52.0" slf4j-version = "2.0.17" slf4j-v1x-version = "1.7.36" -crt-kotlin-version = "0.11.5" +crt-kotlin-version = "0.10.3" micrometer-version = "1.15.2" binary-compatibility-validator-version = "0.18.1" -kotlin-multiplatform-bignum-version = "0.3.10" -kotlinx-datetime-version = "0.6.1" # codegen smithy-version = "1.61.0" @@ -66,7 +64,6 @@ slf4j-api-v1x = { module = "org.slf4j:slf4j-api", version.ref = "slf4j-v1x-versi slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j-version" } crt-kotlin = { module = "aws.sdk.kotlin.crt:aws-crt-kotlin", version.ref = "crt-kotlin-version" } micrometer-core = { module = "io.micrometer:micrometer-core", version.ref = "micrometer-version" } -kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime-version" } smithy-codegen-core = { module = "software.amazon.smithy:smithy-codegen-core", version.ref = "smithy-version" } smithy-cli = { module = "software.amazon.smithy:smithy-cli", version.ref = "smithy-version" } @@ -97,18 +94,14 @@ docker-transport-zerodep = { module = "com.github.docker-java:docker-java-transp ktor-http-cio = { module = "io.ktor:ktor-http-cio", version.ref = "ktor-version" } ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor-version" } ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor-version" } -ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor-version" } ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor-version" } ktor-server-jetty-jakarta = { module = "io.ktor:ktor-server-jetty-jakarta", version.ref = "ktor-version" } ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor-version" } ktor-network-tls-certificates = { module = "io.ktor:ktor-network-tls-certificates", version.ref = "ktor-version" } -ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor-version" } kaml = { module = "com.charleskorn.kaml:kaml", version.ref = "kaml-version" } jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup-version" } -kotlin-multiplatform-bignum = { module = "com.ionspin.kotlin:bignum", version.ref = "kotlin-multiplatform-bignum-version" } - [plugins] dokka = { id = "org.jetbrains.dokka", version.ref = "dokka-version"} kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" } diff --git a/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt index a78bd0143a..bc14e6689b 100644 --- a/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt +++ b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt @@ -3,9 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* SPDX-License-Identifier: Apache-2.0 +*/ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider +import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningConfig.Companion.invoke import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.request.HttpRequest diff --git a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt index 50d38aeb5c..880f4f1d91 100644 --- a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt +++ b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt @@ -3,6 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* SPDX-License-Identifier: Apache-2.0 +*/ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials diff --git a/runtime/auth/aws-signing-crt/api/aws-signing-crt.api b/runtime/auth/aws-signing-crt/api/aws-signing-crt.api index 39dc9fdf45..ed1934cac9 100644 --- a/runtime/auth/aws-signing-crt/api/aws-signing-crt.api +++ b/runtime/auth/aws-signing-crt/api/aws-signing-crt.api @@ -1,4 +1,4 @@ -public final class aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner : aws/sdk/kotlin/crt/WithCrt, aws/smithy/kotlin/runtime/auth/awssigning/AwsSigner { +public final class aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner : aws/smithy/kotlin/runtime/auth/awssigning/AwsSigner { public static final field INSTANCE Laws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner; public fun sign (Laws/smithy/kotlin/runtime/http/request/HttpRequest;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun signChunk ([B[BLaws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/runtime/auth/aws-signing-crt/build.gradle.kts b/runtime/auth/aws-signing-crt/build.gradle.kts index 5dddb3f45f..4c67282762 100644 --- a/runtime/auth/aws-signing-crt/build.gradle.kts +++ b/runtime/auth/aws-signing-crt/build.gradle.kts @@ -8,14 +8,14 @@ extra["moduleName"] = "aws.smithy.kotlin.runtime.auth.awssigning.crt" kotlin { sourceSets { - jvmAndNativeMain { + jvmMain { dependencies { api(project(":runtime:auth:aws-signing-common")) implementation(project(":runtime:crt-util")) } } - jvmAndNativeTest { + jvmTest { dependencies { implementation(project(":runtime:auth:aws-signing-tests")) } diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt b/runtime/auth/aws-signing-crt/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt similarity index 98% rename from runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt rename to runtime/auth/aws-signing-crt/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt index ac039d519b..c0069c1aca 100644 --- a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt +++ b/runtime/auth/aws-signing-crt/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.crt -import aws.sdk.kotlin.crt.WithCrt import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.crt.toSignableCrtRequest @@ -25,7 +24,7 @@ import aws.sdk.kotlin.crt.http.Headers as CrtHeaders private const val S3_EXPRESS_HEADER_NAME = "X-Amz-S3session-Token" -public object CrtAwsSigner : AwsSigner, WithCrt() { +public object CrtAwsSigner : AwsSigner { override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { val isUnsigned = config.hashSpecification is HashSpecification.UnsignedPayload val isAwsChunked = request.headers.contains("Content-Encoding", "aws-chunked") diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedByteReadChannelTest.kt b/runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedByteReadChannelTest.kt similarity index 100% rename from runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedByteReadChannelTest.kt rename to runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedByteReadChannelTest.kt diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedSourceTest.kt b/runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedSourceTest.kt similarity index 100% rename from runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedSourceTest.kt rename to runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsChunkedSourceTest.kt diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtBasicSigningTest.kt b/runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtBasicSigningTest.kt similarity index 100% rename from runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtBasicSigningTest.kt rename to runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtBasicSigningTest.kt diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt b/runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt similarity index 64% rename from runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt rename to runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt index f312bf09a0..1b7ed92a07 100644 --- a/runtime/auth/aws-signing-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt +++ b/runtime/auth/aws-signing-crt/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtSigningSuiteTest.kt @@ -9,4 +9,10 @@ import aws.smithy.kotlin.runtime.auth.awssigning.tests.SigningSuiteTestBase class CrtSigningSuiteTest : SigningSuiteTestBase() { override val signer: AwsSigner = CrtAwsSigner + + override val disabledTests = super.disabledTests + setOf( + // FIXME - Signature mismatch possibly related to https://github.com/awslabs/aws-crt-java/pull/419. Needs + // investigation. + "get-utf8", + ) } diff --git a/runtime/auth/aws-signing-default/api/aws-signing-default.api b/runtime/auth/aws-signing-default/api/aws-signing-default.api index 15ca42c07e..e00e6d829a 100644 --- a/runtime/auth/aws-signing-default/api/aws-signing-default.api +++ b/runtime/auth/aws-signing-default/api/aws-signing-default.api @@ -5,7 +5,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerBui public final fun setTelemetryProvider (Laws/smithy/kotlin/runtime/telemetry/TelemetryProvider;)V } -public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVMKt { +public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerKt { public static final fun DefaultAwsSigner (Lkotlin/jvm/functions/Function1;)Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; public static final fun getDefaultAwsSigner ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; } diff --git a/runtime/auth/aws-signing-default/build.gradle.kts b/runtime/auth/aws-signing-default/build.gradle.kts index 71781c66c7..22e20d39fd 100644 --- a/runtime/auth/aws-signing-default/build.gradle.kts +++ b/runtime/auth/aws-signing-default/build.gradle.kts @@ -25,11 +25,5 @@ kotlin { all { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } - - nativeMain { - dependencies { - implementation(project(":runtime:auth:aws-signing-crt")) - } - } } } diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt index df5d2076b9..85896349b1 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt @@ -4,5 +4,136 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning +import aws.smithy.kotlin.runtime.ExperimentalApi +import aws.smithy.kotlin.runtime.http.Headers +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider +import aws.smithy.kotlin.runtime.telemetry.logging.logger +import aws.smithy.kotlin.runtime.time.TimestampFormat +import kotlin.coroutines.coroutineContext + /** The default implementation of [AwsSigner] */ -public expect val DefaultAwsSigner: AwsSigner +public val DefaultAwsSigner: AwsSigner = DefaultAwsSignerImpl() + +/** Creates a customized instance of [AwsSigner] */ +@Suppress("ktlint:standard:function-naming") +public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = + DefaultAwsSignerBuilder().apply(block).build() + +/** A builder class for creating instances of [AwsSigner] using the default implementation */ +public class DefaultAwsSignerBuilder { + public var telemetryProvider: TelemetryProvider? = null + + public fun build(): AwsSigner = DefaultAwsSignerImpl( + telemetryProvider = telemetryProvider, + ) +} + +private val AwsSigningAlgorithm.signatureCalculator + get() = when (this) { + AwsSigningAlgorithm.SIGV4 -> SignatureCalculator.SigV4 + AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> SignatureCalculator.SigV4a + } + +@OptIn(ExperimentalApi::class) +internal class DefaultAwsSignerImpl( + private val canonicalizer: Canonicalizer = Canonicalizer.Default, + private val requestMutator: RequestMutator = RequestMutator.Default, + private val telemetryProvider: TelemetryProvider? = null, +) : AwsSigner { + override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val canonical = canonicalizer.canonicalRequest(request, config) + if (config.logRequest) { + logger.trace { "Canonical request:\n${canonical.requestString}" } + } + + val signatureCalculator = config.algorithm.signatureCalculator + + val stringToSign = signatureCalculator.stringToSign(canonical.requestString, config) + logger.trace { "String to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated signature: $signature" } + + val signedRequest = requestMutator.appendAuth(config, canonical, signature) + + return AwsSigningResult(signedRequest, signature.encodeToByteArray()) + } + + override suspend fun signChunk( + chunkBody: ByteArray, + prevSignature: ByteArray, + config: AwsSigningConfig, + ): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val signatureCalculator = config.algorithm.signatureCalculator + + val stringToSign = signatureCalculator.chunkStringToSign(chunkBody, prevSignature, config) + logger.trace { "Chunk string to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated chunk signature: $signature" } + + return AwsSigningResult(Unit, signature.encodeToByteArray()) + } + + override suspend fun signChunkTrailer( + trailingHeaders: Headers, + prevSignature: ByteArray, + config: AwsSigningConfig, + ): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val signatureCalculator = config.algorithm.signatureCalculator + + // FIXME - can we share canonicalization code more than we are..., also this reduce is inefficient. + // canonicalize the headers + val trailingHeadersBytes = trailingHeaders.entries().sortedBy { e -> e.key.lowercase() } + .map { e -> + buildString { + append(e.key.lowercase()) + append(":") + append(e.value.joinToString(",") { v -> v.trim() }) + append("\n") + }.encodeToByteArray() + }.reduce { acc, bytes -> acc + bytes } + + val stringToSign = signatureCalculator.chunkTrailerStringToSign(trailingHeadersBytes, prevSignature, config) + logger.trace { "Chunk trailer string to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated chunk signature: $signature" } + + return AwsSigningResult(Unit, signature.encodeToByteArray()) + } +} + +/** + * Formats a credential scope consisting of a signing date, region (SigV4 only), service, and a signature type + */ +internal val AwsSigningConfig.credentialScope: String + get() = run { + val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) + return when (algorithm) { + AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" + AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request" + } + } + +/** + * Formats the value for a credential header/parameter + */ +internal fun credentialValue(config: AwsSigningConfig): String = + "${config.credentials.accessKeyId}/${config.credentialScope}" diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt index ee67e7833b..0c1882cd54 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.time.TimestampFormat /** * An object that can mutate requests to include signing attributes. @@ -56,21 +55,3 @@ internal class DefaultRequestMutator : RequestMutator { return canonical.request.build() } } - -/** - * Formats a credential scope consisting of a signing date, region (SigV4 only), service, and a signature type - */ -internal val AwsSigningConfig.credentialScope: String - get() { - val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) - return when (algorithm) { - AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" - AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request" - } - } - -/** - * Formats the value for a credential header/parameter - */ -internal fun credentialValue(config: AwsSigningConfig): String = - "${config.credentials.accessKeyId}/${config.credentialScope}" diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/SigV4aSignatureCalculatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/SigV4aSignatureCalculatorTest.kt index 81421fcce7..c4c4abe953 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/SigV4aSignatureCalculatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/SigV4aSignatureCalculatorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.util.PlatformProvider @@ -69,7 +68,6 @@ private val TESTS = listOf( * Tests for [SigV4aSignatureCalculator]. Currently only tests forming the string-to-sign. */ class SigV4aSignatureCalculatorTest { - @IgnoreNative // FIXME test resources are not loadable on iOS: https://youtrack.jetbrains.com/issue/KT-49981/ @Test fun testStringToSign() = TESTS.forEach { testId -> runTest { diff --git a/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt b/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt deleted file mode 100644 index ea1f4723d6..0000000000 --- a/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.auth.awssigning - -import aws.smithy.kotlin.runtime.ExperimentalApi -import aws.smithy.kotlin.runtime.http.Headers -import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider -import aws.smithy.kotlin.runtime.telemetry.logging.logger -import kotlin.coroutines.coroutineContext - -/** The default implementation of [AwsSigner] */ -public actual val DefaultAwsSigner: AwsSigner = DefaultAwsSignerImpl() - -/** Creates a customized instance of [AwsSigner] */ -@Suppress("ktlint:standard:function-naming") -public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = - DefaultAwsSignerBuilder().apply(block).build() - -/** A builder class for creating instances of [AwsSigner] using the default implementation */ -public class DefaultAwsSignerBuilder { - public var telemetryProvider: TelemetryProvider? = null - - public fun build(): AwsSigner = DefaultAwsSignerImpl( - telemetryProvider = telemetryProvider, - ) -} - -private val AwsSigningAlgorithm.signatureCalculator - get() = when (this) { - AwsSigningAlgorithm.SIGV4 -> SignatureCalculator.SigV4 - AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> SignatureCalculator.SigV4a - } - -@OptIn(ExperimentalApi::class) -internal class DefaultAwsSignerImpl( - private val canonicalizer: Canonicalizer = Canonicalizer.Default, - private val requestMutator: RequestMutator = RequestMutator.Default, - private val telemetryProvider: TelemetryProvider? = null, -) : AwsSigner { - override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val canonical = canonicalizer.canonicalRequest(request, config) - if (config.logRequest) { - logger.trace { "Canonical request:\n${canonical.requestString}" } - } - - val signatureCalculator = config.algorithm.signatureCalculator - - val stringToSign = signatureCalculator.stringToSign(canonical.requestString, config) - logger.trace { "String to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated signature: $signature" } - - val signedRequest = requestMutator.appendAuth(config, canonical, signature) - - return AwsSigningResult(signedRequest, signature.encodeToByteArray()) - } - - override suspend fun signChunk( - chunkBody: ByteArray, - prevSignature: ByteArray, - config: AwsSigningConfig, - ): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val signatureCalculator = config.algorithm.signatureCalculator - - val stringToSign = signatureCalculator.chunkStringToSign(chunkBody, prevSignature, config) - logger.trace { "Chunk string to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated chunk signature: $signature" } - - return AwsSigningResult(Unit, signature.encodeToByteArray()) - } - - override suspend fun signChunkTrailer( - trailingHeaders: Headers, - prevSignature: ByteArray, - config: AwsSigningConfig, - ): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val signatureCalculator = config.algorithm.signatureCalculator - - // FIXME - can we share canonicalization code more than we are..., also this reduce is inefficient. - // canonicalize the headers - val trailingHeadersBytes = trailingHeaders.entries().sortedBy { e -> e.key.lowercase() } - .map { e -> - buildString { - append(e.key.lowercase()) - append(":") - append(e.value.joinToString(",") { v -> v.trim() }) - append("\n") - }.encodeToByteArray() - }.reduce { acc, bytes -> acc + bytes } - - val stringToSign = signatureCalculator.chunkTrailerStringToSign(trailingHeadersBytes, prevSignature, config) - logger.trace { "Chunk trailer string to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated chunk signature: $signature" } - - return AwsSigningResult(Unit, signature.encodeToByteArray()) - } -} diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsChunkedSourceTest.kt b/runtime/auth/aws-signing-default/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsChunkedSourceTest.kt similarity index 100% rename from runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsChunkedSourceTest.kt rename to runtime/auth/aws-signing-default/jvm/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsChunkedSourceTest.kt diff --git a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt deleted file mode 100644 index 0b9335ec1d..0000000000 --- a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.auth.awssigning - -import aws.smithy.kotlin.runtime.auth.awssigning.crt.CrtAwsSigner - -/** The default implementation of [AwsSigner] */ -public actual val DefaultAwsSigner: AwsSigner = CrtAwsSigner diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedSourceTestBase.kt b/runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedSourceTestBase.kt similarity index 100% rename from runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedSourceTestBase.kt rename to runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedSourceTestBase.kt diff --git a/runtime/auth/http-auth-aws/build.gradle.kts b/runtime/auth/http-auth-aws/build.gradle.kts index e6c8236526..dfcc0c7da3 100644 --- a/runtime/auth/http-auth-aws/build.gradle.kts +++ b/runtime/auth/http-auth-aws/build.gradle.kts @@ -26,7 +26,7 @@ kotlin { } } - jvmAndNativeTest { + jvmTest { dependencies { implementation(project(":runtime:auth:aws-signing-crt")) } diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 0daa2b31fe..75be7cbbf2 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http.auth -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigner @@ -127,7 +126,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignAwsChunkedStreamNonReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -141,7 +139,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignAwsChunkedStreamReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -155,7 +152,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignOneShotStream(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false) diff --git a/runtime/auth/http-auth-aws/jvmAndNative/test/AwsHttpSignerTestBaseJvmAndNative.kt b/runtime/auth/http-auth-aws/jvm/test/AwsHttpSignerTestBaseJvm.kt similarity index 100% rename from runtime/auth/http-auth-aws/jvmAndNative/test/AwsHttpSignerTestBaseJvmAndNative.kt rename to runtime/auth/http-auth-aws/jvm/test/AwsHttpSignerTestBaseJvm.kt diff --git a/runtime/build.gradle.kts b/runtime/build.gradle.kts index 158856a208..9da74f02a8 100644 --- a/runtime/build.gradle.kts +++ b/runtime/build.gradle.kts @@ -3,12 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ import aws.sdk.kotlin.gradle.dsl.configurePublishing -import aws.sdk.kotlin.gradle.kmp.configureKmpTargets -import aws.sdk.kotlin.gradle.kmp.kotlin -import aws.sdk.kotlin.gradle.kmp.needsKmpConfigured +import aws.sdk.kotlin.gradle.kmp.* +import org.gradle.kotlin.dsl.apply import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest plugins { `dokka-convention` @@ -18,9 +15,6 @@ plugins { val sdkVersion: String by project -// Apply KMP configuration from build plugin -configureKmpTargets() - // capture locally - scope issue with custom KMP plugin val libraries = libs @@ -53,25 +47,19 @@ subprojects { } } - findByName("jvmTest")?.run { + named("jvmTest") { dependencies { implementation(libraries.kotlinx.coroutines.debug) implementation(libraries.kotest.assertions.core.jvm) } } - - all { - languageSettings.optIn("kotlin.RequiresOptIn") - } } + } - targets.withType().all { - listOf("${name}Main", "${name}Test").forEach { - this@kotlin.sourceSets.findByName(it)?.apply { - languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") - } - } - } + kotlin.sourceSets.all { + // Allow subprojects to use internal APIs + // See https://kotlinlang.org/docs/reference/opt-in-requirements.html#opting-in-to-using-api + listOf("kotlin.RequiresOptIn").forEach { languageSettings.optIn(it) } } tasks.withType { @@ -85,64 +73,10 @@ subprojects { tasks.withType { compilerOptions { freeCompilerArgs.add("-Xexpect-actual-classes") - - // FIXME When building LinuxX64 on AL2 the linker inclues a bunch of dynamic links to unavailable versions - // of zlib. The below workaround forces the linker to statically link zlib but it's a hack because the - // linker will still dynamically link zlib (although the executable will no longer fail at runtime due to - // link resolution failures). The correct solution for this is probably containerized builds similar to - // what we do in aws-crt-kotlin. The following compiler args were helpful in debugging this issue: - // * Enable verbose compiler output : -verbose - // * Increase verbosity during the compiler's linker phase : -Xverbose-phases=Linker - // * Enable verbose linker output from gold : -linker-option --verbose - if (target.contains("linux", ignoreCase = true)) { - freeCompilerArgs.addAll( - listOf( - "-linker-option", // The subsequent argument is for the linker - "-Bstatic", // Enable static linking for the libraries that follow - "-linker-option", // The subsequent argument is for the linker - "-lz", // Link zlib statically (because of -Bstatic above) - "-linker-option", // The subsequent argument is for the linker - "-Bdynamic", // Restore dynamic linking, which is the default - ), - ) - } - } - } - - /* - FIXME iOS simulator tests fail on GitHub CI with "Bad or unknown session": - > Task :runtime:runtime-core:linkDebugTestIosSimulatorArm64 - java.lang.IllegalStateException: You have standalone simulator tests run mode disabled and tests have failed to run. - - The problem can be that you have not booted the required device or have configured the task to a different simulator. Please check the task output and its device configuration. - > Task :runtime:runtime-core:iosSimulatorArm64Test - If you are sure that your setup is correct, please file an issue: https://kotl.in/issue - An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405): - Process spawn via launchd failed because device is not booted. - Underlying error (domain=com.apple.SimLaunchHostService.RequestError, code=3): - Bad or unknown session: com.apple.CoreSimulator.SimDevice.C120BDE1-C108-4759-842F-7D82B4E71E8C - */ - tasks.withType { - enabled = false - } - - tasks.withType { - if (this is Test) { - useJUnitPlatform() - } - - testLogging { - events("passed", "skipped", "failed") - showStandardStreams = true - showStackTraces = true - showExceptions = true - exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL } } } -// configureIosSimulatorTasks() - val excludeFromDocumentation = listOf( ":runtime:testing", ":runtime:smithy-test", diff --git a/runtime/crt-util/build.gradle.kts b/runtime/crt-util/build.gradle.kts index f14fb5c439..ddc57d11a9 100644 --- a/runtime/crt-util/build.gradle.kts +++ b/runtime/crt-util/build.gradle.kts @@ -11,22 +11,14 @@ extra["moduleName"] = "aws.smithy.kotlin.runtime.crt" kotlin { sourceSets { - commonMain { - dependencies { - api(project(":runtime:runtime-core")) - api(libs.crt.kotlin) - } - } - - jvmAndNativeMain { + jvmMain { dependencies { api(project(":runtime:runtime-core")) api(libs.crt.kotlin) api(project(":runtime:protocol:http")) } } - - jvmAndNativeTest { + jvmTest { dependencies { implementation(libs.kotlinx.coroutines.test) } diff --git a/runtime/crt-util/common/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt b/runtime/crt-util/common/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt deleted file mode 100644 index e08f9f0d1f..0000000000 --- a/runtime/crt-util/common/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.crt - -import aws.sdk.kotlin.crt.io.MutableBuffer -import aws.smithy.kotlin.runtime.io.SdkBuffer - -/** - * write as much of [outgoing] to [dest] as possible - */ -internal expect fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int diff --git a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/Http.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/Http.kt similarity index 100% rename from runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/Http.kt rename to runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/Http.kt diff --git a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt similarity index 96% rename from runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt rename to runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt index 040ba85459..4a3e609808 100644 --- a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt +++ b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStream.kt @@ -18,6 +18,11 @@ import kotlin.time.Duration.Companion.milliseconds private val POLLING_DELAY = 100.milliseconds +/** + * write as much of [outgoing] to [dest] as possible + */ +internal fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer) = outgoing.read(dest.buffer) + /** * Implement's [HttpRequestBodyStream] which proxies an SDK request body channel [SdkByteReadChannel] */ diff --git a/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt deleted file mode 100644 index 7703ef5895..0000000000 --- a/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.crt - -import aws.sdk.kotlin.crt.io.MutableBuffer -import aws.smithy.kotlin.runtime.io.SdkBuffer - -internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer) = outgoing.read(dest.buffer) diff --git a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt similarity index 68% rename from runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt rename to runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt index 269dcdb5ee..cdcceaf596 100644 --- a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt +++ b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/SdkDefaultIO.kt @@ -14,39 +14,33 @@ private const val DEFAULT_EVENT_LOOP_THREAD_COUNT: Int = 1 /** * Default (CRT) IO used by the SDK when not configured manually/directly */ -@Deprecated("This API is no longer used by the SDK and will be removed in version 1.6.x") @InternalApi public object SdkDefaultIO { /** * The default event loop group to run IO on */ - @Deprecated("This API is no longer used by the SDK and will be removed in version 1.6.x") public val EventLoop: EventLoopGroup by lazy { + // TODO - can we register shutdown in appropriate runtimes (e.g. jvm: addShutdown, native: atexit(), etc) when/if these lazy block(s) run? EventLoopGroup(DEFAULT_EVENT_LOOP_THREAD_COUNT) } /** * The default host resolver to resolve DNS queries with */ - @Deprecated("This API is no longer used by the SDK and will be removed in version 1.6.x") public val HostResolver: HostResolver by lazy { - @Suppress("DEPRECATION") HostResolver(EventLoop) } /** * The default client bootstrap */ - @Deprecated("This API is no longer used by the SDK and will be removed in version 1.6.x") public val ClientBootstrap: ClientBootstrap by lazy { - @Suppress("DEPRECATION") ClientBootstrap(EventLoop, HostResolver) } /** * The default TLS context */ - @Deprecated("This API is no longer used by the SDK and will be removed in version 1.6.x") public val TlsContext: TlsContext by lazy { TlsContext(TlsContextOptions.defaultClient()) } diff --git a/runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStream.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStream.kt similarity index 100% rename from runtime/crt-util/jvmAndNative/src/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStream.kt rename to runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStream.kt diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/HttpTest.kt b/runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/HttpTest.kt similarity index 100% rename from runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/HttpTest.kt rename to runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/HttpTest.kt diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt b/runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt similarity index 100% rename from runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt rename to runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt b/runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt similarity index 100% rename from runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt rename to runtime/crt-util/jvm/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt diff --git a/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt b/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt deleted file mode 100644 index e27805bbf6..0000000000 --- a/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.crt - -import aws.sdk.kotlin.crt.io.MutableBuffer -import aws.smithy.kotlin.runtime.io.SdkBuffer - -internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int { - val length = minOf(outgoing.size, dest.writeRemaining.toLong()) - if (length <= 0) return 0 - return dest.write(outgoing.readByteArray(length)) -} diff --git a/runtime/observability/logging-crt/build.gradle.kts b/runtime/observability/logging-crt/build.gradle.kts deleted file mode 100644 index b59d7b81d8..0000000000 --- a/runtime/observability/logging-crt/build.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -description = "Logging provider based on CRT" -extra["displayName"] = "Smithy :: Kotlin :: Observability :: CRT" -extra["moduleName"] = "aws.smithy.kotlin.runtime.telemetry.logging.crt" - -kotlin { - sourceSets { - nativeMain { - dependencies { - api(project(":runtime:observability:telemetry-api")) - api(libs.crt.kotlin) - } - } - } -} diff --git a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogRecordBuilder.kt b/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogRecordBuilder.kt deleted file mode 100644 index 67415ed59b..0000000000 --- a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogRecordBuilder.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.telemetry.logging.crt - -import aws.smithy.kotlin.runtime.telemetry.logging.LogLevel -import aws.smithy.kotlin.runtime.telemetry.logging.LogRecordBuilder -import aws.smithy.kotlin.runtime.telemetry.logging.MessageSupplier - -public class CrtLogRecordBuilder( - private val delegate: CrtLogger, - private val level: LogLevel, -) : LogRecordBuilder { - private var cause: Throwable? = null - private var msg: (() -> String)? = null - - override fun setCause(ex: Throwable) { - cause = ex - } - - override fun setMessage(message: String) { - msg = { message } - } - - override fun setMessage(message: MessageSupplier) { - msg = message - } - - // CRT logger does not support setting key-value pairs - override fun setKeyValuePair(key: String, value: Any) { } - - override fun emit() { - val message = requireNotNull(msg) { "no message provided to LogRecordBuilder" } - - val logMethod = when (level) { - LogLevel.Trace -> delegate::trace - LogLevel.Debug -> delegate::debug - LogLevel.Info -> delegate::info - LogLevel.Warning -> delegate::warn - LogLevel.Error -> delegate::error - } - - logMethod(cause, message) - } -} diff --git a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogger.kt b/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogger.kt deleted file mode 100644 index 1a88eb068b..0000000000 --- a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLogger.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.telemetry.logging.crt - -import aws.sdk.kotlin.crt.WithCrt -import aws.sdk.kotlin.crt.log -import aws.smithy.kotlin.runtime.telemetry.logging.LogLevel -import aws.smithy.kotlin.runtime.telemetry.logging.LogRecordBuilder -import aws.smithy.kotlin.runtime.telemetry.logging.Logger -import aws.smithy.kotlin.runtime.telemetry.logging.MessageSupplier -import aws.sdk.kotlin.crt.Config as CrtConfig -import aws.sdk.kotlin.crt.LogLevel as CrtLogLevel - -public class CrtLogger(public val name: String, public val config: CrtConfig) : - WithCrt(), - Logger { - override fun trace(t: Throwable?, msg: MessageSupplier): Unit = log(CrtLogLevel.Trace, msg()) - override fun debug(t: Throwable?, msg: MessageSupplier): Unit = log(CrtLogLevel.Debug, msg()) - override fun info(t: Throwable?, msg: MessageSupplier): Unit = log(CrtLogLevel.Info, msg()) - override fun warn(t: Throwable?, msg: MessageSupplier): Unit = log(CrtLogLevel.Warn, msg()) - override fun error(t: Throwable?, msg: MessageSupplier): Unit = log(CrtLogLevel.Error, msg()) - override fun isEnabledFor(level: LogLevel): Boolean = config.logLevel.ordinal >= level.ordinal - override fun atLevel(level: LogLevel): LogRecordBuilder = CrtLogRecordBuilder(this, level) -} diff --git a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLoggerProvider.kt b/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLoggerProvider.kt deleted file mode 100644 index 31259e9804..0000000000 --- a/runtime/observability/logging-crt/native/src/aws/smithy/kotlin/runtime/telemetry/logging/crt/CrtLoggerProvider.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.telemetry.logging.crt - -import aws.smithy.kotlin.runtime.telemetry.logging.* -import aws.sdk.kotlin.crt.Config as CrtConfig - -public class CrtLoggerProvider : LoggerProvider { - override fun getOrCreateLogger(name: String): Logger = CrtLogger(name, CrtConfig()) - public fun getOrCreateLogger(name: String, config: CrtConfig): Logger = CrtLogger(name, config) -} diff --git a/runtime/observability/logging-slf4j2/build.gradle.kts b/runtime/observability/logging-slf4j2/build.gradle.kts index 1f2bd3ad69..2fd9ad4c70 100644 --- a/runtime/observability/logging-slf4j2/build.gradle.kts +++ b/runtime/observability/logging-slf4j2/build.gradle.kts @@ -4,7 +4,7 @@ */ description = "Logging provider based on SLF4J" extra["displayName"] = "Smithy :: Kotlin :: Observability :: SLF4J binding" -extra["moduleName"] = "aws.smithy.kotlin.runtime.telemetry.slf4j" +extra["moduleName"] = "aws.smithy.kotlin.runtime.telemetry" kotlin { sourceSets { diff --git a/runtime/observability/telemetry-api/jvm/src/aws/smithy/kotlin/runtime/telemetry/context/TelemetryContextElementJVM.kt b/runtime/observability/telemetry-api/jvm/src/aws/smithy/kotlin/runtime/telemetry/context/TelemetryContextElementJVM.kt index e8548ad31c..d6680f0d69 100644 --- a/runtime/observability/telemetry-api/jvm/src/aws/smithy/kotlin/runtime/telemetry/context/TelemetryContextElementJVM.kt +++ b/runtime/observability/telemetry-api/jvm/src/aws/smithy/kotlin/runtime/telemetry/context/TelemetryContextElementJVM.kt @@ -10,7 +10,6 @@ import kotlinx.coroutines.ThreadContextElement import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.coroutines.CoroutineContext -// FIXME Move to jvmAndNative when https://github.com/Kotlin/kotlinx.coroutines/issues/3326 is implemented @InternalApi public actual class TelemetryContextElement public actual constructor( public actual val context: Context, diff --git a/runtime/observability/telemetry-defaults/build.gradle.kts b/runtime/observability/telemetry-defaults/build.gradle.kts index 357b11d80e..e77655c91d 100644 --- a/runtime/observability/telemetry-defaults/build.gradle.kts +++ b/runtime/observability/telemetry-defaults/build.gradle.kts @@ -24,12 +24,6 @@ kotlin { } } - nativeMain { - dependencies { - implementation(project(":runtime:observability:logging-crt")) - } - } - all { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } diff --git a/runtime/observability/telemetry-defaults/native/src/aws/smithy/kotlin/runtime/telemetry/logging/DefaultLoggerProviderNative.kt b/runtime/observability/telemetry-defaults/native/src/aws/smithy/kotlin/runtime/telemetry/logging/DefaultLoggerProviderNative.kt index 506d10869d..1d8bec0441 100644 --- a/runtime/observability/telemetry-defaults/native/src/aws/smithy/kotlin/runtime/telemetry/logging/DefaultLoggerProviderNative.kt +++ b/runtime/observability/telemetry-defaults/native/src/aws/smithy/kotlin/runtime/telemetry/logging/DefaultLoggerProviderNative.kt @@ -5,6 +5,4 @@ package aws.smithy.kotlin.runtime.telemetry.logging -import aws.smithy.kotlin.runtime.telemetry.logging.crt.CrtLoggerProvider - -internal actual val DefaultLoggerProvider: LoggerProvider = CrtLoggerProvider() +internal actual val DefaultLoggerProvider: LoggerProvider = TODO("Not yet implemented") diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt index 4e35cb58dc..dd118def5a 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt @@ -14,6 +14,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class FrameDecoderTest { + @Test fun testFrameStreamSingleMessage() = runTest { val encoded = validMessageWithAllHeaders() diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt index 16602572ea..12895d367f 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt @@ -14,7 +14,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFails class HeaderValueTest { - @Test fun testExpectAs() { assertEquals(true, HeaderValue.Bool(true).expectBool()) diff --git a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt index 344ce79e0d..172d831283 100644 --- a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt +++ b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt @@ -19,6 +19,7 @@ import kotlin.test.Test import kotlin.test.assertEquals class AwsJsonProtocolTest { + @Test fun testSetJsonProtocolHeaders() = runTest { val op = SdkHttpOperation.build { diff --git a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt index 71afea0700..930b8ee646 100644 --- a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt +++ b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt @@ -33,8 +33,8 @@ private val NOT_SKEWED_RESPONSE_CODE_DESCRIPTION = "RequestThrottled" class ClockSkewInterceptorTest { @Test fun testNotSkewed() { - val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") assertEquals(clientTime, serverTime) assertFalse(clientTime.isSkewed(serverTime, NOT_SKEWED_RESPONSE_CODE_DESCRIPTION)) } @@ -42,24 +42,24 @@ class ClockSkewInterceptorTest { @Test fun testSkewedByResponseCode() { // clocks are exactly the same, but service returned skew error - val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(0.days, clientTime.until(serverTime)) } @Test fun testSkewedByTime() { - val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Sat, 7 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Wed, 7 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(1.days, clientTime.until(serverTime)) } @Test fun testNegativeSkewedByTime() { - val clientTime = Instant.fromRfc5322("Sat, 7 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Wed, 7 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(-1.days, clientTime.until(serverTime)) } @@ -68,8 +68,8 @@ class ClockSkewInterceptorTest { fun testSkewThreshold() { val minute = 20 var clientTime = - Instant.fromRfc5322("Fri, 6 Oct 2023 16:${minute - CLOCK_SKEW_THRESHOLD.inWholeMinutes}:50 -0400") - val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:$minute:50 -0400") + Instant.fromRfc5322("Wed, 6 Oct 2023 16:${minute - CLOCK_SKEW_THRESHOLD.inWholeMinutes}:50 -0400") + val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:$minute:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(CLOCK_SKEW_THRESHOLD, clientTime.until(serverTime)) @@ -128,7 +128,7 @@ class ClockSkewInterceptorTest { @Test fun testClockSkewApplied() = runTest { testRoundTrip( - serverTimeString = "Thu, 14 Sep 2023 16:20:50 -0400", // Big skew + serverTimeString = "Wed, 14 Sep 2023 16:20:50 -0400", // Big skew clientTimeString = "20231006T131604Z", httpStatusCode = HttpStatusCode.Forbidden, expectException = false, diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/build.gradle.kts b/runtime/protocol/http-client-engines/http-client-engine-crt/build.gradle.kts index b3a3f5507a..d2f411578f 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/build.gradle.kts +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/build.gradle.kts @@ -11,18 +11,18 @@ apply(plugin = "org.jetbrains.kotlinx.atomicfu") kotlin { sourceSets { - jvmAndNativeMain { + jvmMain { dependencies { api(project(":runtime:runtime-core")) api(project(":runtime:protocol:http-client")) implementation(project(":runtime:crt-util")) implementation(project(":runtime:observability:telemetry-api")) + implementation(libs.kotlinx.coroutines.core) - api(libs.crt.kotlin) } } - jvmAndNativeTest { + jvmTest { dependencies { implementation(project(":runtime:testing")) implementation(project(":runtime:protocol:http-test")) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt similarity index 92% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt index 6009d41576..79d7bc46a9 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/ConnectionManager.kt @@ -5,11 +5,11 @@ package aws.smithy.kotlin.runtime.http.engine.crt import aws.sdk.kotlin.crt.http.* -import aws.sdk.kotlin.crt.io.ClientBootstrap import aws.sdk.kotlin.crt.io.SocketOptions import aws.sdk.kotlin.crt.io.TlsContext import aws.sdk.kotlin.crt.io.TlsContextOptionsBuilder import aws.sdk.kotlin.crt.io.Uri +import aws.smithy.kotlin.runtime.crt.SdkDefaultIO import aws.smithy.kotlin.runtime.http.HttpErrorCode import aws.smithy.kotlin.runtime.http.HttpException import aws.smithy.kotlin.runtime.http.engine.ProxyConfig @@ -43,11 +43,8 @@ internal class ConnectionManager( .build() .let(::CrtTlsContext) - private val manageClientBootstrap = config.clientBootstrap == null - private val clientBootstrap = config.clientBootstrap ?: ClientBootstrap() - private val options = HttpClientConnectionManagerOptionsBuilder().apply { - clientBootstrap = this@ConnectionManager.clientBootstrap + clientBootstrap = config.clientBootstrap ?: SdkDefaultIO.ClientBootstrap tlsContext = crtTlsContext manualWindowManagement = true socketOptions = SocketOptions( @@ -62,7 +59,7 @@ internal class ConnectionManager( private val connManagers = mutableMapOf() private val mutex = Mutex() - suspend fun acquire(request: HttpRequest): HttpClientConnection { + public suspend fun acquire(request: HttpRequest): HttpClientConnection { val proxyConfig = config.proxySelector.select(request.url) val manager = getManagerForUri(request.uri, proxyConfig) @@ -95,7 +92,6 @@ internal class ConnectionManager( throw httpEx } } - private suspend fun getManagerForUri(uri: Uri, proxyConfig: ProxyConfig): HttpClientConnectionManager = mutex.withLock { connManagers.getOrPut(uri.authority) { val connOpts = options.apply { @@ -117,12 +113,9 @@ internal class ConnectionManager( HttpClientConnectionManager(connOpts) } } - override fun close() { connManagers.forEach { entry -> entry.value.close() } crtTlsContext.close() - - if (manageClientBootstrap) clientBootstrap.close() } private inner class LeasedConnection(private val delegate: HttpClientConnection) : HttpClientConnection by delegate { @@ -138,7 +131,7 @@ internal class ConnectionManager( } private fun toCrtTlsVersion(sdkTlsVersion: SdkTlsVersion?): CrtTlsVersion = when (sdkTlsVersion) { - null -> CrtTlsVersion.SYS_DEFAULT + null -> aws.sdk.kotlin.crt.io.TlsVersion.SYS_DEFAULT TlsVersion.TLS_1_0 -> CrtTlsVersion.TLSv1 TlsVersion.TLS_1_1 -> CrtTlsVersion.TLS_V1_1 TlsVersion.TLS_1_2 -> CrtTlsVersion.TLS_V1_2 diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt similarity index 98% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt index de0e3b5457..40a38a9a90 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt @@ -15,10 +15,9 @@ import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import aws.smithy.kotlin.runtime.operation.ExecutionContext import aws.smithy.kotlin.runtime.telemetry.logging.logger import aws.smithy.kotlin.runtime.time.Instant -import kotlinx.coroutines.job +import kotlinx.coroutines.* import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit -import kotlinx.coroutines.withContext internal const val DEFAULT_WINDOW_SIZE_BYTES: Int = 16 * 1024 internal const val CHUNK_BUFFER_SIZE: Long = 64 * 1024 diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngineConfig.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngineConfig.kt similarity index 100% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngineConfig.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngineConfig.kt diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtil.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtil.kt similarity index 100% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtil.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtil.kt diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandler.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandler.kt similarity index 100% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandler.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/src/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandler.kt diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt similarity index 94% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index e509808ec1..7ad57fa1a0 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.complete @@ -14,6 +13,7 @@ import aws.smithy.kotlin.runtime.http.request.url import aws.smithy.kotlin.runtime.httptest.TestWithLocalServer import aws.smithy.kotlin.runtime.net.Host import aws.smithy.kotlin.runtime.net.Scheme +import aws.smithy.kotlin.runtime.testing.IgnoreWindows import io.ktor.server.cio.* import io.ktor.server.engine.* import io.ktor.server.response.* @@ -26,6 +26,7 @@ import kotlin.test.Test import kotlin.time.Duration.Companion.seconds class AsyncStressTest : TestWithLocalServer() { + override val server = embeddedServer(CIO, serverPort) { routing { get("/largeResponse") { @@ -35,9 +36,9 @@ class AsyncStressTest : TestWithLocalServer() { call.respondText(text.repeat(respSize / text.length)) } } - }.start() + } - @IgnoreNative // FIXME TlsContext needs to initialize CRT. Segmentation fault. + @IgnoreWindows("FIXME - times out after upgrade to kotlinx.coroutines 1.6.0") @Test fun testStreamNotConsumed() = runBlocking { // test that filling the stream window and not consuming the body stream still cleans up resources diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt similarity index 100% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt similarity index 100% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestUtilTest.kt diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt similarity index 96% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index 6c09f0dd02..9bbc35c4cd 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt -import aws.sdk.kotlin.crt.CRT import aws.sdk.kotlin.crt.http.* import aws.sdk.kotlin.crt.io.byteArrayBuffer import aws.smithy.kotlin.runtime.http.HttpBody @@ -22,17 +21,15 @@ import kotlinx.coroutines.yield import kotlin.test.* class SdkStreamResponseHandlerTest { + private class MockHttpStream(override val responseStatusCode: Int) : HttpStream { var closed: Boolean = false override fun activate() {} - override suspend fun writeChunk(chunkData: ByteArray, isFinalChunk: Boolean) { - TODO("Not yet implemented") - } - override fun close() { closed = true } override fun incrementWindow(size: Int) {} + override fun writeChunk(chunkData: ByteArray, isFinalChunk: Boolean) {} } private class MockHttpClientConnection : HttpClientConnection { @@ -155,7 +152,6 @@ class SdkStreamResponseHandlerTest { @Test fun testStreamError() = runTest { - CRT.initRuntime() // CRT needs to be initialized for human-readable error codes val handler = SdkStreamResponseHandler(mockConn, coroutineContext) val stream = MockHttpStream(200) val data = "foo bar" diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt similarity index 92% rename from runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt rename to runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt index 88366c41f0..a7637b6753 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvm/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt @@ -22,7 +22,7 @@ class SendChunkedBodyTest { closed = true } override fun incrementWindow(size: Int) {} - override suspend fun writeChunk(chunkData: ByteArray, isFinalChunk: Boolean) { + override fun writeChunk(chunkData: ByteArray, isFinalChunk: Boolean) { numChunksWritten += 1 } } @@ -33,7 +33,7 @@ class SendChunkedBodyTest { val chunkedBytes = """ 100;chunk-signature=${"0".repeat(64)}\r\n${"0".repeat(256)}\r\n\r\n - """.trimIndent().encodeToByteArray() + """.trimIndent().toByteArray() val source = chunkedBytes.source() @@ -52,7 +52,7 @@ class SendChunkedBodyTest { val chunkedBytes = """ ${chunkSize.toString(16)};chunk-signature=${"0".repeat(64)}\r\n${"0".repeat(chunkSize)}\r\n\r\n - """.trimIndent().encodeToByteArray() + """.trimIndent().toByteArray() val source = chunkedBytes.source() @@ -71,7 +71,7 @@ class SendChunkedBodyTest { val chunkedBytes = """ 100;chunk-signature=${"0".repeat(64)}\r\n${"0".repeat(256)}\r\n\r\n - """.trimIndent().encodeToByteArray() + """.trimIndent().toByteArray() val channel = SdkByteReadChannel(chunkedBytes) @@ -91,7 +91,7 @@ class SendChunkedBodyTest { val chunkedBytes = """ ${chunkSize.toString(16)};chunk-signature=${"0".repeat(64)}\r\n${"0".repeat(chunkSize)}\r\n\r\n - """.trimIndent().encodeToByteArray() + """.trimIndent().toByteArray() val channel = SdkByteReadChannel(chunkedBytes) diff --git a/runtime/protocol/http-client-engines/http-client-engine-default/build.gradle.kts b/runtime/protocol/http-client-engines/http-client-engine-default/build.gradle.kts index 321be4f532..d2381c39f0 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-default/build.gradle.kts +++ b/runtime/protocol/http-client-engines/http-client-engine-default/build.gradle.kts @@ -16,28 +16,19 @@ kotlin { implementation(project(":runtime:runtime-core")) } } - jvmMain { dependencies { // okhttp works on both JVM and Android implementation(project(":runtime:protocol:http-client-engines:http-client-engine-okhttp")) } } - jvmTest { dependencies { implementation(project(":runtime:protocol:http-client-engines:http-client-engine-crt")) } } - all { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } - - nativeMain { - dependencies { - implementation(project(":runtime:protocol:http-client-engines:http-client-engine-crt")) - } - } } } diff --git a/runtime/protocol/http-client-engines/http-client-engine-default/native/src/aws/smithy/kotlin/runtime/http/engine/DefaultHttpEngineNative.kt b/runtime/protocol/http-client-engines/http-client-engine-default/native/src/aws/smithy/kotlin/runtime/http/engine/DefaultHttpEngineNative.kt index 7f74397245..d9d060337f 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-default/native/src/aws/smithy/kotlin/runtime/http/engine/DefaultHttpEngineNative.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-default/native/src/aws/smithy/kotlin/runtime/http/engine/DefaultHttpEngineNative.kt @@ -5,11 +5,5 @@ package aws.smithy.kotlin.runtime.http.engine -import aws.smithy.kotlin.runtime.http.engine.crt.CrtHttpEngine - -internal actual fun newDefaultHttpEngine( - block: (HttpClientEngineConfig.Builder.() -> Unit)?, -): CloseableHttpClientEngine = when (block) { - null -> CrtHttpEngine() - else -> CrtHttpEngine(block) -} +internal actual fun newDefaultHttpEngine(block: (HttpClientEngineConfig.Builder.() -> Unit)?): CloseableHttpClientEngine = + TODO("Not yet implemented") diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp/build.gradle.kts b/runtime/protocol/http-client-engines/http-client-engine-okhttp/build.gradle.kts index 0e12749c09..3e5d139381 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp/build.gradle.kts +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp/build.gradle.kts @@ -9,7 +9,7 @@ extra["moduleName"] = "aws.smithy.kotlin.runtime.http.engine.okhttp" kotlin { sourceSets { - jvmMain { + commonMain { dependencies { implementation(project(":runtime:runtime-core")) api(project(":runtime:protocol:http-client")) diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp4/build.gradle.kts b/runtime/protocol/http-client-engines/http-client-engine-okhttp4/build.gradle.kts index f6b3f12668..26145b4065 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp4/build.gradle.kts +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp4/build.gradle.kts @@ -9,7 +9,7 @@ extra["moduleName"] = "aws.smithy.kotlin.runtime.http.engine.okhttp4" kotlin { sourceSets { - jvmMain { + commonMain { dependencies { api(project(":runtime:protocol:http-client")) implementation(project(":runtime:protocol:http-client-engines:http-client-engine-okhttp")) diff --git a/runtime/protocol/http-client-engines/test-suite/build.gradle.kts b/runtime/protocol/http-client-engines/test-suite/build.gradle.kts index e9c3e6555d..d2487c2722 100644 --- a/runtime/protocol/http-client-engines/test-suite/build.gradle.kts +++ b/runtime/protocol/http-client-engines/test-suite/build.gradle.kts @@ -39,7 +39,6 @@ kotlin { jvmAndNativeMain { dependencies { - implementation(libs.ktor.server.core) implementation(libs.kotlinx.coroutines.test) } } diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt similarity index 88% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt index b3b482fa20..fad3e7fec9 100644 --- a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt +++ b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Concurrency.kt @@ -8,7 +8,6 @@ package aws.smithy.kotlin.runtime.http.test.suite import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* -import io.ktor.utils.io.writeFully import kotlinx.coroutines.delay import kotlin.time.Duration.Companion.milliseconds @@ -25,10 +24,10 @@ internal fun Application.concurrentTests() { route("slow") { get { val chunk = ByteArray(256) { it.toByte() } - call.respondBytesWriter { + call.respondOutputStream { repeat(10) { delay(200.milliseconds) - writeFully(chunk) + write(chunk) } } } diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Connections.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Connections.kt similarity index 100% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Connections.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Connections.kt diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt similarity index 84% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt index 7cd8ba93e6..dd495edf24 100644 --- a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt +++ b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Downloads.kt @@ -6,9 +6,6 @@ package aws.smithy.kotlin.runtime.http.test.suite import aws.smithy.kotlin.runtime.hashing.sha256 -import aws.smithy.kotlin.runtime.io.GzipSdkSource -import aws.smithy.kotlin.runtime.io.readToByteArray -import aws.smithy.kotlin.runtime.io.source import aws.smithy.kotlin.runtime.text.encoding.encodeToHex import io.ktor.http.* import io.ktor.server.application.* @@ -16,6 +13,8 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.utils.io.* import kotlinx.coroutines.delay +import java.io.ByteArrayOutputStream +import java.util.zip.GZIPOutputStream import kotlin.random.Random internal const val DOWNLOAD_SIZE = 16L * 1024 * 1024 // 16MB @@ -56,7 +55,15 @@ internal fun Application.downloadTests() { get("/gzipped") { val uncompressed = ByteArray(1024) { it.toByte() } - val compressed = GzipSdkSource(uncompressed.source()).readToByteArray() + val compressed = ByteArrayOutputStream().use { baStream -> + GZIPOutputStream(baStream).use { gzStream -> + gzStream.write(uncompressed) + gzStream.flush() + } + baStream.flush() + baStream.toByteArray() + } + call.response.header("Content-Encoding", "gzip") call.respondBytes(compressed) } diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Header.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Header.kt similarity index 100% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Header.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Header.kt diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Redirects.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Redirects.kt similarity index 100% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Redirects.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Redirects.kt diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Tls.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Tls.kt similarity index 100% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Tls.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Tls.kt diff --git a/runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Uploads.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Uploads.kt similarity index 100% rename from runtime/protocol/http-client-engines/test-suite/jvmAndNative/src/aws/smithy/kotlin/runtime/http/test/suite/Uploads.kt rename to runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/suite/Uploads.kt diff --git a/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestJVM.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestJVM.kt index 6f0d9182d1..fa091c1f03 100644 --- a/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestJVM.kt +++ b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestJVM.kt @@ -11,7 +11,6 @@ import aws.smithy.kotlin.runtime.http.engine.okhttp4.OkHttp4Engine import aws.smithy.kotlin.runtime.net.url.Url internal actual fun engineFactories(): List = - // FIXME Move DefaultHttpEngine and CrtHttpEngine to `jvmAndNative` listOf( TestEngineFactory("DefaultHttpEngine", ::DefaultHttpEngine), TestEngineFactory("CrtHttpEngine") { CrtHttpEngine(it) }, diff --git a/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/TestServers.kt b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/TestServers.kt index 24c001d5b2..1bc9d6e9ea 100644 --- a/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/TestServers.kt +++ b/runtime/protocol/http-client-engines/test-suite/jvm/src/aws/smithy/kotlin/runtime/http/test/util/TestServers.kt @@ -12,6 +12,7 @@ import aws.smithy.kotlin.runtime.http.test.suite.tlsTests import aws.smithy.kotlin.runtime.http.test.suite.uploadTests import io.ktor.server.application.* import io.ktor.server.engine.* +import io.ktor.server.jetty.* import io.ktor.server.jetty.jakarta.Jetty import io.ktor.server.jetty.jakarta.JettyApplicationEngineBase import redirectTests diff --git a/runtime/protocol/http-client-engines/test-suite/native/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestNative.kt b/runtime/protocol/http-client-engines/test-suite/native/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestNative.kt index 05f82f63d0..bfb3ff18f4 100644 --- a/runtime/protocol/http-client-engines/test-suite/native/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestNative.kt +++ b/runtime/protocol/http-client-engines/test-suite/native/src/aws/smithy/kotlin/runtime/http/test/util/AbstractEngineTestNative.kt @@ -7,7 +7,7 @@ package aws.smithy.kotlin.runtime.http.test.util import aws.smithy.kotlin.runtime.net.url.Url -// FIXME Move CRT and Default engine tests to `jvmAndNative` +// FIXME add engines to test internal actual fun engineFactories(): List = listOf() diff --git a/runtime/protocol/http-client/build.gradle.kts b/runtime/protocol/http-client/build.gradle.kts index b485f29393..d55e5ffe41 100644 --- a/runtime/protocol/http-client/build.gradle.kts +++ b/runtime/protocol/http-client/build.gradle.kts @@ -27,7 +27,6 @@ kotlin { commonTest { dependencies { implementation(libs.kotlinx.coroutines.test) - implementation(project(":runtime:runtime-core")) implementation(project(":runtime:protocol:http-test")) } } diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt index 11163c4a61..55641129d9 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt @@ -8,7 +8,6 @@ package aws.smithy.kotlin.runtime.http.interceptors import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.compression.CompressionAlgorithm import aws.smithy.kotlin.runtime.compression.Gzip -import aws.smithy.kotlin.runtime.compression.decompressGzipBytes import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext import aws.smithy.kotlin.runtime.http.operation.newTestOperation @@ -23,6 +22,8 @@ import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertFailsWith +internal expect fun decompressGzipBytes(bytes: ByteArray): ByteArray + class RequestCompressionInterceptorTest { private val client = SdkHttpClient(TestEngine()) diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt index 5d36840bcf..b03f099ccb 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt @@ -259,9 +259,7 @@ class HttpInterceptorTest { op.roundTrip(client, Unit) } - // FIXME Investigate why the exception `ex` and its cause are duplicated on JVM. - // On JVM, `ex.cause` has the suppressed exceptions. On Native, `ex` has the suppressed exceptions and it has no cause. - val cause = assertNotNull(ex.cause ?: ex) + val cause = assertNotNull(ex.cause) assertEquals(1, cause.suppressedExceptions.size) assertIs(cause.suppressedExceptions.last()) } diff --git a/runtime/protocol/http-client/jvm/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestJvm.kt b/runtime/protocol/http-client/jvm/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestJvm.kt new file mode 100644 index 0000000000..a30c707658 --- /dev/null +++ b/runtime/protocol/http-client/jvm/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestJvm.kt @@ -0,0 +1,10 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.http.interceptors + +import java.util.zip.GZIPInputStream + +internal actual fun decompressGzipBytes(bytes: ByteArray): ByteArray = + GZIPInputStream(bytes.inputStream()).use { it.readBytes() } diff --git a/runtime/protocol/http-client/native/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestNative.kt b/runtime/protocol/http-client/native/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestNative.kt new file mode 100644 index 0000000000..74cbd525c2 --- /dev/null +++ b/runtime/protocol/http-client/native/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTestNative.kt @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.http.interceptors + +internal actual fun decompressGzipBytes(bytes: ByteArray): ByteArray { + TODO("Not yet implemented") +} diff --git a/runtime/protocol/http-test/build.gradle.kts b/runtime/protocol/http-test/build.gradle.kts index e966832924..a2077a979c 100644 --- a/runtime/protocol/http-test/build.gradle.kts +++ b/runtime/protocol/http-test/build.gradle.kts @@ -28,14 +28,6 @@ kotlin { } } - jvmAndNativeMain { - dependencies { - api(libs.ktor.server.cio) - implementation(libs.ktor.client.core) - implementation(libs.ktor.server.core) - } - } - all { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } diff --git a/runtime/protocol/http-test/jvmAndNative/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt b/runtime/protocol/http-test/jvm/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt similarity index 63% rename from runtime/protocol/http-test/jvmAndNative/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt rename to runtime/protocol/http-test/jvm/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt index ed76448c10..3ffc1a868c 100644 --- a/runtime/protocol/http-test/jvmAndNative/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt +++ b/runtime/protocol/http-test/jvm/src/aws/smithy/kotlin/runtime/httptest/TestWithLocalServer.kt @@ -5,14 +5,11 @@ package aws.smithy.kotlin.runtime.httptest -import io.ktor.network.selector.* -import io.ktor.network.sockets.* -import io.ktor.server.application.* import io.ktor.server.engine.* -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout +import java.net.* +import java.util.concurrent.* import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.time.Duration.Companion.seconds @@ -22,27 +19,13 @@ import kotlin.time.Duration.Companion.seconds * mocking an HTTP client engine is difficult. */ public abstract class TestWithLocalServer { - protected val serverPort: Int = runBlocking { - SelectorManager(this.coroutineContext).use { - aSocket(it) - .tcp() - .bind() - .use { (it.localAddress as InetSocketAddress).port } - } - } - + protected val serverPort: Int = ServerSocket(0).use { it.localPort } protected val testHost: String = "localhost" public abstract val server: EmbeddedServer<*, *> @BeforeTest public fun startServer(): Unit = runBlocking { - val serverStarted = CompletableDeferred() - - server.monitor.subscribe(ApplicationStarted) { - serverStarted.complete(Unit) - } - withTimeout(5.seconds) { var attempt = 0 @@ -50,20 +33,32 @@ public abstract class TestWithLocalServer { attempt++ try { server.start() + println("test server listening on: $testHost:$serverPort") break } catch (cause: Throwable) { if (attempt >= 10) throw cause - delay(250L * attempt) + Thread.sleep(250L * attempt) } } while (true) - serverStarted.await() + ensureServerRunning() } } @AfterTest public fun stopServer() { - server.stop(0, 0) + server.stop(0, 0, TimeUnit.SECONDS) println("test server stopped") } + + private fun ensureServerRunning() { + do { + try { + Socket("localhost", serverPort).close() + break + } catch (_: Throwable) { + Thread.sleep(100) + } + } while (true) + } } diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt index 7bd34fe5ae..12287dcc8d 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt @@ -10,6 +10,7 @@ import kotlin.test.assertFalse import kotlin.test.assertTrue class HeadersTest { + @Test fun itBuilds() { val actual = Headers { diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 0e8f85de3a..3b88bc6401 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -33,9 +33,6 @@ public final class aws/smithy/kotlin/runtime/ErrorMetadata$Companion { public abstract interface annotation class aws/smithy/kotlin/runtime/ExperimentalApi : java/lang/annotation/Annotation { } -public abstract interface annotation class aws/smithy/kotlin/runtime/IgnoreNative : java/lang/annotation/Annotation { -} - public abstract interface annotation class aws/smithy/kotlin/runtime/InternalApi : java/lang/annotation/Annotation { } @@ -347,10 +344,6 @@ public final class aws/smithy/kotlin/runtime/compression/Gzip : aws/smithy/kotli public fun getId ()Ljava/lang/String; } -public final class aws/smithy/kotlin/runtime/compression/GzipTestUtilsJvmKt { - public static final fun decompressGzipBytes ([B)[B -} - public final class aws/smithy/kotlin/runtime/config/EnvironmentSetting { public static final field Companion Laws/smithy/kotlin/runtime/config/EnvironmentSetting$Companion; public fun (Lkotlin/jvm/functions/Function1;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V @@ -387,7 +380,6 @@ public final class aws/smithy/kotlin/runtime/config/EnvironmentSettingKt { public final class aws/smithy/kotlin/runtime/content/BigDecimal : java/lang/Number, java/lang/Comparable { public fun (Laws/smithy/kotlin/runtime/content/BigInteger;I)V public fun (Ljava/lang/String;)V - public synthetic fun (Ljava/math/BigDecimal;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun byteValue ()B public fun compareTo (Laws/smithy/kotlin/runtime/content/BigDecimal;)I public synthetic fun compareTo (Ljava/lang/Object;)I @@ -397,11 +389,8 @@ public final class aws/smithy/kotlin/runtime/content/BigDecimal : java/lang/Numb public final fun getExponent ()I public final fun getMantissa ()Laws/smithy/kotlin/runtime/content/BigInteger; public final fun getValue ()Ljava/lang/String; - public fun hashCode ()I public final fun intValue ()I public final fun longValue ()J - public final fun minus (Laws/smithy/kotlin/runtime/content/BigDecimal;)Laws/smithy/kotlin/runtime/content/BigDecimal; - public final fun plus (Laws/smithy/kotlin/runtime/content/BigDecimal;)Laws/smithy/kotlin/runtime/content/BigDecimal; public final fun shortValue ()S public fun toByte ()B public fun toDouble ()D @@ -410,7 +399,6 @@ public final class aws/smithy/kotlin/runtime/content/BigDecimal : java/lang/Numb public fun toLong ()J public final fun toPlainString ()Ljava/lang/String; public fun toShort ()S - public fun toString ()Ljava/lang/String; } public final class aws/smithy/kotlin/runtime/content/BigInteger : java/lang/Number, java/lang/Comparable { @@ -437,8 +425,6 @@ public final class aws/smithy/kotlin/runtime/content/BigInteger : java/lang/Numb public fun toLong ()J public fun toShort ()S public fun toString ()Ljava/lang/String; - public final fun toString (I)Ljava/lang/String; - public static synthetic fun toString$default (Laws/smithy/kotlin/runtime/content/BigInteger;IILjava/lang/Object;)Ljava/lang/String; } public abstract class aws/smithy/kotlin/runtime/content/ByteStream { @@ -488,8 +474,6 @@ public final class aws/smithy/kotlin/runtime/content/ByteStreamJVMKt { } public final class aws/smithy/kotlin/runtime/content/ByteStreamKt { - public static final fun asByteStream (Ljava/lang/String;)Laws/smithy/kotlin/runtime/content/ByteStream; - public static final fun asByteStream ([B)Laws/smithy/kotlin/runtime/content/ByteStream; public static final fun cancel (Laws/smithy/kotlin/runtime/content/ByteStream;)V public static final fun decodeToString (Laws/smithy/kotlin/runtime/content/ByteStream;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun toByteArray (Laws/smithy/kotlin/runtime/content/ByteStream;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -820,12 +804,6 @@ public final class aws/smithy/kotlin/runtime/io/ClosedWriteChannelException : ja public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V } -public class aws/smithy/kotlin/runtime/io/EOFException : java/io/EOFException { - public fun ()V - public fun (Ljava/lang/String;)V - public fun (Ljava/lang/String;Ljava/lang/Throwable;)V -} - public final class aws/smithy/kotlin/runtime/io/GzipByteReadChannel : aws/smithy/kotlin/runtime/io/SdkByteReadChannel { public fun (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;)V public fun cancel (Ljava/lang/Throwable;)Z @@ -1095,13 +1073,16 @@ public abstract interface class aws/smithy/kotlin/runtime/io/SdkSource : java/io public abstract fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;J)J } -public final class aws/smithy/kotlin/runtime/io/SdkSourceKt { - public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkSource;Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V +public final class aws/smithy/kotlin/runtime/io/SdkSourceJVMKt { public static final fun readToByteArray (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun toSdkByteReadChannel (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; public static synthetic fun toSdkByteReadChannel$default (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; } +public final class aws/smithy/kotlin/runtime/io/SdkSourceKt { + public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkSource;Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V +} + public final class aws/smithy/kotlin/runtime/io/internal/ConvertKt { public static final fun toOkio (Laws/smithy/kotlin/runtime/io/SdkBuffer;)Lokio/Buffer; public static final fun toOkio (Laws/smithy/kotlin/runtime/io/SdkSink;)Lokio/Sink; @@ -2415,12 +2396,9 @@ public final class aws/smithy/kotlin/runtime/util/OperatingSystem { public final class aws/smithy/kotlin/runtime/util/OsFamily : java/lang/Enum { public static final field Android Laws/smithy/kotlin/runtime/util/OsFamily; public static final field Ios Laws/smithy/kotlin/runtime/util/OsFamily; - public static final field IpadOs Laws/smithy/kotlin/runtime/util/OsFamily; public static final field Linux Laws/smithy/kotlin/runtime/util/OsFamily; public static final field MacOs Laws/smithy/kotlin/runtime/util/OsFamily; - public static final field TvOs Laws/smithy/kotlin/runtime/util/OsFamily; public static final field Unknown Laws/smithy/kotlin/runtime/util/OsFamily; - public static final field WatchOs Laws/smithy/kotlin/runtime/util/OsFamily; public static final field Windows Laws/smithy/kotlin/runtime/util/OsFamily; public static fun getEntries ()Lkotlin/enums/EnumEntries; public fun toString ()Ljava/lang/String; diff --git a/runtime/runtime-core/build.gradle.kts b/runtime/runtime-core/build.gradle.kts index c26fd8e3c4..bbaa9d60ef 100644 --- a/runtime/runtime-core/build.gradle.kts +++ b/runtime/runtime-core/build.gradle.kts @@ -3,10 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import aws.sdk.kotlin.gradle.kmp.NATIVE_ENABLED -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -import org.jetbrains.kotlin.konan.target.HostManager - plugins { alias(libs.plugins.kotlinx.serialization) } @@ -24,14 +20,6 @@ kotlin { implementation(libs.okio) // Coroutines' locking features are used in retry token bucket implementations api(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.datetime) - } - } - - nativeMain { - dependencies { - api(libs.crt.kotlin) - implementation(libs.kotlin.multiplatform.bignum) } } @@ -53,17 +41,4 @@ kotlin { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } } - - if (NATIVE_ENABLED && !HostManager.hostIsMingw) { - targets.withType { - compilations["main"].cinterops { - val interopDir = "$projectDir/posix/src/posixInterop/cinterop" - create("environ") { - includeDirs(interopDir) - packageName("aws.smithy.platform.posix") - headers(listOf("$interopDir/environ.h")) - } - } - } - } } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Annotations.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Annotations.kt index fa8022f0fd..0a9dac6a55 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Annotations.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Annotations.kt @@ -71,9 +71,3 @@ public annotation class PlannedRemoval( val major: Int, val minor: Int, ) - -/** - * Marks a test that should be ignored on Native platforms - */ -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -public expect annotation class IgnoreNative() diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/compression/GzipTestUtils.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/compression/GzipTestUtils.kt deleted file mode 100644 index 31b014acd0..0000000000 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/compression/GzipTestUtils.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.compression - -import aws.smithy.kotlin.runtime.InternalApi - -/** - * Decompresses a [ByteArray] compressed using the gzip format - */ -@InternalApi -public expect fun decompressGzipBytes(bytes: ByteArray): ByteArray diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigDecimal.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigDecimal.kt index 408f4080f6..d9af8f85d6 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigDecimal.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigDecimal.kt @@ -11,94 +11,32 @@ package aws.smithy.kotlin.runtime.content public expect class BigDecimal(value: String) : Number, Comparable { - /** * Create an instance of [BigDecimal] from a mantissa and exponent. - * @param mantissa a [BigInteger] representing the [significant digits](https://en.wikipedia.org/wiki/Significand) - * of this decimal value - * @param exponent an [Int] representing the exponent of this decimal value + * @param mantissa a [BigInteger] representing the mantissa of this big decimal + * @param exponent an [Int] representing the exponent of this big decimal */ public constructor(mantissa: BigInteger, exponent: Int) /** - * The [significant digits](https://en.wikipedia.org/wiki/Significand) of this decimal value + * The mantissa of this decimal number */ public val mantissa: BigInteger /** - * The exponent of this decimal number. If zero or positive, this represents the number of digits to the right of - * the decimal point. If negative, the [mantissa] is multiplied by ten to the power of the negation of the scale. + * The exponent of this decimal number. + * If zero or positive, this represents the number of digits to the right of the decimal point. + * If negative, the mantissa is multiplied by ten to the power of the negation of the scale. */ public val exponent: Int - /** - * Converts this value to a [Byte], which may involve rounding or truncation - */ override fun toByte(): Byte - - /** - * Converts this value to a [Double], which may involve rounding or truncation - */ override fun toDouble(): Double - - /** - * Converts this value to a [Float], which may involve rounding or truncation - */ override fun toFloat(): Float - - /** - * Converts this value to a [Short], which may involve rounding or truncation - */ override fun toShort(): Short - - /** - * Converts this value to an [Int], which may involve rounding or truncation - */ override fun toInt(): Int - - /** - * Converts this value to a [Long], which may involve rounding or truncation - */ override fun toLong(): Long - - /** - * Returns the decimal (i.e., radix-10) string representation of this value in long-form (i.e., _not_ scientific) - * notation - */ public fun toPlainString(): String - - /** - * Returns the decimal (i.e., radix-10) string representation of this value using scientific notation if an exponent - * is needed - */ - override fun toString(): String - - /** - * Returns a hash code for this value - */ - override fun hashCode(): Int - - /** - * Checks if this value is equal to the given object - * @param other The other value to compare against - */ override fun equals(other: Any?): Boolean - - /** - * Returns the sum of this value and the given value - * @param other The other value to add (i.e., the addend) - */ - public operator fun plus(other: BigDecimal): BigDecimal - - /** - * Returns the difference of this value and the given value - * @param other The value to subtract (i.e., the subtrahend) - */ - public operator fun minus(other: BigDecimal): BigDecimal - - /** - * Compare this value to the given value for in/equality - * @param other The value to compare against - */ public override operator fun compareTo(other: BigDecimal): Int } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigInteger.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigInteger.kt index 798c653003..f223bc36ca 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigInteger.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/BigInteger.kt @@ -11,86 +11,23 @@ package aws.smithy.kotlin.runtime.content public expect class BigInteger(value: String) : Number, Comparable { - /** * Create an instance of [BigInteger] from a [ByteArray] * @param bytes ByteArray representing the large integer */ public constructor(bytes: ByteArray) - /** - * Converts this value to a [Byte], which may involve rounding or truncation - */ override fun toByte(): Byte - - /** - * Converts this value to a [Long], which may involve rounding or truncation - */ override fun toLong(): Long - - /** - * Converts this value to a [Short], which may involve rounding or truncation - */ override fun toShort(): Short - - /** - * Converts this value to an [Int], which may involve rounding or truncation - */ override fun toInt(): Int - - /** - * Converts this value to a [Float], which may involve rounding or truncation - */ override fun toFloat(): Float - - /** - * Converts this value to a [Double], which may involve rounding or truncation - */ override fun toDouble(): Double - - /** - * Returns the decimal (i.e., radix-10) string representation of this value - */ override fun toString(): String - - /** - * Returns a string representation of this value in the given radix - * @param radix The [numerical base](https://en.wikipedia.org/wiki/Radix) in which to represent the value - */ - public fun toString(radix: Int = 10): String - - /** - * Returns a hash code for this value - */ override fun hashCode(): Int - - /** - * Checks if this value is equal to the given object - * @param other The other value to compare against - */ override fun equals(other: Any?): Boolean - - /** - * Returns the sum of this value and the given value - * @param other The other value to add (i.e., the addend) - */ public operator fun plus(other: BigInteger): BigInteger - - /** - * Returns the difference of this value and the given value - * @param other The value to subtract (i.e., the subtrahend) - */ public operator fun minus(other: BigInteger): BigInteger - - /** - * Returns the [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) binary representation of this - * value - */ public fun toByteArray(): ByteArray - - /** - * Compare this value to the given value for in/equality - * @param other The value to compare against - */ public override operator fun compareTo(other: BigInteger): Int } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt index 75fc36c00d..96bf20b25a 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt @@ -196,13 +196,3 @@ private fun SdkSource.toFlow(bufferSize: Long): Flow = flow { emit(sink.readByteArray()) } } - -/** - * Convert this [String] to a [ByteStream] - */ -public fun String.asByteStream(): ByteStream = ByteStream.fromString(this) - -/** - * Convert this [ByteArray] to a [ByteStream] - */ -public fun ByteArray.asByteStream(): ByteStream = ByteStream.fromBytes(this) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32.kt index 454c4fc552..84b76b89a0 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32.kt @@ -11,13 +11,11 @@ public abstract class Crc32Base : HashFunction { override val blockSizeBytes: Int = 4 override val digestSizeBytes: Int = 4 - /** - * Digest the current checksum, returning it as a [UInt] - */ public abstract fun digestValue(): UInt override fun digest(): ByteArray { val x = digestValue() + reset() return byteArrayOf( ((x shr 24) and 0xffu).toByte(), ((x shr 16) and 0xffu).toByte(), diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32c.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32c.kt index a6d9e10a61..da77560226 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32c.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/Crc32c.kt @@ -21,7 +21,7 @@ public class Crc32c : Crc32Base() { override fun update(input: ByteArray, offset: Int, length: Int): Unit = md.update(input, offset, length) - override fun digestValue(): UInt = md.getValue().toUInt().also { reset() } + override fun digestValue(): UInt = md.getValue().toUInt() override fun reset(): Unit = md.reset() } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt index eaa85b35b1..178e210a02 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt @@ -30,7 +30,7 @@ internal expect class BufferedSinkAdapter(sink: okio.BufferedSink) : SdkBuffered // base class that fills in most of the common implementation, platforms just need to implement the platform specific // part of the interface internal abstract class AbstractBufferedSinkAdapter( - internal val delegate: okio.BufferedSink, + protected val delegate: okio.BufferedSink, ) : SdkBufferedSink { override fun toString(): String = delegate.toString() diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt index e1842e26dc..8b92fbbe64 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt @@ -32,76 +32,53 @@ internal expect class BufferedSourceAdapter(source: okio.BufferedSource) : SdkBu override fun close() } -/** - * Used to wrap calls to Okio, catching Okio exceptions (e.g. okio.EOFException) and throwing our own (e.g. aws.smithy.kotlin.runtime.io.EOFException). - */ -internal inline fun SdkBufferedSource.wrapOkio(block: SdkBufferedSource.() -> T): T = try { - block() -} catch (e: okio.EOFException) { - throw EOFException("Okio operation failed: ${e.message}", e) -} catch (e: okio.IOException) { - throw IOException("Okio operation failed: ${e.message}", e) -} - // base class that fills in most of the common implementation, platforms just need to implement the platform specific // part of the interface internal abstract class AbstractBufferedSourceAdapter( - internal val delegate: okio.BufferedSource, + protected val delegate: okio.BufferedSource, ) : SdkBufferedSource { override val buffer: SdkBuffer get() = delegate.buffer.toSdk() - override fun skip(byteCount: Long): Unit = wrapOkio { delegate.skip(byteCount) } + override fun skip(byteCount: Long): Unit = delegate.skip(byteCount) - override fun readByte(): Byte = wrapOkio { delegate.readByte() } + override fun readByte(): Byte = delegate.readByte() - override fun readShort(): Short = wrapOkio { delegate.readShort() } + override fun readShort(): Short = delegate.readShort() - override fun readShortLe(): Short = wrapOkio { delegate.readShortLe() } + override fun readShortLe(): Short = delegate.readShortLe() - override fun readLong(): Long = wrapOkio { delegate.readLong() } + override fun readLong(): Long = delegate.readLong() - override fun readLongLe(): Long = wrapOkio { delegate.readLongLe() } + override fun readLongLe(): Long = delegate.readLongLe() - override fun readInt(): Int = wrapOkio { delegate.readInt() } + override fun readInt(): Int = delegate.readInt() - override fun readIntLe(): Int = wrapOkio { delegate.readIntLe() } + override fun readIntLe(): Int = delegate.readIntLe() - override fun readAll(sink: SdkSink): Long = wrapOkio { + override fun readAll(sink: SdkSink): Long = delegate.readAll(sink.toOkio()) - } - override fun read(sink: ByteArray, offset: Int, limit: Int): Int = wrapOkio { + override fun read(sink: ByteArray, offset: Int, limit: Int): Int = delegate.read(sink, offset, limit) - } - override fun read(sink: SdkBuffer, limit: Long): Long = wrapOkio { + override fun read(sink: SdkBuffer, limit: Long): Long = delegate.read(sink.toOkio(), limit) - } - override fun readByteArray(): ByteArray = wrapOkio { delegate.readByteArray() } + override fun readByteArray(): ByteArray = delegate.readByteArray() - override fun readByteArray(byteCount: Long): ByteArray = wrapOkio { - delegate.readByteArray(byteCount) - } + override fun readByteArray(byteCount: Long): ByteArray = delegate.readByteArray(byteCount) - override fun readUtf8(): String = wrapOkio { delegate.readUtf8() } + override fun readUtf8(): String = delegate.readUtf8() - override fun readUtf8(byteCount: Long): String = wrapOkio { - delegate.readUtf8(byteCount) - } + override fun readUtf8(byteCount: Long): String = delegate.readUtf8(byteCount) - override fun peek(): SdkBufferedSource = wrapOkio { + override fun peek(): SdkBufferedSource = delegate.peek().toSdk().buffer() - } - - override fun exhausted(): Boolean = wrapOkio { delegate.exhausted() } - - override fun request(byteCount: Long): Boolean = wrapOkio { - delegate.request(byteCount) - } + override fun exhausted(): Boolean = delegate.exhausted() + override fun request(byteCount: Long): Boolean = delegate.request(byteCount) - override fun require(byteCount: Long): Unit = wrapOkio { delegate.require(byteCount) } + override fun require(byteCount: Long): Unit = delegate.require(byteCount) - override fun close() = wrapOkio { delegate.close() } + override fun close() = delegate.close() } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt index 96d6685ff8..b0dfa89c5f 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt @@ -10,9 +10,8 @@ public expect open class IOException(message: String?, cause: Throwable?) : Exce public constructor(message: String?) } -public expect open class EOFException(message: String?, cause: Throwable?) : IOException { +public expect open class EOFException(message: String?) : IOException { public constructor() - public constructor(message: String?) } /** diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index 92a159725d..a50259e240 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt @@ -7,7 +7,6 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi import aws.smithy.kotlin.runtime.hashing.HashFunction import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.withContext /** diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt index aefb75dc08..dfb9534627 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt @@ -6,15 +6,7 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.io.internal.JobChannel -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers -import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.ensureActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext /** * A source for reading a stream of bytes (e.g. from file, network, or in-memory buffer). Sources may @@ -51,9 +43,7 @@ public interface SdkSource : Closeable { * Consume the [SdkSource] and pull the entire contents into memory as a [ByteArray]. */ @InternalApi -public suspend fun SdkSource.readToByteArray(): ByteArray = withContext(SdkDispatchers.IO) { - use { it.buffer().readByteArray() } -} +public expect suspend fun SdkSource.readToByteArray(): ByteArray /** * Convert the [SdkSource] to an [SdkByteReadChannel]. Content is read from the source and forwarded @@ -61,32 +51,8 @@ public suspend fun SdkSource.readToByteArray(): ByteArray = withContext(SdkDispa * @param coroutineScope the coroutine scope to use to launch a background reader channel responsible for propagating data * between source and the returned channel */ -@OptIn(DelicateCoroutinesApi::class) @InternalApi -public fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope? = null): SdkByteReadChannel { - val source = this - val ch = JobChannel() - val scope = coroutineScope ?: GlobalScope - val job = scope.launch(SdkDispatchers.IO + CoroutineName("sdk-source-reader")) { - val buffer = SdkBuffer() - val result = runCatching { - source.use { - while (true) { - ensureActive() - val rc = source.read(buffer, DEFAULT_BYTE_CHANNEL_MAX_BUFFER_SIZE.toLong()) - if (rc == -1L) break - ch.write(buffer) - } - } - } - - ch.close(result.exceptionOrNull()) - } - - ch.attachJob(job) - - return ch -} +public expect fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope? = null): SdkByteReadChannel /** * Remove exactly [byteCount] bytes from this source and appends them to [sink]. diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt index e5cd2a8f70..1657f933ce 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt @@ -9,108 +9,95 @@ package aws.smithy.kotlin.runtime.io.internal import aws.smithy.kotlin.runtime.io.* -/** - * Used to wrap calls to Okio, catching Okio exceptions (e.g. okio.EOFException) and throwing our own (e.g. aws.smithy.kotlin.runtime.io.EOFException). - */ -internal inline fun SdkBuffer.wrapOkio(block: SdkBuffer.() -> T): T = try { - block() -} catch (e: okio.EOFException) { - throw EOFException("Okio operation failed: ${e.message}", e) -} catch (e: okio.IOException) { - throw IOException("Okio operation failed: ${e.message}", e) -} - -internal inline fun SdkBuffer.commonSkip(byteCount: Long) = wrapOkio { inner.skip(byteCount) } +internal inline fun SdkBuffer.commonSkip(byteCount: Long) = inner.skip(byteCount) -internal inline fun SdkBuffer.commonReadByte(): Byte = wrapOkio { inner.readByte() } +internal inline fun SdkBuffer.commonReadByte(): Byte = inner.readByte() -internal inline fun SdkBuffer.commonReadShort(): Short = wrapOkio { inner.readShort() } +internal inline fun SdkBuffer.commonReadShort(): Short = inner.readShort() -internal inline fun SdkBuffer.commonReadShortLe(): Short = wrapOkio { inner.readShortLe() } +internal inline fun SdkBuffer.commonReadShortLe(): Short = inner.readShortLe() -internal inline fun SdkBuffer.commonReadLong(): Long = wrapOkio { inner.readLong() } +internal inline fun SdkBuffer.commonReadLong(): Long = inner.readLong() -internal inline fun SdkBuffer.commonReadLongLe(): Long = wrapOkio { inner.readLongLe() } +internal inline fun SdkBuffer.commonReadLongLe(): Long = inner.readLongLe() -internal inline fun SdkBuffer.commonReadInt(): Int = wrapOkio { inner.readInt() } +internal inline fun SdkBuffer.commonReadInt(): Int = inner.readInt() -internal inline fun SdkBuffer.commonReadIntLe(): Int = wrapOkio { inner.readIntLe() } +internal inline fun SdkBuffer.commonReadIntLe(): Int = inner.readIntLe() -internal inline fun SdkBuffer.commonReadAll(sink: SdkSink): Long = wrapOkio { inner.readAll(sink.toOkio()) } +internal inline fun SdkBuffer.commonReadAll(sink: SdkSink): Long = + inner.readAll(sink.toOkio()) internal inline fun SdkBuffer.commonRead(sink: ByteArray, offset: Int, limit: Int): Int = - wrapOkio { inner.read(sink, offset, limit) } + inner.read(sink, offset, limit) internal inline fun SdkBuffer.commonRead(sink: SdkBuffer, limit: Long): Long = - wrapOkio { inner.read(sink.inner, limit) } + inner.read(sink.inner, limit) -internal inline fun SdkBuffer.commonReadByteArray(): ByteArray = wrapOkio { inner.readByteArray() } +internal inline fun SdkBuffer.commonReadByteArray(): ByteArray = inner.readByteArray() -internal inline fun SdkBuffer.commonReadByteArray(byteCount: Long): ByteArray = wrapOkio { inner.readByteArray(byteCount) } +internal inline fun SdkBuffer.commonReadByteArray(byteCount: Long): ByteArray = inner.readByteArray(byteCount) -internal inline fun SdkBuffer.commonReadUtf8(): String = wrapOkio { inner.readUtf8() } +internal inline fun SdkBuffer.commonReadUtf8(): String = inner.readUtf8() -internal inline fun SdkBuffer.commonReadUtf8(byteCount: Long): String = wrapOkio { inner.readUtf8(byteCount) } +internal inline fun SdkBuffer.commonReadUtf8(byteCount: Long): String = inner.readUtf8(byteCount) -internal inline fun SdkBuffer.commonPeek(): SdkBufferedSource = wrapOkio { inner.peek().toSdk().buffer() } +internal inline fun SdkBuffer.commonPeek(): SdkBufferedSource = inner.peek().toSdk().buffer() +internal inline fun SdkBuffer.commonExhausted(): Boolean = inner.exhausted() +internal inline fun SdkBuffer.commonRequest(byteCount: Long): Boolean = inner.request(byteCount) -internal inline fun SdkBuffer.commonExhausted(): Boolean = wrapOkio { inner.exhausted() } - -internal inline fun SdkBuffer.commonRequest(byteCount: Long): Boolean = wrapOkio { inner.request(byteCount) } - -internal inline fun SdkBuffer.commonRequire(byteCount: Long) = wrapOkio { inner.require(byteCount) } +internal inline fun SdkBuffer.commonRequire(byteCount: Long): Unit = inner.require(byteCount) internal inline fun SdkBuffer.commonWrite(source: ByteArray, offset: Int, limit: Int) { - wrapOkio { inner.write(source, offset, limit) } + inner.write(source, offset, limit) } internal inline fun SdkBuffer.commonWrite(source: SdkSource, byteCount: Long) { - wrapOkio { inner.write(source.toOkio(), byteCount) } + inner.write(source.toOkio(), byteCount) } - internal inline fun SdkBuffer.commonWrite(source: SdkBuffer, byteCount: Long) { - wrapOkio { inner.write(source.toOkio(), byteCount) } + inner.write(source.toOkio(), byteCount) } internal inline fun SdkBuffer.commonWriteAll(source: SdkSource): Long = - wrapOkio { inner.writeAll(source.toOkio()) } + inner.writeAll(source.toOkio()) internal inline fun SdkBuffer.commonWriteUtf8(string: String, start: Int, endExclusive: Int) { - wrapOkio { inner.writeUtf8(string, start, endExclusive) } + inner.writeUtf8(string, start, endExclusive) } internal inline fun SdkBuffer.commonWriteByte(x: Byte) { - wrapOkio { inner.writeByte(x.toInt()) } + inner.writeByte(x.toInt()) } internal inline fun SdkBuffer.commonWriteShort(x: Short) { - wrapOkio { inner.writeShort(x.toInt()) } + inner.writeShort(x.toInt()) } internal inline fun SdkBuffer.commonWriteShortLe(x: Short) { - wrapOkio { inner.writeShortLe(x.toInt()) } + inner.writeShortLe(x.toInt()) } internal inline fun SdkBuffer.commonWriteInt(x: Int) { - wrapOkio { inner.writeInt(x) } + inner.writeInt(x) } internal inline fun SdkBuffer.commonWriteIntLe(x: Int) { - wrapOkio { inner.writeIntLe(x) } + inner.writeIntLe(x) } internal inline fun SdkBuffer.commonWriteLong(x: Long) { - wrapOkio { inner.writeLong(x) } + inner.writeLong(x) } internal inline fun SdkBuffer.commonWriteLongLe(x: Long) { - wrapOkio { inner.writeLongLe(x) } + inner.writeLongLe(x) } internal inline fun SdkBuffer.commonFlush() { - wrapOkio { inner.flush() } + inner.flush() } internal inline fun SdkBuffer.commonClose() { - wrapOkio { inner.close() } + inner.close() } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/time/TimestampFormat.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/time/TimestampFormat.kt index 025e1cd668..18d005b660 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/time/TimestampFormat.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/time/TimestampFormat.kt @@ -9,10 +9,10 @@ package aws.smithy.kotlin.runtime.time */ public enum class TimestampFormat { /** - * ISO-8601/RFC3339 timestamp including fractional seconds at microsecond precision (e.g., + * ISO-8601/RFC5399 timestamp including fractional seconds at microsecond precision (e.g., * "2022-04-25T16:44:13.667307Z") * - * Prefers RFC3339 when formatting + * Prefers RFC5399 when formatting */ ISO_8601, @@ -28,7 +28,7 @@ public enum class TimestampFormat { ISO_8601_CONDENSED_DATE, /** - * ISO-8601/RFC3339 timestamp including fractional seconds at arbitrary (i.e., untruncated) precision + * ISO-8601/RFC5399 timestamp including fractional seconds at arbitrary (i.e., untruncated) precision */ ISO_8601_FULL, diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/Platform.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/Platform.kt index cfd3dc1cc7..610a7b3405 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/Platform.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/Platform.kt @@ -67,9 +67,6 @@ public enum class OsFamily { Windows, Android, Ios, - IpadOs, - TvOs, - WatchOs, Unknown, ; @@ -79,9 +76,6 @@ public enum class OsFamily { Windows -> "windows" Android -> "android" Ios -> "ios" - IpadOs -> "ipados" - TvOs -> "tvos" - WatchOs -> "watchos" Unknown -> "unknown" } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/compression/GzipTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/compression/GzipTest.kt deleted file mode 100644 index 0125eae489..0000000000 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/compression/GzipTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.compression - -import aws.smithy.kotlin.runtime.content.ByteStream -import aws.smithy.kotlin.runtime.content.toByteArray -import kotlinx.coroutines.test.runTest -import kotlin.test.Test -import kotlin.test.assertContentEquals - -class GzipTest { - @Test - fun testCompress() = runTest { - val payload = "Hello World".encodeToByteArray() - val byteStream = ByteStream.fromBytes(payload) - - val compressed = Gzip() - .compress(byteStream) - .toByteArray() - - val decompressedBytes = decompressGzipBytes(compressed) - assertContentEquals(payload, decompressedBytes) - } - - @Test - fun testCompressEmptyByteArray() = runTest { - val payload = ByteArray(0) - val byteStream = ByteStream.fromBytes(payload) - - val compressed = Gzip() - .compress(byteStream) - .toByteArray() - - val decompressedBytes = decompressGzipBytes(compressed) - - assertContentEquals(payload, decompressedBytes) - } -} diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt index be78e6c3d8..2dc9083025 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt @@ -77,6 +77,7 @@ class BigIntegerTest { "0x123456789abcdef0" to "1311768467463790320", "0x00ffffffffffffffffffffffffffffffec" to "340282366920938463463374607431768211436", "0x81445edf51ddc07216da5621c727bfd379d400f3da08018d45749a" to "-52134902384590238490284023839028330923830129830129301234239834982", + ) tests.forEach { (hex, expected) -> diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32Test.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32Test.kt index 8f622fd513..e3b489aba0 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32Test.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32Test.kt @@ -20,6 +20,7 @@ class Crc32Test { val input = "foobar" crc.update(input.encodeToByteArray(), 0, input.length) + assertEquals(2666930069U, crc.digestValue()) // checksum of "foobar" assertEquals("nvYflQ==", crc.digest().encodeBase64String()) } @@ -38,8 +39,9 @@ class Crc32Test { val crc = Crc32() val input = "foobar" crc.update(input.encodeToByteArray(), 0, input.length / 2) + assertEquals(2356372769U, crc.digestValue()) // checksum of "foo" crc.update(input.encodeToByteArray(), (input.length - input.length / 2), input.length / 2) - assertEquals("nvYflQ==", crc.digest().encodeBase64String()) // checksum of "foobar" + assertEquals(2666930069U, crc.digestValue()) // checksum of "foobar" } @Test @@ -47,7 +49,8 @@ class Crc32Test { val crc = Crc32() val input = "foobar" crc.update(input.encodeToByteArray(), 0, input.length) - assertEquals("nvYflQ==", crc.digest().encodeBase64String()) // checksum of "foobar" + assertEquals(2666930069U, crc.digestValue()) // checksum of "foobar" + crc.digest() assertEquals(0U, crc.digestValue()) } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32cTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32cTest.kt index 0123036e53..184f62cbd9 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32cTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/hashing/Crc32cTest.kt @@ -33,6 +33,8 @@ class Crc32cTest { val input = "foobar" crc.update(input.encodeToByteArray(), 0, input.length / 2) + assertEquals(3485773341U, crc.digestValue()) // checksum of "foo" + crc.update(input.encodeToByteArray(), (input.length - input.length / 2), input.length / 2) assertEquals(224353407U, crc.digestValue()) // checksum of "foobar" } @@ -43,7 +45,8 @@ class Crc32cTest { val input = "foobar" crc.update(input.encodeToByteArray(), 0, input.length) - assertEquals("DV9cfw==", crc.digest().encodeBase64String()) // checksum of "foobar" + assertEquals(224353407U, crc.digestValue()) // checksum of "foobar" + assertEquals("DV9cfw==", crc.digest().encodeBase64String()) } @Test diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipByteReadChannelTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipByteReadChannelTest.kt index 259b4a3aab..6c6f1884ee 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipByteReadChannelTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipByteReadChannelTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.compression.decompressGzipBytes import aws.smithy.kotlin.runtime.hashing.crc32 import kotlinx.coroutines.test.runTest import kotlin.test.Test diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipSdkSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipSdkSourceTest.kt index 179673c28a..bfa47e012d 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipSdkSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipSdkSourceTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.compression.decompressGzipBytes import aws.smithy.kotlin.runtime.hashing.crc32 import kotlinx.coroutines.test.runTest import kotlin.test.Test diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipTestUtils.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipTestUtils.kt new file mode 100644 index 0000000000..109844814e --- /dev/null +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/GzipTestUtils.kt @@ -0,0 +1,10 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io + +/** + * Decompresses a byte array compressed using the gzip format + */ +internal expect fun decompressGzipBytes(bytes: ByteArray): ByteArray diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/net/HostResolverTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/net/HostResolverTest.kt deleted file mode 100644 index 3bad624976..0000000000 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/net/HostResolverTest.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.net - -import kotlinx.coroutines.test.runTest -import kotlin.test.* - -class HostResolverTest { - @Test - fun testResolveLocalhost() = runTest { - val addresses = HostResolver.Default.resolve("localhost") - assertTrue(addresses.isNotEmpty()) - - addresses.forEach { addr -> - assertEquals("localhost", addr.hostname) - - val localHostAddr = when (addr.address) { - is IpV4Addr -> IpV4Addr.LOCALHOST - is IpV6Addr -> IpV6Addr.LOCALHOST - } - assertEquals(addr.address, localHostAddr) - } - } - - @Test - fun testResolveIpv4Address() = runTest { - val addresses = HostResolver.Default.resolve("127.0.0.1") - assertTrue(addresses.isNotEmpty()) - - addresses.forEach { addr -> - assertTrue(addr.address is IpV4Addr) - assertContentEquals(byteArrayOf(127, 0, 0, 1), addr.address.octets) - } - } - - @Test - fun testResolveIpv6Address() = runTest { - val addresses = HostResolver.Default.resolve("::1") - assertTrue(addresses.isNotEmpty()) - - addresses.forEach { addr -> - assertTrue(addr.address is IpV6Addr) - val expectedBytes = ByteArray(16) { 0 } - expectedBytes[15] = 1 - assertContentEquals(expectedBytes, addr.address.octets) - } - } - - @Test - fun testResolveExampleDomain() = runTest { - val addresses = HostResolver.Default.resolve("example.com") - assertNotNull(addresses) - assertTrue(addresses.isNotEmpty()) - - addresses.forEach { addr -> - assertEquals("example.com", addr.hostname) - when (val ip = addr.address) { - is IpV4Addr -> assertEquals(4, ip.octets.size) - is IpV6Addr -> assertEquals(16, ip.octets.size) - } - } - } - - @Test - fun testResolveInvalidDomain() = runTest { - assertFails { - HostResolver.Default.resolve("this-domain-definitely-does-not-exist-12345.local") - } - } - - @Test - fun testNoopMethods() { - // Test no-op methods don't throw - val dummyAddr = HostAddress("test.com", IpV4Addr(ByteArray(4))) - val resolver = HostResolver.Default - resolver.reportFailure(dummyAddr) - resolver.purgeCache(null) - resolver.purgeCache(dummyAddr) - } -} diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt index c50bbd6d85..4c96d68dc5 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt @@ -17,6 +17,7 @@ import kotlin.time.Duration.Companion.seconds // tests for conversion from a parsed representation into an Instant instance class InstantTest { + /** * Conversion from a string to epoch sec/ns */ @@ -56,10 +57,8 @@ class InstantTest { // leap second - dropped to: 2020-12-31T23:59:59 FromTest("2020-12-31T23:59:60Z", 1609459199, 0), - - // condensed, date only - FromTest("20250205", 1738713600, 0), - FromTest("20231127", 1701043200, 0), + // midnight - should be 11/5 12AM + FromTest("2020-11-04T24:00:00Z", 1604534400, 0), ) @Test @@ -108,7 +107,7 @@ class InstantTest { .fromEpochSeconds(test.sec, test.ns) .format(format) val expected = getter(test) - assertEquals(expected, actual, "test[$idx]: failed to correctly format Instant.fromEpochSeconds(${test.sec}, ${test.ns}) as $format") + assertEquals(expected, actual, "test[$idx]: failed to correctly format Instant as $format") } } } @@ -215,26 +214,42 @@ class InstantTest { assertEquals("1944-06-06T00:00:00Z", timestamp.toString()) } - @Test - fun testUntil() { - val untilTests = mapOf( - ("2013-01-01T00:00:00+00:00" to "2014-01-01T00:00:00+00:00") to 365.days, - ("2020-01-01T00:00:00+00:00" to "2021-01-01T00:00:00+00:00") to 366.days, // leap year! - ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:00:00+00:00") to Duration.ZERO, - ("2023-10-06T00:00:00+00:00" to "2023-10-07T00:00:00+00:00") to 1.days, - ("2023-10-06T00:00:00+00:00" to "2023-10-06T01:00:00+00:00") to 1.hours, - ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:01:00+00:00") to 1.minutes, - ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:00:01+00:00") to 1.seconds, - ("2023-10-06T00:00:00+00:00" to "2023-10-06T12:12:12+00:00") to 12.hours + 12.minutes + 12.seconds, - ) - - for ((times, expectedDuration) in untilTests) { - val start = Instant.fromIso8601(times.first) - val end = Instant.fromIso8601(times.second) + // Select tests pulled from edge cases/tickets in the V2 Java SDK. + // Always good to learn from others... + class V2JavaSdkTests { + @Test + fun v2JavaSdkTt0031561767() { + val input = "Fri, 16 May 2014 23:56:46 GMT" + val instant: Instant = Instant.fromRfc5322(input) + assertEquals(input, instant.format(TimestampFormat.RFC_5322)) + } - assertEquals(expectedDuration, start.until(end)) - assertEquals(end.until(start), -expectedDuration) + /** + * Tests the Date marshalling and unmarshalling. Asserts that the value is + * same before and after marshalling/unmarshalling + */ + @Test + fun v2JavaSdkUnixTimestampRoundtrip() { + // v2 sdk used currentTimeMillis(), instead we just hard code a value here + // otherwise that would be a JVM specific test since since we do not (yet) have + // a Kotlin MPP way of getting current timestamp. Also obviously not using epoch mill + // but instead just epoch sec. Spirit of the test is the same though + longArrayOf(1595016457, 1L, 0L) + .map { Instant.fromEpochSeconds(0, 0) } + .forEach { instant -> + val serverSpecificDateFormat: String = instant.format(TimestampFormat.EPOCH_SECONDS) + val parsed: Instant = parseEpoch(serverSpecificDateFormat) + assertEquals(instant.epochSeconds, parsed.epochSeconds) + } } + + // NOTE: There is additional set of edge case tests related to a past issue + // in DateUtilsTest.java in the v2 sdk. Specifically around + // issue 223: https://github.com/aws/aws-sdk-java/issues/233 + // + // (1) - That issue is about round tripping values between SDK versions + // (2) - The input year in those tests is NOT valid and should never have + // been accepted by the parser. } @Test @@ -263,42 +278,26 @@ class InstantTest { assertEquals(test.second, actual, "test[$idx]: failed to format offset timestamp in UTC") } } -} -// Select tests pulled from edge cases/tickets in the V2 Java SDK. -// Always good to learn from others... -class V2JavaSdkTests { @Test - fun v2JavaSdkTt0031561767() { - val input = "Fri, 16 May 2014 23:56:46 GMT" - val instant: Instant = Instant.fromRfc5322(input) - assertEquals(input, instant.format(TimestampFormat.RFC_5322)) - } + fun testUntil() { + val untilTests = mapOf( + ("2013-01-01T00:00:00+00:00" to "2014-01-01T00:00:00+00:00") to 365.days, + ("2020-01-01T00:00:00+00:00" to "2021-01-01T00:00:00+00:00") to 366.days, // leap year! + ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:00:00+00:00") to Duration.ZERO, + ("2023-10-06T00:00:00+00:00" to "2023-10-07T00:00:00+00:00") to 1.days, + ("2023-10-06T00:00:00+00:00" to "2023-10-06T01:00:00+00:00") to 1.hours, + ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:01:00+00:00") to 1.minutes, + ("2023-10-06T00:00:00+00:00" to "2023-10-06T00:00:01+00:00") to 1.seconds, + ("2023-10-06T00:00:00+00:00" to "2023-10-06T12:12:12+00:00") to 12.hours + 12.minutes + 12.seconds, + ) - /** - * Tests the Date marshalling and unmarshalling. Asserts that the value is - * same before and after marshalling/unmarshalling - */ - @Test - fun v2JavaSdkUnixTimestampRoundtrip() { - // v2 sdk used currentTimeMillis(), instead we just hard code a value here - // otherwise that would be a JVM specific test since since we do not (yet) have - // a Kotlin MPP way of getting current timestamp. Also obviously not using epoch mill - // but instead just epoch sec. Spirit of the test is the same though - longArrayOf(1595016457, 1L, 0L) - .map { Instant.fromEpochSeconds(0, 0) } - .forEach { instant -> - val serverSpecificDateFormat: String = instant.format(TimestampFormat.EPOCH_SECONDS) - val parsed: Instant = parseEpoch(serverSpecificDateFormat) - assertEquals(instant.epochSeconds, parsed.epochSeconds) - } - } + for ((times, expectedDuration) in untilTests) { + val start = Instant.fromIso8601(times.first) + val end = Instant.fromIso8601(times.second) - // NOTE: There is additional set of edge case tests related to a past issue - // in DateUtilsTest.java in the v2 sdk. Specifically around - // issue 223: https://github.com/aws/aws-sdk-java/issues/233 - // - // (1) - That issue is about round tripping values between SDK versions - // (2) - The input year in those tests is NOT valid and should never have - // been accepted by the parser. + assertEquals(expectedDuration, start.until(end)) + assertEquals(end.until(start), -expectedDuration) + } + } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderTest.kt deleted file mode 100644 index 734f788e49..0000000000 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.util - -import kotlinx.coroutines.test.runTest -import kotlin.test.Test -import kotlin.test.assertContentEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull -import kotlin.test.assertTrue - -class SystemPlatformProviderTest { - @Test - fun testReadWriteFile() = runTest { - val ps = PlatformProvider.System - - val tempDir = if (ps.osInfo().family == OsFamily.Windows) { - requireNotNull(ps.getenv("TEMP")) { "%TEMP% unexpectedly null" } - } else { - "/tmp" - } - val path = "$tempDir/testReadWriteFile-${Uuid.random()}.txt" - - val expected = "Hello, File!".encodeToByteArray() - - ps.writeFile(path, expected) - assertTrue(ps.fileExists(path)) - - val actual = ps.readFileOrNull(path) - assertContentEquals(expected, actual) - } - - @Test - fun testGetEnv() = runTest { - val envVarKeys = listOf("PATH", "USERPROFILE") // PATH is not set on Windows CI - assertNotNull( - envVarKeys.firstNotNullOfOrNull { PlatformProvider.System.getenv(it) }, - ) - - assertNull(PlatformProvider.System.getenv("THIS_ENV_VAR_IS_NOT_SET")) - } - - @Test - fun testGetAllEnvVars() = runTest { - val allEnv = PlatformProvider.System.getAllEnvVars() - assertTrue(allEnv.isNotEmpty()) - - val envVarKeys = listOf("PATH", "USERPROFILE") // PATH is not set on Windows CI - assertTrue( - envVarKeys.any { allEnv.contains(it) }, - ) - } - - @Test - fun testOsInfo() = runTest { - val osInfo = PlatformProvider.System.osInfo() - assertNotEquals(OsFamily.Unknown, osInfo.family) - } -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/AnnotationsJvm.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/AnnotationsJvm.kt deleted file mode 100644 index b18b1bec0b..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/AnnotationsJvm.kt +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime - -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -public actual annotation class IgnoreNative diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsJvm.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsJvm.kt deleted file mode 100644 index bd2b274962..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsJvm.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.compression - -import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.io.use -import java.util.zip.GZIPInputStream - -/** - * Decompresses a [ByteArray] compressed using the gzip format - */ -@InternalApi -public actual fun decompressGzipBytes(bytes: ByteArray): ByteArray = - GZIPInputStream(bytes.inputStream()).use { it.readBytes() } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigDecimalJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigDecimalJVM.kt index 3890cfa9d9..9fb5d4efce 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigDecimalJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigDecimalJVM.kt @@ -4,54 +4,33 @@ */ package aws.smithy.kotlin.runtime.content -import java.math.BigDecimal as JvmBigDecimal - -public actual class BigDecimal private constructor(private val delegate: JvmBigDecimal) : +public actual class BigDecimal actual constructor(public val value: String) : Number(), Comparable { + private val delegate = java.math.BigDecimal(value) - private companion object { - /** - * Returns a new or existing [BigDecimal] wrapper for the given delegate [value] - * @param value The delegate value to wrap - * @param left A candidate wrapper which may already contain [value] - * @param right A candidate wrapper which may already contain [value] - */ - fun coalesceOrCreate(value: JvmBigDecimal, left: BigDecimal, right: BigDecimal): BigDecimal = when (value) { - left.delegate -> left - right.delegate -> right - else -> BigDecimal(value) - } - } - - public actual constructor(value: String) : this(JvmBigDecimal(value)) - public actual constructor(mantissa: BigInteger, exponent: Int) : this(JvmBigDecimal(mantissa.delegate, exponent)) + public actual constructor(mantissa: BigInteger, exponent: Int) : this( + java.math.BigDecimal( + java.math.BigInteger(mantissa.toString()), + exponent, + ).toPlainString(), + ) public actual fun toPlainString(): String = delegate.toPlainString() - public actual override fun toString(): String = delegate.toString() - public actual override fun toByte(): Byte = delegate.toByte() - public actual override fun toDouble(): Double = delegate.toDouble() - public actual override fun toFloat(): Float = delegate.toFloat() - public actual override fun toInt(): Int = delegate.toInt() - public actual override fun toLong(): Long = delegate.toLong() - public actual override fun toShort(): Short = delegate.toShort() + actual override fun toByte(): Byte = delegate.toByte() + actual override fun toDouble(): Double = delegate.toDouble() + actual override fun toFloat(): Float = delegate.toFloat() + actual override fun toInt(): Int = delegate.toInt() + actual override fun toLong(): Long = delegate.toLong() + actual override fun toShort(): Short = delegate.toShort() - public actual override fun equals(other: Any?): Boolean = other is BigDecimal && delegate == other.delegate - public actual override fun hashCode(): Int = 31 + delegate.hashCode() + actual override fun equals(other: Any?): Boolean = other is BigDecimal && delegate == other.delegate public actual val mantissa: BigInteger - get() = BigInteger(delegate.unscaledValue()) + get() = BigInteger(delegate.unscaledValue().toString()) public actual val exponent: Int get() = delegate.scale() - public val value: String = delegate.toString() - - public actual operator fun plus(other: BigDecimal): BigDecimal = - coalesceOrCreate(delegate + other.delegate, this, other) - - public actual operator fun minus(other: BigDecimal): BigDecimal = - coalesceOrCreate(delegate - other.delegate, this, other) - actual override fun compareTo(other: BigDecimal): Int = delegate.compareTo(other.delegate) } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigIntegerJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigIntegerJVM.kt index 738d5ed102..e89d12c9c4 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigIntegerJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/BigIntegerJVM.kt @@ -4,28 +4,12 @@ */ package aws.smithy.kotlin.runtime.content -import java.math.BigInteger as JvmBigInteger - -public actual class BigInteger internal constructor(internal val delegate: JvmBigInteger) : +public actual class BigInteger actual constructor(public val value: String) : Number(), Comparable { + private val delegate = java.math.BigInteger(value) - private companion object { - /** - * Returns a new or existing [BigInteger] wrapper for the given delegate [value] - * @param value The delegate value to wrap - * @param left A candidate wrapper which may already contain [value] - * @param right A candidate wrapper which may already contain [value] - */ - fun coalesceOrCreate(value: JvmBigInteger, left: BigInteger, right: BigInteger): BigInteger = when (value) { - left.delegate -> left - right.delegate -> right - else -> BigInteger(value) - } - } - - public actual constructor(value: String) : this(JvmBigInteger(value)) - public actual constructor(bytes: ByteArray) : this(JvmBigInteger(bytes)) + public actual constructor(bytes: ByteArray) : this(java.math.BigInteger(bytes).toString()) public actual override fun toByte(): Byte = delegate.toByte() public actual override fun toLong(): Long = delegate.toLong() @@ -33,19 +17,12 @@ public actual class BigInteger internal constructor(internal val delegate: JvmBi public actual override fun toInt(): Int = delegate.toInt() public actual override fun toFloat(): Float = delegate.toFloat() public actual override fun toDouble(): Double = delegate.toDouble() - public actual override fun toString(): String = toString(10) - public actual fun toString(radix: Int): String = delegate.toString(radix) - public val value: String = delegate.toString() - - public actual override fun hashCode(): Int = 17 + delegate.hashCode() + public actual override fun toString(): String = delegate.toString() + public actual override fun hashCode(): Int = delegate.hashCode() public actual override fun equals(other: Any?): Boolean = other is BigInteger && delegate == other.delegate - public actual operator fun plus(other: BigInteger): BigInteger = - coalesceOrCreate(delegate + other.delegate, this, other) - - public actual operator fun minus(other: BigInteger): BigInteger = - coalesceOrCreate(delegate - other.delegate, this, other) - + public actual operator fun plus(other: BigInteger): BigInteger = BigInteger((delegate + other.delegate).toString()) + public actual operator fun minus(other: BigInteger): BigInteger = BigInteger((delegate - other.delegate).toString()) public actual override operator fun compareTo(other: BigInteger): Int = delegate.compareTo(other.delegate) public actual fun toByteArray(): ByteArray = delegate.toByteArray() } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt index 9d1a03d49a..5647ac15af 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt @@ -96,14 +96,7 @@ public suspend fun ByteStream.writeToFile(path: Path): Long = writeToFile(path.t public fun ByteStream.toInputStream(): InputStream = when (this) { is ByteStream.Buffer -> ByteArrayInputStream(bytes()) is ByteStream.ChannelStream -> readFrom().toInputStream() - is ByteStream.SourceStream -> { - val buffer = (readFrom().buffer()) - when (buffer) { - is SdkBuffer -> buffer.inputStream() - is BufferedSourceAdapter -> buffer.inputStream() - else -> throw IllegalStateException("Buffer class ${buffer::class.simpleName} could not be converted to an InputStream") - } - } + is ByteStream.SourceStream -> readFrom().buffer().inputStream() } /** diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/hashing/Crc32JVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/hashing/Crc32JVM.kt index 5afae09bad..0c42a47434 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/hashing/Crc32JVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/hashing/Crc32JVM.kt @@ -13,7 +13,7 @@ public actual class Crc32 : Crc32Base() { actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = md.update(input, offset, length) - actual override fun digestValue(): UInt = md.value.toUInt().also { reset() } + actual override fun digestValue(): UInt = md.value.toUInt() actual override fun reset(): Unit = md.reset() } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt index 6d01916a93..82d28aaac0 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt @@ -7,14 +7,4 @@ package aws.smithy.kotlin.runtime.io public actual typealias IOException = java.io.IOException -public actual open class EOFException actual constructor( - message: String?, - cause: Throwable?, -) : java.io.EOFException(message) { - init { - initCause(cause) - } - - public actual constructor() : this(null, null) - public actual constructor(message: String?) : this(message, null) -} +public actual typealias EOFException = java.io.EOFException diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt index c2f486c3c9..3fc01858e4 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt @@ -10,7 +10,6 @@ import java.io.InputStream import java.io.OutputStream import java.nio.ByteBuffer -// FIXME Commonize with Native after removing WritableByteStream / ReadableByteStream in 1.6.x public actual class SdkBuffer : SdkBufferedSource, SdkBufferedSink { diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannelJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannelJVM.kt index 2986b998a3..5afef01745 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannelJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannelJVM.kt @@ -6,6 +6,7 @@ package aws.smithy.kotlin.runtime.io import kotlinx.coroutines.runBlocking import java.io.InputStream +import java.util.* /** * Create a blocking [InputStream] that blocks everytime the channel suspends at [SdkByteReadChannel.read] diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt new file mode 100644 index 0000000000..2eda1fd3f7 --- /dev/null +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt @@ -0,0 +1,42 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.smithy.kotlin.runtime.io + +import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.io.internal.JobChannel +import kotlinx.coroutines.* + +@InternalApi +public actual suspend fun SdkSource.readToByteArray(): ByteArray = withContext(Dispatchers.IO) { + use { it.buffer().readByteArray() } +} + +@InternalApi +@OptIn(DelicateCoroutinesApi::class) +public actual fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope?): SdkByteReadChannel { + val source = this + val ch = JobChannel() + val scope = coroutineScope ?: GlobalScope + val job = scope.launch(Dispatchers.IO + CoroutineName("sdk-source-reader")) { + val buffer = SdkBuffer() + val result = runCatching { + source.use { + while (true) { + ensureActive() + val rc = source.read(buffer, DEFAULT_BYTE_CHANNEL_MAX_BUFFER_SIZE.toLong()) + if (rc == -1L) break + ch.write(buffer) + } + } + } + + ch.close(result.exceptionOrNull()) + } + + ch.attachJob(job) + + return ch +} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt index 3f0f1459fa..b90a57de82 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt @@ -25,9 +25,7 @@ import kotlin.time.Duration import kotlin.time.toKotlinDuration import java.time.Duration as jtDuration import java.time.Instant as jtInstant -import kotlinx.datetime.Instant as KtInstant -// FIXME Consider making this multiplatform (`common`) using kotlinx.datetime public actual class Instant(internal val value: jtInstant) : Comparable { public actual val epochSeconds: Long get() = value.epochSecond @@ -137,12 +135,12 @@ public actual class Instant(internal val value: jtInstant) : Comparable /** * Create an [Instant] with the minimum possible value */ - public actual val MIN_VALUE: Instant = fromEpochMilliseconds(KtInstant.DISTANT_PAST.toEpochMilliseconds()) + public actual val MIN_VALUE: Instant = Instant(jtInstant.MIN) /** * Create an [Instant] with the maximum possible value */ - public actual val MAX_VALUE: Instant = fromEpochMilliseconds(KtInstant.DISTANT_FUTURE.toEpochMilliseconds()) + public actual val MAX_VALUE: Instant = Instant(jtInstant.MAX) } } diff --git a/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsJVM.kt b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsJVM.kt new file mode 100644 index 0000000000..1d79af8102 --- /dev/null +++ b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsJVM.kt @@ -0,0 +1,13 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io + +import java.util.zip.GZIPInputStream + +/** + * Decompresses a byte array compressed using the gzip format + */ +internal actual fun decompressGzipBytes(bytes: ByteArray): ByteArray = + GZIPInputStream(bytes.inputStream()).use { it.readBytes() } diff --git a/runtime/runtime-core/linuxX64/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderLinuxX64Test.kt b/runtime/runtime-core/linuxX64/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderLinuxX64Test.kt deleted file mode 100644 index f6ca8da166..0000000000 --- a/runtime/runtime-core/linuxX64/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderLinuxX64Test.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.util - -import kotlinx.coroutines.test.runTest -import kotlin.test.Test -import kotlin.test.assertEquals - -class SystemPlatformProviderLinuxX64Test { - @Test - fun testOsInfo() = runTest { - val osInfo = PlatformProvider.System.osInfo() - assertEquals(OsFamily.Linux, osInfo.family) - } -} diff --git a/runtime/runtime-core/mingw/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderMingw.kt b/runtime/runtime-core/mingw/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderMingw.kt deleted file mode 100644 index cc3dfe8f98..0000000000 --- a/runtime/runtime-core/mingw/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderMingw.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.util - -import aws.sdk.kotlin.crt.util.osVersionFromKernel -import kotlinx.cinterop.* -import platform.posix.environ - -public actual object SystemDefaultProvider : SystemDefaultProviderBase() { - actual override val filePathSeparator: String = "\\" - - // FIXME We currently get the OS info by parsing from Kernel32.dll. Is there a less hacky way we can do this? - actual override fun osInfo(): OperatingSystem = OperatingSystem(OsFamily.Windows, osVersionFromKernel()) - - actual override fun getAllEnvVars(): Map = memScoped { - generateSequence(0) { it + 1 } - .map { idx -> environ?.get(idx)?.toKString() } - .takeWhile { it != null } - .associate { env -> - val parts = env?.split("=", limit = 2) - check(parts?.size == 2) { "Environment entry \"$env\" is malformed" } - parts[0] to parts[1] - } - } -} diff --git a/runtime/runtime-core/mingw/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderMingwTest.kt b/runtime/runtime-core/mingw/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderMingwTest.kt deleted file mode 100644 index 8c6d9f450d..0000000000 --- a/runtime/runtime-core/mingw/test/aws/smithy/kotlin/runtime/util/SystemPlatformProviderMingwTest.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.util - -import kotlinx.coroutines.test.runTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotNull - -class SystemPlatformProviderMingwTest { - @Test - fun testOsInfo() = runTest { - val osInfo = PlatformProvider.System.osInfo() - assertEquals(OsFamily.Windows, osInfo.family) - assertNotNull(osInfo.version) - } -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/AnnotationsNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/AnnotationsNative.kt deleted file mode 100644 index 76c0ce0cef..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/AnnotationsNative.kt +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime - -public actual typealias IgnoreNative = kotlin.test.Ignore diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipCompressor.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipCompressor.kt deleted file mode 100644 index 2d4c657af3..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipCompressor.kt +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.compression - -import aws.sdk.kotlin.crt.Closeable -import aws.smithy.kotlin.runtime.io.SdkBuffer -import kotlinx.cinterop.* -import platform.zlib.* - -private const val DEFAULT_WINDOW_BITS = 15 // Default window bits -private const val WINDOW_BITS_GZIP_OFFSET = 16 // Gzip offset for window bits -private const val MEM_LEVEL = 8 // Default memory level - -/** - * Streaming-style gzip compressor, implemented using zlib bindings - */ -@OptIn(ExperimentalForeignApi::class) -internal class GzipCompressor : Closeable { - companion object { - internal const val BUFFER_SIZE = 16384 - } - - private val stream = nativeHeap.alloc() - private val outputBuffer = SdkBuffer() - internal var isClosed = false - - internal val availableForRead: Int - get() = outputBuffer.size.toInt() - - init { - // Initialize deflate with gzip encoding - val initResult = deflateInit2_( - stream.ptr, - Z_BEST_COMPRESSION, - Z_DEFLATED, - DEFAULT_WINDOW_BITS + WINDOW_BITS_GZIP_OFFSET, - MEM_LEVEL, - Z_DEFAULT_STRATEGY, - ZLIB_VERSION, - sizeOf().toInt(), - ) - - check(initResult == Z_OK) { "Failed to initialize zlib deflate with error code $initResult: ${zError(initResult)!!.toKString()}" } - } - - /** - * Update the compressor with [input] bytes - */ - fun update(input: ByteArray) = memScoped { - check(!isClosed) { "Compressor is closed" } - - val inputPin = input.pin() - - stream.next_in = inputPin.addressOf(0).reinterpret() - stream.avail_in = input.size.toUInt() - - val compressionBuffer = ByteArray(BUFFER_SIZE) - - while (stream.avail_in > 0u) { - val outputPin = compressionBuffer.pin() - stream.next_out = outputPin.addressOf(0).reinterpret() - stream.avail_out = BUFFER_SIZE.toUInt() - - val deflateResult = deflate(stream.ptr, Z_NO_FLUSH) - check(deflateResult == Z_OK) { "Deflate failed with error code $deflateResult" } - - val bytesWritten = BUFFER_SIZE - stream.avail_out.toInt() - outputBuffer.write(compressionBuffer, 0, bytesWritten) - - outputPin.unpin() - } - - inputPin.unpin() - } - - /** - * Consume [count] gzip-compressed bytes. - */ - fun consume(count: Int): ByteArray { - check(!isClosed) { "Compressor is closed" } - require(count in 0..availableForRead) { - "Count must be between 0 and $availableForRead, got $count" - } - - return outputBuffer.readByteArray(count.toLong()) - } - - /** - * Flush the compressor and return the terminal sequence of bytes that represent the end of the gzip compression. - */ - fun flush(): ByteArray { - check(!isClosed) { "Compressor is closed" } - - memScoped { - val compressionBuffer = ByteArray(BUFFER_SIZE) - var deflateResult: Int? = null - var outputLength = 0L - - do { - val outputPin = compressionBuffer.pin() - stream.next_out = outputPin.addressOf(0).reinterpret() - stream.avail_out = BUFFER_SIZE.toUInt() - - deflateResult = deflate(stream.ptr, Z_FINISH) - check(deflateResult == Z_OK || deflateResult == Z_STREAM_END) { "Deflate failed during finish with error code $deflateResult" } - - val bytesWritten = BUFFER_SIZE - stream.avail_out.toInt() - outputBuffer.write(compressionBuffer, 0, bytesWritten) - - outputLength += bytesWritten.toLong() - outputPin.unpin() - } while (deflateResult != Z_STREAM_END) - - return outputBuffer.readByteArray(outputLength) - } - } - - override fun close() { - if (isClosed) { - return - } - - deflateEnd(stream.ptr) - nativeHeap.free(stream.ptr) - isClosed = true - } -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipNative.kt index f82274317a..a9fc036399 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipNative.kt @@ -5,14 +5,6 @@ package aws.smithy.kotlin.runtime.compression import aws.smithy.kotlin.runtime.content.ByteStream -import aws.smithy.kotlin.runtime.content.asByteStream -import aws.smithy.kotlin.runtime.io.GzipByteReadChannel -import aws.smithy.kotlin.runtime.io.GzipSdkSource -import aws.smithy.kotlin.runtime.io.SdkByteReadChannel -import aws.smithy.kotlin.runtime.io.SdkSource -import aws.smithy.kotlin.runtime.io.buffer -import aws.smithy.kotlin.runtime.io.source -import aws.smithy.kotlin.runtime.io.use /** * The gzip compression algorithm. @@ -21,31 +13,12 @@ import aws.smithy.kotlin.runtime.io.use * See: https://en.wikipedia.org/wiki/Gzip */ public actual class Gzip : CompressionAlgorithm { - actual override val id: String = "gzip" - actual override val contentEncoding: String = "gzip" + actual override val id: String + get() = TODO("Not yet implemented") + actual override val contentEncoding: String + get() = TODO("Not yet implemented") - actual override fun compress(stream: ByteStream): ByteStream = when (stream) { - is ByteStream.ChannelStream -> object : ByteStream.ChannelStream() { - override fun readFrom(): SdkByteReadChannel = GzipByteReadChannel(stream.readFrom()) - override val contentLength: Long? = null - override val isOneShot: Boolean = stream.isOneShot - } - - is ByteStream.SourceStream -> object : ByteStream.SourceStream() { - override fun readFrom(): SdkSource = GzipSdkSource(stream.readFrom()) - override val contentLength: Long? = null - override val isOneShot: Boolean = stream.isOneShot - } - - is ByteStream.Buffer -> { - val bytes = stream.bytes() - if (bytes.isEmpty()) { - stream - } else { - GzipSdkSource(bytes.source()).use { - it.buffer().readByteArray().asByteStream() - } - } - } + actual override fun compress(stream: ByteStream): ByteStream { + TODO("Not yet implemented") } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsNative.kt deleted file mode 100644 index 185019607e..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/compression/GzipTestUtilsNative.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.compression - -import aws.smithy.kotlin.runtime.InternalApi -import kotlinx.cinterop.ExperimentalForeignApi -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.alloc -import kotlinx.cinterop.memScoped -import kotlinx.cinterop.pin -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.sizeOf -import kotlinx.cinterop.toKString -import platform.zlib.* - -/** - * Decompresses a byte array compressed using the gzip format - */ -@OptIn(ExperimentalForeignApi::class) -@InternalApi -public actual fun decompressGzipBytes(bytes: ByteArray): ByteArray { - if (bytes.isEmpty()) { - return bytes - } - - val decompressedBuffer = UByteArray(bytes.size * 2).pin() - - memScoped { - val zStream = alloc() - - // Initialize the inflate context for gzip decoding - val result = inflateInit2_( - strm = zStream.ptr, - windowBits = 31, - version = ZLIB_VERSION, - stream_size = sizeOf().toInt(), - ) - if (result != Z_OK) { - throw IllegalStateException("inflateInit2_ failed with error code $result") - } - - try { - val bytesPinned = bytes.pin() - - zStream.next_in = bytesPinned.addressOf(0).getPointer(memScope).reinterpret() - zStream.avail_in = bytes.size.toUInt() - - val output = mutableListOf() - while (zStream.avail_in > 0u) { - zStream.next_out = decompressedBuffer.addressOf(0) - zStream.avail_out = decompressedBuffer.get().size.toUInt() - - val inflateResult = inflate(zStream.ptr, Z_NO_FLUSH) - - when (inflateResult) { - Z_OK, Z_STREAM_END -> { - val chunkSize = decompressedBuffer.get().size.toUInt() - zStream.avail_out - output.addAll(decompressedBuffer.get().copyOf(chunkSize.toInt())) - } - else -> { - throw IllegalStateException("Decompression failed with error code $inflateResult: ${zError(inflateResult)!!.toKString()}") - } - } - - if (inflateResult == Z_STREAM_END) { - break - } - } - - return output.toUByteArray().toByteArray() - } finally { - inflateEnd(zStream.ptr) - } - } -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigDecimalNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigDecimalNative.kt index b22085d029..202cebe004 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigDecimalNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigDecimalNative.kt @@ -4,53 +4,46 @@ */ package aws.smithy.kotlin.runtime.content -import com.ionspin.kotlin.bignum.decimal.BigDecimal as IonSpinBigDecimal - -public actual class BigDecimal private constructor(private val delegate: IonSpinBigDecimal) : +public actual class BigDecimal actual constructor(value: String) : Number(), Comparable { + public actual fun toPlainString(): String { + TODO("Not yet implemented") + } - private companion object { - /** - * Returns a new or existing [BigDecimal] wrapper for the given delegate [value] - * @param value The delegate value to wrap - * @param left A candidate wrapper which may already contain [value] - * @param right A candidate wrapper which may already contain [value] - */ - fun coalesceOrCreate(value: IonSpinBigDecimal, left: BigDecimal, right: BigDecimal): BigDecimal = when (value) { - left.delegate -> left - right.delegate -> right - else -> BigDecimal(value) - } + actual override fun toByte(): Byte { + TODO("Not yet implemented") } - public actual constructor(value: String) : this(IonSpinBigDecimal.parseString(value, 10)) + actual override fun toDouble(): Double { + TODO("Not yet implemented") + } - public actual constructor(mantissa: BigInteger, exponent: Int) : - this(IonSpinBigDecimal.fromBigIntegerWithExponent(mantissa.delegate, exponent.toLong())) + actual override fun toFloat(): Float { + TODO("Not yet implemented") + } - actual override fun toByte(): Byte = delegate.byteValue(exactRequired = false) - actual override fun toDouble(): Double = delegate.doubleValue(exactRequired = false) - actual override fun toFloat(): Float = delegate.floatValue(exactRequired = false) - actual override fun toInt(): Int = delegate.intValue(exactRequired = false) - actual override fun toLong(): Long = delegate.longValue(exactRequired = false) - actual override fun toShort(): Short = delegate.shortValue(exactRequired = false) + actual override fun toInt(): Int { + TODO("Not yet implemented") + } + + actual override fun toLong(): Long { + TODO("Not yet implemented") + } + + actual override fun toShort(): Short { + TODO("Not yet implemented") + } public actual val mantissa: BigInteger - get() = BigInteger(delegate.significand) + get() = TODO("Not yet implemented") public actual val exponent: Int - get() = delegate.exponent.toInt() + get() = TODO("Not yet implemented") - actual override fun compareTo(other: BigDecimal): Int = delegate.compare(other.delegate) - actual override fun equals(other: Any?): Boolean = other is BigDecimal && other.delegate == delegate - actual override fun hashCode(): Int = 31 + delegate.hashCode() - public actual fun toPlainString(): String = delegate.toPlainString() - actual override fun toString(): String = delegate.toString() - - public actual operator fun plus(other: BigDecimal): BigDecimal = - coalesceOrCreate(delegate + other.delegate, this, other) + public actual constructor(mantissa: BigInteger, exponent: Int) : this("TODO(Not yet implemented)") { + TODO("Not yet implemented") + } - public actual operator fun minus(other: BigDecimal): BigDecimal = - coalesceOrCreate(delegate - other.delegate, this, other) + actual override fun compareTo(other: BigDecimal): Int = TODO("Not yet implemented") } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigIntegerNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigIntegerNative.kt index 09674a0d21..5ddee8af74 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigIntegerNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/content/BigIntegerNative.kt @@ -4,48 +4,37 @@ */ package aws.smithy.kotlin.runtime.content -import com.ionspin.kotlin.bignum.integer.util.fromTwosComplementByteArray -import com.ionspin.kotlin.bignum.integer.util.toTwosComplementByteArray -import com.ionspin.kotlin.bignum.integer.BigInteger as IonSpinBigInteger - -public actual class BigInteger internal constructor(internal val delegate: IonSpinBigInteger) : +public actual class BigInteger actual constructor(value: String) : Number(), Comparable { + public actual constructor(bytes: ByteArray) : this("Not yet implemented") - private companion object { - /** - * Returns a new or existing [BigInteger] wrapper for the given delegate [value] - * @param value The delegate value to wrap - * @param left A candidate wrapper which may already contain [value] - * @param right A candidate wrapper which may already contain [value] - */ - fun coalesceOrCreate(value: IonSpinBigInteger, left: BigInteger, right: BigInteger): BigInteger = when (value) { - left.delegate -> left - right.delegate -> right - else -> BigInteger(value) - } + actual override fun toByte(): Byte { + TODO("Not yet implemented") } - public actual constructor(value: String) : this(IonSpinBigInteger.parseString(value, 10)) - public actual constructor(bytes: ByteArray) : this(IonSpinBigInteger.fromTwosComplementByteArray(bytes)) + actual override fun toDouble(): Double { + TODO("Not yet implemented") + } - public actual override fun toByte(): Byte = delegate.byteValue(exactRequired = false) - public actual override fun toDouble(): Double = delegate.doubleValue(exactRequired = false) - public actual override fun toFloat(): Float = delegate.floatValue(exactRequired = false) - public actual override fun toInt(): Int = delegate.intValue(exactRequired = false) - public actual override fun toLong(): Long = delegate.longValue(exactRequired = false) - public actual override fun toShort(): Short = delegate.shortValue(exactRequired = false) + actual override fun toFloat(): Float { + TODO("Not yet implemented") + } - public actual operator fun plus(other: BigInteger): BigInteger = - coalesceOrCreate(delegate + other.delegate, this, other) + actual override fun toInt(): Int { + TODO("Not yet implemented") + } - public actual operator fun minus(other: BigInteger): BigInteger = - coalesceOrCreate(delegate - other.delegate, this, other) + actual override fun toLong(): Long { + TODO("Not yet implemented") + } + + actual override fun toShort(): Short { + TODO("Not yet implemented") + } - public actual fun toByteArray(): ByteArray = delegate.toTwosComplementByteArray() - public actual override fun compareTo(other: BigInteger): Int = delegate.compare(other.delegate) - public actual override fun equals(other: Any?): Boolean = other is BigInteger && other.delegate == delegate - public actual override fun hashCode(): Int = 17 + delegate.hashCode() - public actual override fun toString(): String = toString(10) - public actual fun toString(radix: Int): String = delegate.toString(radix) + public actual operator fun plus(other: BigInteger): BigInteger = TODO("Not yet implemented") + public actual operator fun minus(other: BigInteger): BigInteger = TODO("Not yet implemented") + public actual fun toByteArray(): ByteArray = TODO("Not yet implemented") + actual override fun compareTo(other: BigInteger): Int = TODO("Not yet implemented") } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Crc32Native.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Crc32Native.kt index ef86e4e519..2c40576e88 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Crc32Native.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Crc32Native.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.hashing import aws.smithy.kotlin.runtime.InternalApi -import aws.sdk.kotlin.crt.util.hashing.Crc32 as CrtCrc32 /** * CRC-32 checksum. Note: [digest] will return the bytes (big endian) of the CRC32 integer value. Access [digestValue] @@ -13,16 +12,15 @@ import aws.sdk.kotlin.crt.util.hashing.Crc32 as CrtCrc32 */ @InternalApi public actual class Crc32 actual constructor() : Crc32Base() { - private val delegate = CrtCrc32() - actual override fun digestValue(): UInt { - val bytes = delegate.digest() - return ((bytes[0].toUInt() and 0xffu) shl 24) or - ((bytes[1].toUInt() and 0xffu) shl 16) or - ((bytes[2].toUInt() and 0xffu) shl 8) or - (bytes[3].toUInt() and 0xffu) + TODO("Not yet implemented") + } + + actual override fun update(input: ByteArray, offset: Int, length: Int) { + TODO("Not yet implemented") } - actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = delegate.update(input, offset, length) - actual override fun reset(): Unit = delegate.reset() + actual override fun reset() { + TODO("Not yet implemented") + } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt index 112b60df14..a2bca1c4e6 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt @@ -4,7 +4,10 @@ */ package aws.smithy.kotlin.runtime.hashing +// FIXME Implement using aws-c-cal: https://github.com/awslabs/aws-c-cal/blob/main/include/aws/cal/ecc.h +// Will need to be implemented and exposed in aws-crt-kotlin. Or maybe we can _only_ offer the CRT signer on Native? +// Will require updating DefaultAwsSigner to be expect/actual and set to CrtSigner on Native. /** * ECDSA on the SECP256R1 curve. */ -public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = error("This function should not be invoked on Native, which uses the CrtAwsSigner.") +public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = TODO("Not yet implemented") diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Md5Native.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Md5Native.kt index efff134fc8..9614543dad 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Md5Native.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Md5Native.kt @@ -5,15 +5,21 @@ package aws.smithy.kotlin.runtime.hashing import aws.smithy.kotlin.runtime.InternalApi -import aws.sdk.kotlin.crt.util.hashing.Md5 as CrtMd5 /** * Implementation of RFC1321 MD5 digest */ @InternalApi public actual class Md5 actual constructor() : Md5Base() { - private val delegate = CrtMd5() - actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = delegate.update(input, offset, length) - actual override fun digest(): ByteArray = delegate.digest() - actual override fun reset(): Unit = delegate.reset() + actual override fun update(input: ByteArray, offset: Int, length: Int) { + TODO("Not yet implemented") + } + + actual override fun digest(): ByteArray { + TODO("Not yet implemented") + } + + actual override fun reset() { + TODO("Not yet implemented") + } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha1Native.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha1Native.kt index 541b25246f..6a4f4e1abc 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha1Native.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha1Native.kt @@ -5,16 +5,21 @@ package aws.smithy.kotlin.runtime.hashing import aws.smithy.kotlin.runtime.InternalApi -import aws.sdk.kotlin.crt.util.hashing.Sha1 as CrtSha1 /** * Implementation of SHA-1 (Secure Hash Algorithm 1) hash function. See: https://csrc.nist.gov/projects/hash-functions */ @InternalApi public actual class Sha1 actual constructor() : Sha1Base() { - private val delegate = CrtSha1() + actual override fun update(input: ByteArray, offset: Int, length: Int) { + TODO("Not yet implemented") + } - actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = delegate.update(input, offset, length) - actual override fun digest(): ByteArray = delegate.digest() - actual override fun reset(): Unit = delegate.reset() + actual override fun digest(): ByteArray { + TODO("Not yet implemented") + } + + actual override fun reset() { + TODO("Not yet implemented") + } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha256Native.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha256Native.kt index 69a82d4664..6c85dfccea 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha256Native.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/Sha256Native.kt @@ -5,12 +5,10 @@ package aws.smithy.kotlin.runtime.hashing import aws.smithy.kotlin.runtime.InternalApi -import aws.sdk.kotlin.crt.util.hashing.Sha256 as CrtSha256 @InternalApi public actual class Sha256 : Sha256Base() { - private val delegate = CrtSha256() - actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = delegate.update(input, offset, length) - actual override fun digest(): ByteArray = delegate.digest() - actual override fun reset(): Unit = delegate.reset() + actual override fun update(input: ByteArray, offset: Int, length: Int): Unit = TODO("native not supported") + actual override fun digest(): ByteArray = TODO("native not supported") + actual override fun reset(): Unit = TODO("native not supported") } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt index bf5767cf35..48f9badc3a 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt @@ -4,6 +4,67 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : - AbstractBufferedSinkAdapter(sink), - SdkBufferedSink +internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : SdkBufferedSink { + actual override val buffer: SdkBuffer + get() = TODO("Not yet implemented") + + actual override fun write(source: ByteArray, offset: Int, limit: Int) { + TODO("Not yet implemented") + } + + actual override fun writeAll(source: SdkSource): Long { + TODO("Not yet implemented") + } + + actual override fun write(source: SdkSource, byteCount: Long) { + TODO("Not yet implemented") + } + + actual override fun writeUtf8(string: String, start: Int, endExclusive: Int) { + TODO("Not yet implemented") + } + + actual override fun writeByte(x: Byte) { + TODO("Not yet implemented") + } + + actual override fun writeShort(x: Short) { + TODO("Not yet implemented") + } + + actual override fun writeShortLe(x: Short) { + TODO("Not yet implemented") + } + + actual override fun writeInt(x: Int) { + TODO("Not yet implemented") + } + + actual override fun writeIntLe(x: Int) { + TODO("Not yet implemented") + } + + actual override fun writeLong(x: Long) { + TODO("Not yet implemented") + } + + actual override fun writeLongLe(x: Long) { + TODO("Not yet implemented") + } + + actual override fun flush() { + TODO("Not yet implemented") + } + + actual override fun emit() { + TODO("Not yet implemented") + } + + actual override fun write(source: SdkBuffer, byteCount: Long) { + TODO("Not yet implemented") + } + + actual override fun close() { + TODO("Not yet implemented") + } +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt index 437b018606..cfa9d4c76f 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt @@ -4,6 +4,87 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : - AbstractBufferedSourceAdapter(source), - SdkBufferedSource +internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : SdkBufferedSource { + actual override val buffer: SdkBuffer + get() = TODO("Not yet implemented") + + actual override fun skip(byteCount: Long) { + TODO("Not yet implemented") + } + + actual override fun readByte(): Byte { + TODO("Not yet implemented") + } + + actual override fun readShort(): Short { + TODO("Not yet implemented") + } + + actual override fun readShortLe(): Short { + TODO("Not yet implemented") + } + + actual override fun readLong(): Long { + TODO("Not yet implemented") + } + + actual override fun readLongLe(): Long { + TODO("Not yet implemented") + } + + actual override fun readInt(): Int { + TODO("Not yet implemented") + } + + actual override fun readIntLe(): Int { + TODO("Not yet implemented") + } + + actual override fun readAll(sink: SdkSink): Long { + TODO("Not yet implemented") + } + + actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int { + TODO("Not yet implemented") + } + + actual override fun readByteArray(): ByteArray { + TODO("Not yet implemented") + } + + actual override fun readByteArray(byteCount: Long): ByteArray { + TODO("Not yet implemented") + } + + actual override fun readUtf8(): String { + TODO("Not yet implemented") + } + + actual override fun readUtf8(byteCount: Long): String { + TODO("Not yet implemented") + } + + actual override fun peek(): SdkBufferedSource { + TODO("Not yet implemented") + } + + actual override fun exhausted(): Boolean { + TODO("Not yet implemented") + } + + actual override fun request(byteCount: Long): Boolean { + TODO("Not yet implemented") + } + + actual override fun require(byteCount: Long) { + TODO("Not yet implemented") + } + + actual override fun read(sink: SdkBuffer, limit: Long): Long { + TODO("Not yet implemented") + } + + actual override fun close() { + TODO("Not yet implemented") + } +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt index 631e84c1bf..a5265fbb64 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt @@ -12,7 +12,6 @@ public actual open class IOException actual constructor( public actual constructor(message: String?) : this(message, null) } -public actual open class EOFException actual constructor(message: String?, cause: Throwable?) : IOException(message, cause) { - public actual constructor() : this(null, null) - public actual constructor(message: String?) : this(message, null) +public actual open class EOFException actual constructor(message: String?) : IOException(message) { + public actual constructor() : this(null) } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipByteReadChannelNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipByteReadChannelNative.kt index 4fadeacbb9..f8ca725e14 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipByteReadChannelNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipByteReadChannelNative.kt @@ -5,62 +5,26 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.compression.GzipCompressor /** - * Wraps an [SdkByteReadChannel], compressing bytes read into GZIP format. - * @param channel the [SdkByteReadChannel] to compress the contents of + * Wraps the SdkByteReadChannel so that it compresses into gzip format with each read. */ @InternalApi -public actual class GzipByteReadChannel actual constructor(public val channel: SdkByteReadChannel) : SdkByteReadChannel { - private val compressor = GzipCompressor() - +public actual class GzipByteReadChannel actual constructor(channel: SdkByteReadChannel) : SdkByteReadChannel { actual override val availableForRead: Int - get() = compressor.availableForRead - + get() = TODO("Not yet implemented") actual override val isClosedForRead: Boolean - get() = channel.isClosedForRead && compressor.isClosed - + get() = TODO("Not yet implemented") actual override val isClosedForWrite: Boolean - get() = channel.isClosedForWrite - + get() = TODO("Not yet implemented") actual override val closedCause: Throwable? - get() = channel.closedCause + get() = TODO("Not yet implemented") actual override suspend fun read(sink: SdkBuffer, limit: Long): Long { - require(limit >= 0L) - if (limit == 0L) return 0L - if (compressor.isClosed) return -1L - - // If no compressed bytes are available, attempt to refill the compressor - if (compressor.availableForRead == 0 && !channel.isClosedForRead) { - val temp = SdkBuffer() - val rc = channel.read(temp, GzipCompressor.BUFFER_SIZE.toLong()) - - if (rc > 0) { - val input = temp.readByteArray(rc) - compressor.update(input) - } - } - - // If still no data is available and the channel is closed, we've hit EOF. Close the compressor and write the remaining bytes - if (compressor.availableForRead == 0 && channel.isClosedForRead) { - val terminationBytes = compressor.flush() - sink.write(terminationBytes) - return terminationBytes.size.toLong().also { - compressor.close() - } - } - - // Read compressed bytes from the compressor - val bytesToRead = minOf(limit, compressor.availableForRead.toLong()) - val compressed = compressor.consume(bytesToRead.toInt()) - sink.write(compressed) - return compressed.size.toLong() + TODO("Not yet implemented") } actual override fun cancel(cause: Throwable?): Boolean { - compressor.close() - return channel.cancel(cause) + TODO("Not yet implemented") } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipSdkSourceNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipSdkSourceNative.kt index 39055dd4d9..f38cfd45d1 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipSdkSourceNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/GzipSdkSourceNative.kt @@ -5,50 +5,17 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.compression.GzipCompressor /** - * Wraps an [SdkSource], compressing bytes read into GZIP format. - * @param source the [SdkSource] to compress the contents of + * Wraps the SdkSource so that it compresses into gzip format with each read. */ @InternalApi -public actual class GzipSdkSource actual constructor(public val source: SdkSource) : SdkSource { - private val compressor = GzipCompressor() - +public actual class GzipSdkSource actual constructor(source: SdkSource) : SdkSource { actual override fun read(sink: SdkBuffer, limit: Long): Long { - require(limit >= 0L) - if (limit == 0L) return 0L - if (compressor.isClosed) return -1L - - // If no compressed bytes are available, attempt to refill the compressor - if (compressor.availableForRead == 0) { - val temp = SdkBuffer() - val rc = source.read(temp, GzipCompressor.BUFFER_SIZE.toLong()) - - if (rc > 0) { - val input = temp.readByteArray(rc) - compressor.update(input) - } - } - - // If still no data is available, we've hit EOF. Close the compressor and write the remaining bytes - if (compressor.availableForRead == 0) { - val terminationBytes = compressor.flush() - sink.write(terminationBytes) - return terminationBytes.size.toLong().also { - compressor.close() - } - } - - // Read compressed bytes from the compressor - val bytesToRead = minOf(limit, compressor.availableForRead.toLong()) - val compressed = compressor.consume(bytesToRead.toInt()) - sink.write(compressed) - return compressed.size.toLong() + TODO("Not yet implemented") } actual override fun close() { - compressor.close() - source.close() + TODO("Not yet implemented") } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt index 616ef39a76..e8bee2b911 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt @@ -4,103 +4,157 @@ */ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.io.internal.* +import okio.Buffer -// FIXME Commonize with JVM after removing WritableByteStream / ReadableByteStream in 1.6.x public actual class SdkBuffer : SdkBufferedSource, SdkBufferedSink { - public actual constructor() : this(okio.Buffer()) + public actual val size: Long + get() = TODO("Not yet implemented") - internal actual val inner: okio.Buffer + public actual constructor() - internal actual constructor(buffer: okio.Buffer) { - this.inner = buffer - } + internal actual val inner: okio.Buffer + get() = TODO("Not yet implemented") - public actual val size: Long - get() = inner.size + internal actual constructor(buffer: okio.Buffer) actual override val buffer: SdkBuffer - get() = this - - override fun toString(): String = inner.toString() + get() = TODO("Not yet implemented") - override fun hashCode(): Int = inner.hashCode() - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is SdkBuffer) return false - return inner == other.inner + actual override fun write(source: ByteArray, offset: Int, limit: Int) { + TODO("Not yet implemented") } - actual override fun write(source: SdkBuffer, byteCount: Long): Unit = commonWrite(source, byteCount) - - actual override fun write(source: ByteArray, offset: Int, limit: Int): Unit = commonWrite(source, offset, limit) - - actual override fun write(source: SdkSource, byteCount: Long): Unit = commonWrite(source, byteCount) + actual override fun writeAll(source: SdkSource): Long { + TODO("Not yet implemented") + } - actual override fun writeAll(source: SdkSource): Long = commonWriteAll(source) + actual override fun write(source: SdkSource, byteCount: Long) { + TODO("Not yet implemented") + } - actual override fun writeUtf8(string: String, start: Int, endExclusive: Int): Unit = commonWriteUtf8(string, start, endExclusive) + actual override fun writeUtf8(string: String, start: Int, endExclusive: Int) { + TODO("Not yet implemented") + } - actual override fun writeByte(x: Byte): Unit = commonWriteByte(x) + actual override fun writeByte(x: Byte) { + TODO("Not yet implemented") + } - actual override fun writeShort(x: Short): Unit = commonWriteShort(x) + actual override fun writeShort(x: Short) { + TODO("Not yet implemented") + } - actual override fun writeShortLe(x: Short): Unit = commonWriteShortLe(x) + actual override fun writeShortLe(x: Short) { + TODO("Not yet implemented") + } - actual override fun writeInt(x: Int): Unit = commonWriteInt(x) + actual override fun writeInt(x: Int) { + TODO("Not yet implemented") + } - actual override fun writeIntLe(x: Int): Unit = commonWriteIntLe(x) + actual override fun writeIntLe(x: Int) { + TODO("Not yet implemented") + } - actual override fun writeLong(x: Long): Unit = commonWriteLong(x) + actual override fun writeLong(x: Long) { + TODO("Not yet implemented") + } - actual override fun writeLongLe(x: Long): Unit = commonWriteLongLe(x) + actual override fun writeLongLe(x: Long) { + TODO("Not yet implemented") + } - actual override fun flush(): Unit = commonFlush() + actual override fun flush() { + TODO("Not yet implemented") + } actual override fun emit() { - wrapOkio { inner.emit() } + TODO("Not yet implemented") + } + + actual override fun skip(byteCount: Long) { + TODO("Not yet implemented") } - actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount) + actual override fun readByte(): Byte { + TODO("Not yet implemented") + } - actual override fun readByte(): Byte = commonReadByte() + actual override fun readShort(): Short { + TODO("Not yet implemented") + } - actual override fun readShort(): Short = commonReadShort() + actual override fun readShortLe(): Short { + TODO("Not yet implemented") + } - actual override fun readShortLe(): Short = commonReadShortLe() + actual override fun readLong(): Long { + TODO("Not yet implemented") + } - actual override fun readLong(): Long = commonReadLong() + actual override fun readLongLe(): Long { + TODO("Not yet implemented") + } - actual override fun readLongLe(): Long = commonReadLongLe() + actual override fun readInt(): Int { + TODO("Not yet implemented") + } - actual override fun readInt(): Int = commonReadInt() + actual override fun readIntLe(): Int { + TODO("Not yet implemented") + } - actual override fun readIntLe(): Int = commonReadIntLe() + actual override fun readAll(sink: SdkSink): Long { + TODO("Not yet implemented") + } - actual override fun readAll(sink: SdkSink): Long = commonReadAll(sink) + actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int { + TODO("Not yet implemented") + } - actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int = commonRead(sink, offset, limit) + actual override fun readByteArray(): ByteArray { + TODO("Not yet implemented") + } - actual override fun readByteArray(): ByteArray = commonReadByteArray() + actual override fun readByteArray(byteCount: Long): ByteArray { + TODO("Not yet implemented") + } - actual override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount) + actual override fun readUtf8(): String { + TODO("Not yet implemented") + } - actual override fun readUtf8(): String = commonReadUtf8() + actual override fun readUtf8(byteCount: Long): String { + TODO("Not yet implemented") + } - actual override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount) + actual override fun peek(): SdkBufferedSource { + TODO("Not yet implemented") + } - actual override fun peek(): SdkBufferedSource = commonPeek() + actual override fun exhausted(): Boolean { + TODO("Not yet implemented") + } - actual override fun exhausted(): Boolean = commonExhausted() + actual override fun request(byteCount: Long): Boolean { + TODO("Not yet implemented") + } - actual override fun request(byteCount: Long): Boolean = commonRequest(byteCount) + actual override fun require(byteCount: Long) { + TODO("Not yet implemented") + } - actual override fun require(byteCount: Long): Unit = commonRequire(byteCount) + actual override fun write(source: SdkBuffer, byteCount: Long) { + TODO("Not yet implemented") + } - actual override fun read(sink: SdkBuffer, limit: Long): Long = commonRead(sink, limit) + actual override fun read(sink: SdkBuffer, limit: Long): Long { + TODO("Not yet implemented") + } - actual override fun close(): Unit = commonClose() + actual override fun close() { + TODO("Not yet implemented") + } } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt new file mode 100644 index 0000000000..e7febda6d2 --- /dev/null +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt @@ -0,0 +1,27 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io + +import aws.smithy.kotlin.runtime.InternalApi +import kotlinx.coroutines.CoroutineScope + +/** + * Consume the [SdkSource] and pull the entire contents into memory as a [ByteArray]. + */ +@InternalApi +public actual suspend fun SdkSource.readToByteArray(): ByteArray { + TODO("Not yet implemented") +} + +/** + * Convert the [SdkSource] to an [SdkByteReadChannel]. Content is read from the source and forwarded + * to the channel. + * @param coroutineScope the coroutine scope to use to launch a background reader channel responsible for propagating data + * between source and the returned channel + */ +@InternalApi +public actual fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope?): SdkByteReadChannel { + TODO("Not yet implemented") +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt index de34d71300..e5b1309c5a 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt @@ -6,8 +6,6 @@ package aws.smithy.kotlin.runtime.io.internal import aws.smithy.kotlin.runtime.InternalApi import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO @InternalApi public actual object SdkDispatchers { @@ -15,5 +13,5 @@ public actual object SdkDispatchers { * The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads. */ public actual val IO: CoroutineDispatcher - get() = Dispatchers.IO + get() = TODO("Not yet implemented") } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/DefaultHostResolverNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/DefaultHostResolverNative.kt deleted file mode 100644 index a5ee1870d2..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/DefaultHostResolverNative.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.net - -import aws.sdk.kotlin.crt.io.CrtHostAddress -import aws.sdk.kotlin.crt.use -import aws.sdk.kotlin.crt.io.HostResolver as CrtHostResolver - -internal actual object DefaultHostResolver : HostResolver { - actual override suspend fun resolve(hostname: String): List { - val results = CrtHostResolver().use { - it.resolve(hostname) - } - return results.map { it.toHostAddress() } - } - - // No-op, matches JVM implementation - actual override fun purgeCache(addr: HostAddress?) { } - - // No-op, matches JVM implementation - actual override fun reportFailure(addr: HostAddress) { } - - private fun CrtHostAddress.toHostAddress() = HostAddress(host, IpAddr.parse(address)) -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/HostResolverNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/HostResolverNative.kt new file mode 100644 index 0000000000..4b8fd7e7ae --- /dev/null +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/net/HostResolverNative.kt @@ -0,0 +1,22 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.net + +import aws.smithy.kotlin.runtime.InternalApi + +internal actual object DefaultHostResolver : HostResolver { + actual override suspend fun resolve(hostname: String): List { + TODO("Not yet implemented") + } + + actual override fun reportFailure(addr: HostAddress) { + TODO("Not yet implemented") + } + + @InternalApi + actual override fun purgeCache(addr: HostAddress?) { + TODO("Not yet implemented") + } +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt deleted file mode 100644 index 550a95cfe1..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.time - -import kotlinx.datetime.LocalDate -import kotlinx.datetime.UtcOffset -import kotlinx.datetime.format.DateTimeComponents -import kotlinx.datetime.format.DateTimeFormat -import kotlinx.datetime.format.DayOfWeekNames -import kotlinx.datetime.format.MonthNames -import kotlinx.datetime.format.Padding -import kotlinx.datetime.format.alternativeParsing -import kotlinx.datetime.format.char -import kotlinx.datetime.format.optional - -/** - * [DateTimeFormat] for use with [kotlinx.datetime.Instant] - */ -internal object DateTimeFormats { - - /** - * ISO8601, full precision. Corresponds to [TimestampFormat.ISO_8601_FULL]. Truncate to microseconds for [TimestampFormat.ISO_8601]. - * e.g. "2020-11-05T19:22:37+00:00" - */ - val ISO_8601 = DateTimeComponents.Format { - // Two possible date formats: YYYY-MM-DD or YYYYMMDD - alternativeParsing({ - date( - LocalDate.Format { - year() - monthNumber() - dayOfMonth() - }, - ) - }) { - date( - LocalDate.Format { - year() - char('-') - monthNumber() - char('-') - dayOfMonth() - }, - ) - } - - char('T') - - // Two possible time formats: HH:MM:SS or HHMMSS - alternativeParsing({ - hour() - minute() - second() - }) { - hour() - char(':') - minute() - char(':') - second() - } - - // Fractional seconds - optional { - char('.') - secondFraction(1, 9) - } - - // Offsets - alternativeParsing({ - offsetHours() - }) { - offset(UtcOffset.Formats.ISO) - } - } - - /** - * ISO8601 condensed. Corresponds to [TimestampFormat.ISO_8601_CONDENSED]. - */ - val ISO_8601_CONDENSED = DateTimeComponents.Format { - year() - monthNumber() - dayOfMonth() - - char('T') - hour() - minute() - second() - char('Z') - } - - /** - * ISO8601 condensed, date only. Corresponds to [TimestampFormat.ISO_8601_CONDENSED_DATE] - */ - val ISO_8601_CONDENSED_DATE = DateTimeComponents.Format { - year() - monthNumber() - dayOfMonth() - } - - /** - * [RFC-5322/2822/822 IMF timestamp](https://tools.ietf.org/html/rfc5322). Corresponds to [TimestampFormat.RFC_5322]. - * e.g. "Thu, 05 Nov 2020 19:22:37 +0000" - */ - val RFC_5322 = DateTimeComponents.Format { - dayOfWeek(DayOfWeekNames.ENGLISH_ABBREVIATED) - chars(", ") - - alternativeParsing({ - dayOfMonth(padding = Padding.NONE) - }) { - dayOfMonth() - } - - char(' ') - monthName(MonthNames.ENGLISH_ABBREVIATED) - char(' ') - year() - char(' ') - - hour() - char(':') - minute() - char(':') - second() - char(' ') - - optional("GMT") { - offset(UtcOffset.Formats.FOUR_DIGITS) - } - } -} - -/** - * ISO8601 condensed, date only. Corresponds to [TimestampFormat.ISO_8601_CONDENSED_DATE]. - * Used only for _parsing_ ISO8601 condensed strings. Instant.parse() will fail if using [DateTimeFormats.ISO_8601_CONDENSED_DATE] - * because that is a [DateTimeFormat] which requires a time component to be present. - */ -internal val ISO_8601_CONDENSED_DATE_LOCALDATE = LocalDate.Format { - year() - monthNumber() - dayOfMonth() -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 01edcaf1af..00bc92f2fa 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -5,124 +5,91 @@ package aws.smithy.kotlin.runtime.time -import kotlinx.datetime.Clock -import kotlinx.datetime.LocalDate -import kotlinx.datetime.TimeZone -import kotlinx.datetime.atStartOfDayIn -import kotlinx.datetime.format import kotlin.time.Duration -import kotlinx.datetime.Instant as KtInstant -private fun TimestampFormat.asDateTimeFormat() = when (this) { - TimestampFormat.RFC_5322 -> DateTimeFormats.RFC_5322 - TimestampFormat.ISO_8601_FULL -> DateTimeFormats.ISO_8601 - TimestampFormat.ISO_8601_CONDENSED -> DateTimeFormats.ISO_8601_CONDENSED - TimestampFormat.ISO_8601_CONDENSED_DATE -> DateTimeFormats.ISO_8601_CONDENSED_DATE - else -> throw IllegalArgumentException("TimestampFormat $this could not be converted to a DateTimeFormat") -} - -private fun KtInstant.truncateToMicros(): KtInstant = KtInstant.fromEpochSeconds(epochSeconds, nanosecondsOfSecond / 1_000 * 1_000) - -public actual class Instant(internal val delegate: KtInstant) : Comparable { - - actual override fun compareTo(other: Instant): Int = delegate.compareTo(other.delegate) +public actual class Instant : Comparable { + actual override fun compareTo(other: Instant): Int { + TODO("Not yet implemented") + } - public actual val epochSeconds: Long = delegate.epochSeconds - public actual val nanosecondsOfSecond: Int = delegate.nanosecondsOfSecond + public actual val epochSeconds: Long + get() = TODO("Not yet implemented") + public actual val nanosecondsOfSecond: Int + get() = TODO("Not yet implemented") /** * Encode the [Instant] as a string into the format specified by [TimestampFormat] */ - public actual fun format(fmt: TimestampFormat): String = when (fmt) { - TimestampFormat.ISO_8601 -> delegate.truncateToMicros().format(DateTimeFormats.ISO_8601) - TimestampFormat.EPOCH_SECONDS -> { - val s = delegate.epochSeconds.toString() - val ns = if (delegate.nanosecondsOfSecond != 0) { - ".${delegate.nanosecondsOfSecond.toString().padStart(9, '0').trimEnd('0')}" - } else { - "" - } - s + ns - } - else -> delegate.format(fmt.asDateTimeFormat()) + public actual fun format(fmt: TimestampFormat): String { + TODO("Not yet implemented") } /** * Returns an instant that is the result of adding the specified [duration] to this instant. * NOTE: Duration may be negative in which case the returned Instant will be earlier than this Instant. */ - public actual operator fun plus(duration: Duration): Instant = Instant(delegate + duration) + public actual operator fun plus(duration: Duration): Instant { + TODO("Not yet implemented") + } /** * Returns an instant that is the result of subtracting the specified [duration] from this instant. * NOTE: Duration may be negative in which case the returned Instant will be later than this Instant. */ - public actual operator fun minus(duration: Duration): Instant = Instant(delegate - duration) + public actual operator fun minus(duration: Duration): Instant { + TODO("Not yet implemented") + } - public actual operator fun minus(other: Instant): Duration = delegate - other.delegate + public actual operator fun minus(other: Instant): Duration { + TODO("Not yet implemented") + } public actual companion object { /** * Parse an ISO-8601 formatted string into an [Instant] */ public actual fun fromIso8601(ts: String): Instant { - val parseException = ParseException(ts, "Failed to parse $ts into an ISO-8601 timestamp", 0) - - listOf( - { DateTimeFormats.ISO_8601.parse(ts).apply { if (second == 60) second = 59 }.toInstantUsingOffset() }, - { KtInstant.parse(ts, DateTimeFormats.ISO_8601_CONDENSED) }, - { LocalDate.parse(ts, ISO_8601_CONDENSED_DATE_LOCALDATE).atStartOfDayIn(TimeZone.UTC) }, - ).forEach { parseFn -> - try { - return Instant(parseFn()) - } catch (e: IllegalArgumentException) { - parseException.addSuppressed(e) - } - } - - throw parseException + TODO("Not yet implemented") } /** * Parse an RFC5322/RFC-822 formatted string into an [Instant] */ - public actual fun fromRfc5322(ts: String): Instant = try { - Instant(KtInstant.parse(ts, DateTimeFormats.RFC_5322)) - } catch (e: IllegalArgumentException) { - throw ParseException(ts, "Failed to parse $ts into an RFC-5322 timestamp", 0) + public actual fun fromRfc5322(ts: String): Instant { + TODO("Not yet implemented") } /** * Create an [Instant] from its parts */ - public actual fun fromEpochSeconds(seconds: Long, ns: Int): Instant = try { - Instant(KtInstant.fromEpochSeconds(seconds, ns)) - } catch (e: IllegalArgumentException) { - throw ParseException("${seconds}s, ${ns}ns", "Failed to parse (${seconds}s, ${ns}ns) into an epoch seconds timestamp", 0) + public actual fun fromEpochSeconds(seconds: Long, ns: Int): Instant { + TODO("Not yet implemented") } /** * Parse a string formatted as epoch-seconds into an [Instant] */ - public actual fun fromEpochSeconds(ts: String): Instant = fromEpochSeconds(ts.toLong(), 0) + public actual fun fromEpochSeconds(ts: String): Instant { + TODO("Not yet implemented") + } /** * Create an [Instant] from the current system time */ - public actual fun now(): Instant = Instant(Clock.System.now()) + public actual fun now(): Instant { + TODO("Not yet implemented") + } /** * Create an [Instant] with the minimum possible value */ - public actual val MIN_VALUE: Instant = Instant(KtInstant.DISTANT_PAST) + public actual val MIN_VALUE: Instant + get() = TODO("Not yet implemented") /** * Create an [Instant] with the maximum possible value */ - public actual val MAX_VALUE: Instant = Instant(KtInstant.DISTANT_FUTURE) + public actual val MAX_VALUE: Instant + get() = TODO("Not yet implemented") } - - public override fun equals(other: Any?): Boolean = other is Instant && delegate == other.delegate - public override fun toString(): String = delegate.toString() - public override fun hashCode(): Int = delegate.hashCode() } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/PlatformNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/PlatformNative.kt new file mode 100644 index 0000000000..bb435ccaea --- /dev/null +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/PlatformNative.kt @@ -0,0 +1,53 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.util + +internal actual object SystemDefaultProvider : PlatformProvider { + actual override fun getAllEnvVars(): Map { + TODO("Not yet implemented") + } + + actual override fun getenv(key: String): String? { + TODO("Not yet implemented") + } + + actual override val filePathSeparator: String + get() = TODO("Not yet implemented") + + actual override suspend fun readFileOrNull(path: String): ByteArray? { + TODO("Not yet implemented") + } + + actual override suspend fun writeFile(path: String, data: ByteArray) { + TODO("Not yet implemented") + } + + actual override fun fileExists(path: String): Boolean { + TODO("Not yet implemented") + } + + actual override fun osInfo(): OperatingSystem { + TODO("Not yet implemented") + } + + actual override val isJvm: Boolean + get() = TODO("Not yet implemented") + actual override val isAndroid: Boolean + get() = TODO("Not yet implemented") + actual override val isBrowser: Boolean + get() = TODO("Not yet implemented") + actual override val isNode: Boolean + get() = TODO("Not yet implemented") + actual override val isNative: Boolean + get() = TODO("Not yet implemented") + + actual override fun getAllProperties(): Map { + TODO("Not yet implemented") + } + + actual override fun getProperty(key: String): String? { + TODO("Not yet implemented") + } +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderBase.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderBase.kt deleted file mode 100644 index 1bee4e4ff2..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderBase.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.util - -import aws.smithy.kotlin.runtime.io.IOException -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers -import kotlinx.cinterop.* -import kotlinx.coroutines.withContext -import platform.posix.* - -@OptIn(ExperimentalForeignApi::class) -public abstract class SystemDefaultProviderBase : PlatformProvider { - override fun getenv(key: String): String? = platform.posix.getenv(key)?.toKString() - - override suspend fun readFileOrNull(path: String): ByteArray? = withContext(SdkDispatchers.IO) { - try { - val size = memScoped { - val statResult = alloc() - if (stat(path, statResult.ptr) != 0) return@withContext null - @OptIn(UnsafeNumber::class) - statResult.st_size.convert() - } - - val file = fopen(path, "rb") ?: return@withContext null - - try { - // Read file content - val buffer = ByteArray(size).pin() - val rc = fread(buffer.addressOf(0), 1uL, size.toULong(), file) - if (rc == size.toULong()) buffer.get() else null - } finally { - fclose(file) - } - } catch (_: Exception) { - null - } - } - - override suspend fun writeFile(path: String, data: ByteArray): Unit = withContext(SdkDispatchers.IO) { - val file = fopen(path, "wb") ?: throw IOException("Cannot open file for writing: $path") - try { - val wc = fwrite(data.refTo(0), 1uL, data.size.toULong(), file) - if (wc != data.size.toULong()) { - throw IOException("Failed to write all bytes to file $path, expected ${data.size.toLong()}, wrote $wc") - } - } finally { - fclose(file) - } - } - - override fun fileExists(path: String): Boolean = access(path, F_OK) == 0 - - override val isJvm: Boolean = false - override val isAndroid: Boolean = false - override val isBrowser: Boolean = false - override val isNode: Boolean = false - override val isNative: Boolean = true - - // Kotlin/Native doesn't have system properties - override fun getAllProperties(): Map = emptyMap() - override fun getProperty(key: String): String? = null -} diff --git a/runtime/runtime-core/native/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsNative.kt b/runtime/runtime-core/native/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsNative.kt new file mode 100644 index 0000000000..198808f770 --- /dev/null +++ b/runtime/runtime-core/native/test/aws/smithy/kotlin/runtime/io/GzipTestUtilsNative.kt @@ -0,0 +1,12 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io + +/** + * Decompresses a byte array compressed using the gzip format + */ +internal actual fun decompressGzipBytes(bytes: ByteArray): ByteArray { + TODO("Not yet implemented") +} diff --git a/runtime/runtime-core/posix/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderPosix.kt b/runtime/runtime-core/posix/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderPosix.kt deleted file mode 100644 index 9c1010c6b0..0000000000 --- a/runtime/runtime-core/posix/src/aws/smithy/kotlin/runtime/util/SystemDefaultProviderPosix.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.util - -import aws.smithy.platform.posix.get_environ_ptr -import kotlinx.cinterop.* -import platform.posix.uname -import platform.posix.utsname - -@OptIn(ExperimentalForeignApi::class) -public actual object SystemDefaultProvider : SystemDefaultProviderBase() { - actual override val filePathSeparator: String = "/" - - actual override fun osInfo(): OperatingSystem = memScoped { - val utsname = alloc() - uname(utsname.ptr) - - val sysName = utsname.sysname.toKString().lowercase() - val version = utsname.release.toKString() - val machine = utsname.machine.toKString().lowercase() // Helps differentiate Apple platforms - - val family = when { - sysName.contains("darwin") -> { - when { - machine.startsWith("iphone") -> OsFamily.Ios - // TODO Validate that iPadOS/tvOS/watchOS resolves correctly on each of these devices - machine.startsWith("ipad") -> OsFamily.IpadOs - machine.startsWith("tv") -> OsFamily.TvOs - machine.startsWith("watch") -> OsFamily.WatchOs - else -> OsFamily.MacOs - } - } - sysName.contains("linux") -> OsFamily.Linux - else -> OsFamily.Unknown - } - - return OperatingSystem(family, version) - } - - actual override fun getAllEnvVars(): Map = memScoped { - val environ = get_environ_ptr() - generateSequence(0) { it + 1 } - .map { idx -> environ?.get(idx)?.toKString() } - .takeWhile { it != null } - .associate { env -> - val parts = env?.split("=", limit = 2) - check(parts?.size == 2) { "Environment entry \"$env\" is malformed" } - parts[0] to parts[1] - } - } -} diff --git a/runtime/runtime-core/posix/src/posixInterop/cinterop/environ.h b/runtime/runtime-core/posix/src/posixInterop/cinterop/environ.h deleted file mode 100644 index aa6348ea0d..0000000000 --- a/runtime/runtime-core/posix/src/posixInterop/cinterop/environ.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ENVIRON_H -#define ENVIRON_H - -// External declaration to get environment variables -extern char **environ; - -// Helper function to get the environ pointer -char** get_environ_ptr() { - return environ; -} - -#endif \ No newline at end of file diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt index 63da8441e5..918fe764ba 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt @@ -290,10 +290,12 @@ class CborSerializerTest { val buffer = SdkBuffer().apply { write(serializer.toByteArray()) } val deserializer = CborPrimitiveDeserializer(buffer) - tests.forEach { + tests.dropLast(1).forEach { assertEquals(it.epochMilliseconds, deserializer.deserializeInstant(TimestampFormat.EPOCH_SECONDS).epochMilliseconds) } + // FIXME Serializing -> deserializing Instant.MAX_VALUE results in a one millisecond offset... + assertEquals(Instant.MAX_VALUE.epochMilliseconds, deserializer.deserializeInstant(TimestampFormat.EPOCH_SECONDS).epochMilliseconds - 1) assertEquals(0, buffer.size) } diff --git a/runtime/smithy-client/native/src/aws/smithy/kotlin/runtime/client/util/AnnotationsNative.kt b/runtime/smithy-client/native/src/aws/smithy/kotlin/runtime/client/util/AnnotationsNative.kt index efb9576ffb..118ea69bda 100644 --- a/runtime/smithy-client/native/src/aws/smithy/kotlin/runtime/client/util/AnnotationsNative.kt +++ b/runtime/smithy-client/native/src/aws/smithy/kotlin/runtime/client/util/AnnotationsNative.kt @@ -5,8 +5,6 @@ package aws.smithy.kotlin.runtime.client.util -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) public actual annotation class MpJvmDefaultWithoutCompatibility { // No-op on non-JVM platforms } diff --git a/settings.gradle.kts b/settings.gradle.kts index a39f42c908..dcd6c01bdb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -83,7 +83,6 @@ include(":runtime:auth:http-auth-api") include(":runtime:auth:http-auth-aws") include(":runtime:auth:identity-api") include(":runtime:crt-util") -include(":runtime:observability:logging-crt") include(":runtime:observability:logging-slf4j2") include(":runtime:observability:telemetry-api") include(":runtime:observability:telemetry-defaults") diff --git a/tests/codegen/waiter-tests/build.gradle.kts b/tests/codegen/waiter-tests/build.gradle.kts index 4171d35fee..34f5cc852e 100644 --- a/tests/codegen/waiter-tests/build.gradle.kts +++ b/tests/codegen/waiter-tests/build.gradle.kts @@ -38,7 +38,6 @@ kotlin.sourceSets.getByName("main") { tasks.withType { dependsOn(tasks.generateSmithyProjections) - // FIXME Re-enable warnings as errors SDK-KT-785 compilerOptions { allWarningsAsErrors = false From 6dd54050a2c4cdea0827e96817e63276b6debfb1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 30 Sep 2025 18:44:31 -0400 Subject: [PATCH 2/2] Revert "misc: upgrade to latest aws-kotlin-repo-tools version (#1428)" This reverts commit 26546d1f01cd592313fa6952cbf2ef2a43a0fcfa. --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9891cf19aa..184a78daa8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ kotlin-version = "2.2.0" dokka-version = "2.0.0" -aws-kotlin-repo-tools-version = "0.4.59" +aws-kotlin-repo-tools-version = "0.4.58" # libs coroutines-version = "1.10.2"