From 09586fe90149f17a05da68b6d61f892b40ad5133 Mon Sep 17 00:00:00 2001 From: warunalakshitha Date: Thu, 17 Oct 2024 10:06:51 +0530 Subject: [PATCH] Migrate to Java 21 --- .../workflows/build-dependent-std-libs.yml | 8 +- .../workflows/build-timestamped-master.yml | 2 +- .../workflows/build-with-bal-test-graalvm.yml | 2 +- .../workflows/build-with-ballerina-lang.yml | 8 +- .github/workflows/central-publish.yml | 2 +- ...build-timestamped-master-without-tests.yml | 2 +- .../workflows/process-load-test-result.yml | 2 +- .github/workflows/publish-release.yml | 2 +- .github/workflows/pull-request.yml | 2 +- .github/workflows/trigger-load-tests.yml | 2 +- .github/workflows/trivy-scan.yml | 2 +- README.md | 2 +- .../http-advanced-tests/Ballerina.toml | 4 +- .../http-client-tests/Ballerina.toml | 4 +- .../http-dispatching-tests/Ballerina.toml | 4 +- .../http-interceptor-tests/Ballerina.toml | 4 +- .../http-misc-tests/Ballerina.toml | 4 +- .../http-resiliency-tests/Ballerina.toml | 4 +- .../http-security-tests/Ballerina.toml | 4 +- .../http-service-tests/Ballerina.toml | 4 +- ballerina-tests/http2-tests/Ballerina.toml | 4 +- build-config/resources/Ballerina.toml | 60 ++++----- build.gradle | 8 +- compiler-plugin-tests/build.gradle | 7 +- compiler-plugin/build.gradle | 7 +- gradle.properties | 39 +++--- native/build.gradle | 8 +- native/spotbugs-exclude.xml | 41 ++++++ .../api/BallerinaHTTPConnectorListener.java | 57 ++++---- .../stdlib/http/api/DataContext.java | 19 +-- .../http/api/HttpCallableUnitCallback.java | 49 +++---- .../stdlib/http/api/HttpDispatcher.java | 54 ++------ .../HttpRequestInterceptorUnitCallback.java | 36 ++---- .../stdlib/http/api/HttpResource.java | 1 - .../HttpResponseInterceptorUnitCallback.java | 43 ++---- .../stdlib/http/api/HttpService.java | 34 ++--- .../ballerina/stdlib/http/api/HttpUtil.java | 34 ++--- .../http/api/client/actions/Execute.java | 13 +- .../http/api/client/actions/Forward.java | 11 +- .../api/client/actions/GetNextPromise.java | 21 ++- .../client/actions/GetPromisedResponse.java | 25 ++-- .../http/api/client/actions/GetResponse.java | 24 ++-- .../http/api/client/actions/HasPromise.java | 18 ++- .../api/client/actions/HttpClientAction.java | 122 ++++++------------ .../http/api/client/actions/Submit.java | 12 +- .../ExternHttpDataSourceBuilder.java | 91 +++++++------ .../nativeimpl/ExternResponseProcessor.java | 104 +++++---------- .../http/api/nativeimpl/ExternUtils.java | 13 ++ .../api/nativeimpl/connection/Promise.java | 21 ++- .../connection/PushPromisedResponse.java | 32 +++-- .../api/nativeimpl/connection/Respond.java | 37 +++--- .../transport/contractimpl/common/Util.java | 3 +- .../sender/states/http2/SendingHeaders.java | 1 - .../ballerina/stdlib/http/api/TestUtils.java | 5 - .../ConnectionPoolProxyTestCase.java | 26 ++-- .../ConnectionPoolTimeoutProxyTestCase.java | 19 +-- .../connectionpool/PerClientPoolTestCase.java | 20 +-- .../listeners/DumbMessageListener.java | 7 +- .../listeners/EchoMessageListener.java | 7 +- .../EchoStreamingMessageListener.java | 6 +- .../listeners/GetFullMessageListener.java | 10 +- .../MockHalfResponseMessageListener.java | 7 +- .../RequestResponseCreationListener.java | 7 +- ...uestResponseCreationStreamingListener.java | 8 +- .../RequestResponseTransformListener.java | 7 +- ...estResponseTransformStreamingListener.java | 7 +- ...onseStreamingWithoutBufferingListener.java | 6 +- .../listeners/TrailerHeaderListener.java | 5 +- .../contractimpl/common/FrameLoggerTest.java | 17 +-- .../listener/HttpTraceLoggingHandlerTest.java | 29 ++--- .../encoding/ContentReadingListener.java | 6 +- ...ctionAfterTcpClientGoAwayScenarioTest.java | 5 +- ...ctionAfterTcpClientGoAwayScenarioTest.java | 6 +- ...GoAwayAfterSendingHeadersScenarioTest.java | 5 +- .../Http2TcpClientSuccessScenarioTest.java | 5 +- .../listeners/Http2RedirectListener.java | 7 +- .../Http2ServerConnectorListener.java | 6 +- .../Http2ServerWaitDuringDataWrite.java | 5 +- .../HttpPipeliningListener.java | 7 +- .../message/BlockingEntityCollectorTest.java | 8 +- .../message/HttpCarbonMessageTest.java | 2 +- .../HeadRequestMessageProcessorListener.java | 7 +- ...sthroughHttpsMessageProcessorListener.java | 7 +- .../PassthroughMessageProcessorListener.java | 7 +- .../Continue100AfterRespReceivedListener.java | 6 +- .../server/listeners/Continue100Listener.java | 6 +- ...tServerHandshakeFunctionalityTestCase.java | 11 +- 87 files changed, 634 insertions(+), 782 deletions(-) diff --git a/.github/workflows/build-dependent-std-libs.yml b/.github/workflows/build-dependent-std-libs.yml index 604e989f6e..e6ff55d611 100644 --- a/.github/workflows/build-dependent-std-libs.yml +++ b/.github/workflows/build-dependent-std-libs.yml @@ -30,11 +30,11 @@ jobs: matrix: module: ${{ fromJson(inputs.ballerina_modules) }} steps: - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21 - name: Checkout module uses: actions/checkout@v3 @@ -98,11 +98,11 @@ jobs: matrix: module: ${{ fromJson(inputs.ballerinax_modules) }} steps: - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21 - name: Checkout module uses: actions/checkout@v3 diff --git a/.github/workflows/build-timestamped-master.yml b/.github/workflows/build-timestamped-master.yml index cc4972eb8c..38ea4e7310 100644 --- a/.github/workflows/build-timestamped-master.yml +++ b/.github/workflows/build-timestamped-master.yml @@ -14,5 +14,5 @@ jobs: call_workflow: name: Run Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/build-timestamp-master-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/build-timestamp-master-template.yml@java21 secrets: inherit diff --git a/.github/workflows/build-with-bal-test-graalvm.yml b/.github/workflows/build-with-bal-test-graalvm.yml index 425ab94e8d..db61bedcd8 100644 --- a/.github/workflows/build-with-bal-test-graalvm.yml +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -39,7 +39,7 @@ jobs: call_stdlib_workflow: name: Run StdLib Workflow if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }} - uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java21 with: lang_tag: ${{ inputs.lang_tag }} lang_version: ${{ inputs.lang_version }} diff --git a/.github/workflows/build-with-ballerina-lang.yml b/.github/workflows/build-with-ballerina-lang.yml index 58cbe880fb..35e0763091 100644 --- a/.github/workflows/build-with-ballerina-lang.yml +++ b/.github/workflows/build-with-ballerina-lang.yml @@ -30,11 +30,11 @@ jobs: repository: 'ballerina-platform/ballerina-lang' ref: ${{ inputs.lang_tag || 'master' }} - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21 - name: Set Ballerina Lang version run: | @@ -77,11 +77,11 @@ jobs: repository: 'ballerina-platform/ballerina-lang' ref: ${{ inputs.lang_tag || 'master' }} - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21 - name: Set Ballerina Lang version run: | diff --git a/.github/workflows/central-publish.yml b/.github/workflows/central-publish.yml index 6bd74c449f..0dcae97c97 100644 --- a/.github/workflows/central-publish.yml +++ b/.github/workflows/central-publish.yml @@ -16,7 +16,7 @@ jobs: call_workflow: name: Run Central Publish Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/central-publish-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/central-publish-template.yml@java21 secrets: inherit with: environment: ${{ github.event.inputs.environment }} diff --git a/.github/workflows/on-demand-urgent-build-timestamped-master-without-tests.yml b/.github/workflows/on-demand-urgent-build-timestamped-master-without-tests.yml index 30470f7f8f..a2bb53d137 100644 --- a/.github/workflows/on-demand-urgent-build-timestamped-master-without-tests.yml +++ b/.github/workflows/on-demand-urgent-build-timestamped-master-without-tests.yml @@ -7,7 +7,7 @@ jobs: call_workflow: name: Run Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/build-timestamp-master-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/build-timestamp-master-template.yml@java21 with: additional-build-flags: '-x check -x test' secrets: inherit diff --git a/.github/workflows/process-load-test-result.yml b/.github/workflows/process-load-test-result.yml index 67a30482df..e187bfd27e 100644 --- a/.github/workflows/process-load-test-result.yml +++ b/.github/workflows/process-load-test-result.yml @@ -6,7 +6,7 @@ on: jobs: call_stdlib_process_load_test_results_workflow: name: Run StdLib Process Load Test Results Workflow - uses: ballerina-platform/ballerina-library/.github/workflows/process-load-test-results-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/process-load-test-results-template.yml@java21 with: results: ${{ toJson(github.event.client_payload.results) }} secrets: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 3119cf2777..55214c4a4f 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -9,7 +9,7 @@ jobs: call_workflow: name: Run Release Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/release-package-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/release-package-template.yml@java21 secrets: inherit with: package-name: http diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index dbbc163ad9..806bcb0489 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -6,5 +6,5 @@ jobs: call_workflow: name: Run PR Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java21 secrets: inherit diff --git a/.github/workflows/trigger-load-tests.yml b/.github/workflows/trigger-load-tests.yml index 66a910ca3d..5cec3af227 100644 --- a/.github/workflows/trigger-load-tests.yml +++ b/.github/workflows/trigger-load-tests.yml @@ -22,7 +22,7 @@ jobs: call_stdlib_trigger_load_test_workflow: name: Run StdLib Load Test Workflow if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }} - uses: ballerina-platform/ballerina-library/.github/workflows/trigger-load-tests-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/trigger-load-tests-template.yml@java21 with: repo_name: 'module-ballerina-http' runtime_artifacts_url: 'https://api.github.com/repos/ballerina-platform/module-ballerina-http/actions/artifacts' diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index 2f7999dedd..684db29190 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -9,5 +9,5 @@ jobs: call_workflow: name: Run Trivy Scan Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/trivy-scan-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/trivy-scan-template.yml@java21 secrets: inherit diff --git a/README.md b/README.md index 7671d72216..572d661fc8 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ This repository only contains the source code for the package. ### Set Up the prerequisites -1. Download and install Java SE Development Kit (JDK) version 17 (from one of the following locations). +1. Download and install Java SE Development Kit (JDK) version 21 (from one of the following locations). * [Oracle](https://www.oracle.com/java/technologies/downloads/) diff --git a/ballerina-tests/http-advanced-tests/Ballerina.toml b/ballerina-tests/http-advanced-tests/Ballerina.toml index 3ee0bd35f6..0c540ca7cd 100644 --- a/ballerina-tests/http-advanced-tests/Ballerina.toml +++ b/ballerina-tests/http-advanced-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-client-tests/Ballerina.toml b/ballerina-tests/http-client-tests/Ballerina.toml index c6fafc1909..358b168e05 100644 --- a/ballerina-tests/http-client-tests/Ballerina.toml +++ b/ballerina-tests/http-client-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-dispatching-tests/Ballerina.toml b/ballerina-tests/http-dispatching-tests/Ballerina.toml index 6b409df4f0..20d1c2d98b 100644 --- a/ballerina-tests/http-dispatching-tests/Ballerina.toml +++ b/ballerina-tests/http-dispatching-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-interceptor-tests/Ballerina.toml b/ballerina-tests/http-interceptor-tests/Ballerina.toml index c9e750b259..2c26dac811 100644 --- a/ballerina-tests/http-interceptor-tests/Ballerina.toml +++ b/ballerina-tests/http-interceptor-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-misc-tests/Ballerina.toml b/ballerina-tests/http-misc-tests/Ballerina.toml index fd660d3f52..e6f4275ae1 100644 --- a/ballerina-tests/http-misc-tests/Ballerina.toml +++ b/ballerina-tests/http-misc-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-resiliency-tests/Ballerina.toml b/ballerina-tests/http-resiliency-tests/Ballerina.toml index afa1e84565..15d751433a 100644 --- a/ballerina-tests/http-resiliency-tests/Ballerina.toml +++ b/ballerina-tests/http-resiliency-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-security-tests/Ballerina.toml b/ballerina-tests/http-security-tests/Ballerina.toml index ca398c1cc0..d1882132c8 100644 --- a/ballerina-tests/http-security-tests/Ballerina.toml +++ b/ballerina-tests/http-security-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http-service-tests/Ballerina.toml b/ballerina-tests/http-service-tests/Ballerina.toml index 019d2dc081..ce1f463d94 100644 --- a/ballerina-tests/http-service-tests/Ballerina.toml +++ b/ballerina-tests/http-service-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/ballerina-tests/http2-tests/Ballerina.toml b/ballerina-tests/http2-tests/Ballerina.toml index 89b8f31e5b..78dd5cdcb0 100644 --- a/ballerina-tests/http2-tests/Ballerina.toml +++ b/ballerina-tests/http2-tests/Ballerina.toml @@ -9,9 +9,9 @@ name = "http_test_common" repository = "local" version = "2.12.1" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] scope = "testOnly" path = "../../test-utils/build/libs/http-test-utils-2.12.1-SNAPSHOT.jar" diff --git a/build-config/resources/Ballerina.toml b/build-config/resources/Ballerina.toml index 2bb22346b2..81853a7955 100644 --- a/build-config/resources/Ballerina.toml +++ b/build-config/resources/Ballerina.toml @@ -10,163 +10,163 @@ license = ["Apache-2.0"] distribution = "2201.10.0" export = ["http", "http.httpscerr"] -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "http-native" version = "@toml.version@" path = "../native/build/libs/http-native-@project.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "mime-native" version = "@mime.version@" path = "./lib/mime-native-@stdlib.mimenative.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "constraint-native" version = "@constraint.version@" path = "./lib/constraint-native-@stdlib.constraintnative.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-common" version = "@netty.version@" path = "./lib/netty-common-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-buffer" version = "@netty.version@" path = "./lib/netty-buffer-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-transport" version = "@netty.version@" path = "./lib/netty-transport-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-resolver" version = "@netty.version@" path = "./lib/netty-resolver-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-handler" version = "@netty.version@" path = "./lib/netty-handler-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-codec-http" version = "@netty.version@" path = "./lib/netty-codec-http-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-codec" version = "@netty.version@" path = "./lib/netty-codec-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-handler-proxy" version = "@netty.version@" path = "./lib/netty-handler-proxy-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-codec-http2" version = "@netty.version@" path = "./lib/netty-codec-http2-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "commons-pool.wso2" artifactId = "commons-pool" version = "@commmon.pool.version@" path = "./lib/commons-pool-@commmon.pool.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-transport-native-unix-common" version = "@netty.version@" path = "./lib/netty-transport-native-unix-common-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "org.bouncycastle" artifactId = "bcprov-jdk18on" version = "@bouncycastle.version@" path = "./lib/bcprov-jdk18on-@bouncycastle.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "org.bouncycastle" artifactId = "bcutil-jdk18on" version = "@bouncycastle.version@" path = "./lib/bcutil-jdk18on-@bouncycastle.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "org.bouncycastle" artifactId = "bcpkix-jdk18on" version = "@bouncycastle.version@" path = "./lib/bcpkix-jdk18on-@bouncycastle.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-tcnative-boringssl-static" version = "@tcnative.version@" path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@-windows-x86_64.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@-linux-aarch_64.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@-linux-x86_64.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@-osx-aarch_64.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-tcnative-boringssl-static-@tcnative.version@-osx-x86_64.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-tcnative-classes" version = "@tcnative.version@" path = "./lib/netty-tcnative-classes-@tcnative.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "org.jvnet.mimepull" artifactId = "mimepull" version = "@mimepull.version@" path = "./lib/mimepull-@mimepull.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.netty" artifactId = "netty-codec-socks" version = "@netty.version@" path = "./lib/netty-codec-socks-@netty.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "org.jboss.marshalling" artifactId = "jboss-marshalling" version = "@marshalling.version@" path = "./lib/jboss-marshalling-@marshalling.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "net.jpountz.lz4" artifactId = "lz4" version = "@lz4.version@" path = "./lib/lz4-@lz4.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "com.google.protobufl" artifactId = "protobuf-java" version = "@protobuf.version@" diff --git a/build.gradle b/build.gradle index 74b6ea4ac9..46a77c629c 100644 --- a/build.gradle +++ b/build.gradle @@ -16,10 +16,10 @@ */ plugins { - id "com.github.spotbugs" version "5.0.14" - id "com.github.johnrengelman.shadow" version "8.1.1" - id "de.undercouch.download" version "5.4.0" - id "net.researchgate.release" version "2.8.0" + id "com.github.spotbugs" version "${githubSpotbugsVersion}" + id "com.github.johnrengelman.shadow" version "${githubJohnrengelmanShadowVersion}" + id "de.undercouch.download" version "${underCouchDownloadVersion}" + id "net.researchgate.release" version "${researchgateReleaseVersion}" } ext.ballerinaLangVersion = project.ballerinaLangVersion diff --git a/compiler-plugin-tests/build.gradle b/compiler-plugin-tests/build.gradle index 73c3f3cd25..87375786e5 100644 --- a/compiler-plugin-tests/build.gradle +++ b/compiler-plugin-tests/build.gradle @@ -56,8 +56,11 @@ checkstyle { checkstyleTest.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") spotbugsTest { - effort "max" - reportLevel "low" + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW reportsDir = file("$project.buildDir/reports/spotbugs") reports { html.enabled true diff --git a/compiler-plugin/build.gradle b/compiler-plugin/build.gradle index e1c254571c..e47fb7fb02 100644 --- a/compiler-plugin/build.gradle +++ b/compiler-plugin/build.gradle @@ -56,8 +56,11 @@ checkstyle { checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") spotbugsMain { - effort "max" - reportLevel "low" + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW reportsDir = file("$project.buildDir/reports/spotbugs") reports { html.enabled true diff --git a/gradle.properties b/gradle.properties index 0303be03bd..d4b478cb91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ org.gradle.caching=true group=io.ballerina.stdlib version=2.12.1-SNAPSHOT -ballerinaLangVersion=2201.10.0 +ballerinaLangVersion=2201.10.0-20241011-161100-51978649 ballerinaTomlParserVersion=1.2.2 commonsLang3Version=3.12.0 nettyVersion=4.1.108.Final @@ -26,23 +26,28 @@ jacocoVersion=0.8.10 ballerinaToOpenApiVersion=2.1.0 swaggerCoreVersion=2.2.22 -stdlibIoVersion=1.6.1 -stdlibTimeVersion=2.4.0 -stdlibUrlVersion=2.4.0 +githubSpotbugsVersion=6.0.18 +githubJohnrengelmanShadowVersion=8.1.1 +underCouchDownloadVersion=5.4.0 +researchgateReleaseVersion=2.8.0 -stdlibConstraintVersion=1.5.0 -stdlibOsVersion=1.8.0 -stdlibTaskVersion=2.5.0 -stdlibLogVersion=2.10.0 -stdlibCryptoVersion=2.7.2 +stdlibIoVersion=1.6.2-20241015-173200-3e70033 +stdlibTimeVersion=2.5.1-20240930-120200-e59222b +stdlibUrlVersion=2.4.1-20240930-120200-b7fb9e1 -stdlibFileVersion=1.10.0 -stdlibMimeVersion=2.10.0 -stdlibCacheVersion=3.8.0 +stdlibConstraintVersion=1.5.1-20240930-123400-5ecd396 +stdlibOsVersion=1.8.1-20241001-120600-dd1626e +stdlibTaskVersion=2.5.1-20241002-145700-5bdb843 +stdlibLogVersion=2.10.1-20240930-154200-5ab2aa4 +stdlibCryptoVersion=2.7.3-20240930-132000-5ecc9ab -stdlibAuthVersion=2.12.0 -stdlibJwtVersion=2.13.0 -stdlibOAuth2Version=2.12.0 +stdlibFileVersion=1.10.1-20241007-160900-03f7b64 +stdlibMimeVersion=2.10.1-20241009-141200-8b6c9f0 +stdlibCacheVersion=3.8.1-20241007-154900-63f4403 -observeVersion=1.3.0 -observeInternalVersion=1.3.0 +stdlibAuthVersion=2.12.1-20241010-130800-733dbef +stdlibJwtVersion=2.13.1-20241010-123600-5ea6a94 +stdlibOAuth2Version=2.12.1-20241010-123600-0e0cfcc + +observeVersion=1.3.1-20241007-161000-645452d +observeInternalVersion=1.3.1-20241015-172900-cdc3cb3 diff --git a/native/build.gradle b/native/build.gradle index 64d9a6aea1..34b1f3e2a5 100644 --- a/native/build.gradle +++ b/native/build.gradle @@ -43,6 +43,7 @@ dependencies { implementation group: 'io.ballerina.stdlib', name: 'mime-native', version: "${stdlibMimeVersion}" implementation group: 'io.ballerina.stdlib', name: 'constraint-native', version: "${stdlibConstraintVersion}" + implementation group: 'org.slf4j', name: 'slf4j-api', version: "${slf4jVersion}" implementation group: 'org.slf4j', name: 'slf4j-jdk14', version: "${slf4jVersion}" implementation group: 'org.apache.commons', name: 'commons-lang3', version: "${commonsLang3Version}" implementation group: 'com.google.code.gson', name: 'gson', version: "${gsonVersion}" @@ -115,8 +116,11 @@ checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") checkstyleTest.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") spotbugsMain { - effort "max" - reportLevel "low" + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW reportsDir = file("$project.buildDir/reports/spotbugs") reports { html.enabled true diff --git a/native/spotbugs-exclude.xml b/native/spotbugs-exclude.xml index 0a80fdd752..a44b6df5a3 100644 --- a/native/spotbugs-exclude.xml +++ b/native/spotbugs-exclude.xml @@ -177,4 +177,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/BallerinaHTTPConnectorListener.java b/native/src/main/java/io/ballerina/stdlib/http/api/BallerinaHTTPConnectorListener.java index 0bdac2a974..1d69bfd737 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/BallerinaHTTPConnectorListener.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/BallerinaHTTPConnectorListener.java @@ -18,7 +18,6 @@ package io.ballerina.stdlib.http.api; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.types.ObjectType; import io.ballerina.runtime.api.utils.TypeUtils; @@ -183,20 +182,27 @@ protected void extractPropertiesAndStartResourceExecution(HttpCarbonMessage inbo inboundMessage.setProperty(HttpConstants.OBSERVABILITY_CONTEXT_PROPERTY, observerContext); } Runtime runtime = httpServicesRegistry.getRuntime(); - Callback callback = new HttpCallableUnitCallback(inboundMessage, runtime, httpResource, + HttpCallableUnitCallback callback = new HttpCallableUnitCallback(inboundMessage, runtime, httpResource, httpServicesRegistry.isPossibleLastService()); BObject service = httpResource.getParentService().getBalService(); String resourceName = httpResource.getName(); ObjectType serviceType = (ObjectType) TypeUtils.getReferredType(TypeUtils.getType(service)); - if (serviceType.isIsolated() && serviceType.isIsolated(resourceName)) { - runtime.invokeMethodAsyncConcurrently(service, resourceName, null, - ModuleUtils.getOnMessageMetaData(), callback, properties, - httpResource.getBalResource().getReturnType(), signatureParams); - } else { - runtime.invokeMethodAsyncSequentially(service, resourceName, null, - ModuleUtils.getOnMessageMetaData(), callback, properties, - httpResource.getBalResource().getReturnType(), signatureParams); - } + Thread.startVirtualThread(() -> { + Object result; + try { + if (serviceType.isIsolated() && serviceType.isIsolated(resourceName)) { + result = runtime.startIsolatedWorker(service, resourceName, null, + ModuleUtils.getOnMessageMetaData(), properties, signatureParams).get(); + + } else { + result = runtime.startNonIsolatedWorker(service, resourceName, null, + ModuleUtils.getOnMessageMetaData(), properties, signatureParams).get(); + } + callback.handleResult(result); + } catch (BError error) { + callback.handlePanic(error); + } + }); } protected boolean accessed(HttpCarbonMessage inboundMessage) { @@ -234,27 +240,34 @@ private Map collectRequestProperties(HttpCarbonMessage inboundMe protected void extractPropertiesAndStartInterceptorResourceExecution(HttpCarbonMessage inboundMessage, InterceptorResource resource, HTTPInterceptorServicesRegistry registry) { + Map properties = collectRequestProperties(inboundMessage, true); Runtime runtime = registry.getRuntime(); Object[] signatureParams = HttpDispatcher.getSignatureParameters(resource, inboundMessage, endpointConfig, registry.getRuntime()); - Callback callback = new HttpRequestInterceptorUnitCallback( - inboundMessage, runtime, this); + HttpRequestInterceptorUnitCallback callback = new HttpRequestInterceptorUnitCallback(inboundMessage, runtime, + this); BObject service = resource.getParentService().getBalService(); String resourceName = resource.getName(); inboundMessage.removeProperty(HttpConstants.INTERCEPTOR_SERVICE_ERROR); ObjectType serviceType = (ObjectType) TypeUtils.getReferredType(TypeUtils.getType(service)); - if (serviceType.isIsolated() && serviceType.isIsolated(resourceName)) { - runtime.invokeMethodAsyncConcurrently(service, resourceName, null, - ModuleUtils.getOnMessageMetaData(), callback, properties, - resource.getBalResource().getReturnType(), signatureParams); - } else { - runtime.invokeMethodAsyncSequentially(service, resourceName, null, - ModuleUtils.getOnMessageMetaData(), callback, properties, - resource.getBalResource().getReturnType(), signatureParams); - } + Thread.startVirtualThread(() -> { + Object result; + try { + if (serviceType.isIsolated() && serviceType.isIsolated(resourceName)) { + result = runtime.startIsolatedWorker(service, resourceName, null, + ModuleUtils.getOnMessageMetaData(), properties, signatureParams); + } else { + result = runtime.startNonIsolatedWorker(service, resourceName, null, + ModuleUtils.getOnMessageMetaData(), properties, signatureParams); + } + callback.handleResult(result); + } catch (BError error) { + callback.handlePanic(error); + } + }); } protected void executeMainResourceOnMessage(HttpCarbonMessage inboundMessage) { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/DataContext.java b/native/src/main/java/io/ballerina/stdlib/http/api/DataContext.java index 768fca6ec0..48805af58f 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/DataContext.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/DataContext.java @@ -19,12 +19,13 @@ package io.ballerina.stdlib.http.api; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BObject; import io.ballerina.stdlib.http.transport.contract.HttpClientConnector; import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; +import java.util.concurrent.CompletableFuture; + /** * {@code DataContext} is the wrapper to hold {@code Context} and {@code Callback}. */ @@ -32,21 +33,23 @@ public class DataContext { private Environment environment; private HttpClientConnector clientConnector; private BObject requestObj; - private Future balFuture; + private CompletableFuture balFuture; private HttpCarbonMessage correlatedMessage; - public DataContext(Environment environment, HttpClientConnector clientConnector, - BObject requestObj, HttpCarbonMessage outboundRequestMsg) { + public DataContext(Environment environment, CompletableFuture balFuture, + HttpClientConnector clientConnector, BObject requestObj, + HttpCarbonMessage outboundRequestMsg) { this.environment = environment; - this.balFuture = environment.markAsync(); + this.balFuture = balFuture; this.clientConnector = clientConnector; this.requestObj = requestObj; this.correlatedMessage = outboundRequestMsg; } - public DataContext(Environment environment, HttpCarbonMessage inboundRequestMsg) { + public DataContext(Environment environment, CompletableFuture balFuture, + HttpCarbonMessage inboundRequestMsg) { this.environment = environment; - this.balFuture = environment.markAsync(); + this.balFuture = balFuture; this.clientConnector = null; this.requestObj = null; this.correlatedMessage = inboundRequestMsg; @@ -84,7 +87,7 @@ public Environment getEnvironment() { return environment; } - public Future getFuture() { + public CompletableFuture getFuture() { return balFuture; } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpCallableUnitCallback.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpCallableUnitCallback.java index 3eedc79796..b15e38bff9 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpCallableUnitCallback.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpCallableUnitCallback.java @@ -16,9 +16,7 @@ package io.ballerina.stdlib.http.api; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; @@ -39,7 +37,7 @@ * * @since 0.94 */ -public class HttpCallableUnitCallback implements Callback { +public class HttpCallableUnitCallback { private static final String ILLEGAL_FUNCTION_INVOKED = "illegal return: response has already been sent"; private final BObject caller; @@ -85,8 +83,7 @@ private BObject getCaller(HttpCarbonMessage requestMessage, String resourceAcces return caller; } - @Override - public void notifySuccess(Object result) { + public void handleResult(Object result) { if (alreadyResponded(result)) { stopObserverContext(); return; @@ -102,44 +99,31 @@ public void notifySuccess(Object result) { } private void returnResponse(Object result) { - Object[] paramFeed = new Object[8]; + Object[] paramFeed = new Object[4]; paramFeed[0] = result; - paramFeed[1] = true; - paramFeed[2] = Objects.nonNull(returnMediaType) ? StringUtils.fromString(returnMediaType) : null; - paramFeed[3] = true; - paramFeed[4] = cacheConfig; - paramFeed[5] = true; - paramFeed[6] = Objects.nonNull(links) && !links.isEmpty() ? links : null; - paramFeed[7] = true; - + paramFeed[1] = Objects.nonNull(returnMediaType) ? StringUtils.fromString(returnMediaType) : null; + paramFeed[2] = cacheConfig; + paramFeed[3] = Objects.nonNull(links) && !links.isEmpty() ? links : null; invokeBalMethod(paramFeed, "returnResponse"); } private void returnErrorResponse(BError error) { - Object[] paramFeed = new Object[4]; + Object[] paramFeed = new Object[2]; paramFeed[0] = error; - paramFeed[1] = true; - paramFeed[2] = returnMediaType != null ? StringUtils.fromString(returnMediaType) : null; - paramFeed[3] = true; - + paramFeed[1] = returnMediaType != null ? StringUtils.fromString(returnMediaType) : null; invokeBalMethod(paramFeed, "returnErrorResponse"); } public void invokeBalMethod(Object[] paramFeed, String methodName) { - Callback returnCallback = new Callback() { - @Override - public void notifySuccess(Object result) { + Thread.startVirtualThread(() -> { + try { + runtime.startNonIsolatedWorker(caller, methodName, null, + ModuleUtils.getNotifySuccessMetaData(), null, paramFeed).get(); stopObserverContext(); + } catch (BError error) { + sendFailureResponse(error); } - - @Override - public void notifyFailure(BError result) { - sendFailureResponse(result); - } - }; - runtime.invokeMethodAsyncSequentially( - caller, methodName, null, ModuleUtils.getNotifySuccessMetaData(), - returnCallback, null, PredefinedTypes.TYPE_NULL, paramFeed); + }); } public void stopObserverContext() { @@ -152,8 +136,7 @@ public void stopObserverContext() { } } - @Override - public void notifyFailure(BError error) { // handles panic and check_panic + public void handlePanic(BError error) { // handles panic and check_panic // Allow the panics from internal authentication/authorization to be handled by the interceptors. if (error.getType().getName().equals(HttpErrorType.INTERNAL_LISTENER_AUTHN_ERROR.getErrorName()) || error.getType().getName().equals(HttpErrorType.INTERNAL_LISTENER_AUTHZ_ERROR.getErrorName())) { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpDispatcher.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpDispatcher.java index 89ca9d40e6..928e616289 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpDispatcher.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpDispatcher.java @@ -18,9 +18,7 @@ package io.ballerina.stdlib.http.api; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.Type; @@ -51,7 +49,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CountDownLatch; import static io.ballerina.stdlib.http.api.HttpConstants.AUTHORIZATION_HEADER; import static io.ballerina.stdlib.http.api.HttpConstants.BEARER_AUTHORIZATION_HEADER; @@ -275,40 +272,35 @@ public static Object[] getRemoteSignatureParameters(InterceptorService service, BError error = (BError) httpCarbonMessage.getProperty(HttpConstants.INTERCEPTOR_SERVICE_ERROR); RemoteMethodParamHandler paramHandler = service.getRemoteMethodParamHandler(); int sigParamCount = paramHandler.getParamCount(); - Object[] paramFeed = new Object[sigParamCount * 2]; + Object[] paramFeed = new Object[sigParamCount]; for (Parameter param : paramHandler.getOtherParamList()) { String typeName = param.getTypeName(); switch (typeName) { case HttpConstants.REQUEST_CONTEXT: int index = ((NonRecurringParam) param).getIndex(); - paramFeed[index++] = requestCtx; - paramFeed[index] = true; + paramFeed[index] = requestCtx; break; case HttpConstants.REQUEST: if (inRequest == null) { inRequest = createRequest(httpCarbonMessage, entityObj); } index = ((NonRecurringParam) param).getIndex(); - paramFeed[index++] = inRequest; - paramFeed[index] = true; + paramFeed[index] = inRequest; break; case HttpConstants.STRUCT_GENERIC_ERROR: if (error == null) { error = createError(); } index = ((NonRecurringParam) param).getIndex(); - paramFeed[index++] = error; - paramFeed[index] = true; + paramFeed[index] = error; break; case HttpConstants.RESPONSE: index = ((NonRecurringParam) param).getIndex(); - paramFeed[index++] = response; - paramFeed[index] = true; + paramFeed[index] = response; break; case HttpConstants.CALLER: index = ((NonRecurringParam) param).getIndex(); - paramFeed[index++] = caller; - paramFeed[index] = true; + paramFeed[index] = caller; break; default: break; @@ -474,40 +466,14 @@ private static void addJwtValuesToRequestContext(Runtime runtime, BObject reques private static Object invokeJwtDecode(Runtime runtime, String authHeader) { final Object[] jwtInformation = new Object[1]; - CountDownLatch countDownLatch = new CountDownLatch(1); - Callback decodeCallback = new Callback() { - @Override - public void notifySuccess(Object result) { - if (!(result instanceof Exception)) { - jwtInformation[0] = result; - } - countDownLatch.countDown(); - } - - @Override - public void notifyFailure(BError bError) { - countDownLatch.countDown(); - } - }; - String[] splitValues = authHeader.split(WHITESPACE); if (splitValues.length != 2) { return null; } - runtime.invokeMethodAsyncSequentially( - ValueCreator.createObjectValue(ModuleUtils.getHttpPackage(), JWT_DECODER_CLASS_NAME), - JWT_DECODE_METHOD_NAME, - null, - ModuleUtils.getNotifySuccessMetaData(), - decodeCallback, - null, - PredefinedTypes.TYPE_ANY, - StringUtils.fromString(splitValues[1]), - true); - try { - countDownLatch.await(); - } catch (InterruptedException exception) { - logger.warn("Interrupted before receiving the response"); + Object result = runtime.call(ValueCreator.createObjectValue(ModuleUtils.getHttpPackage(), + JWT_DECODER_CLASS_NAME), JWT_DECODE_METHOD_NAME, StringUtils.fromString(splitValues[1])); + if (!(result instanceof Exception)) { + jwtInformation[0] = result; } return jwtInformation[0]; } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpRequestInterceptorUnitCallback.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpRequestInterceptorUnitCallback.java index dc10dc7a43..76b93fac1e 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpRequestInterceptorUnitCallback.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpRequestInterceptorUnitCallback.java @@ -18,9 +18,7 @@ package io.ballerina.stdlib.http.api; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.types.ServiceType; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -56,7 +54,7 @@ public class HttpRequestInterceptorUnitCallback extends HttpCallableUnitCallback } @Override - public void notifySuccess(Object result) { + public void handleResult(Object result) { if (result instanceof BError) { if (!result.equals(requestCtx.getNativeData(HttpConstants.TARGET_SERVICE))) { requestMessage.setHttpStatusCode(500); @@ -68,7 +66,7 @@ public void notifySuccess(Object result) { } @Override - public void notifyFailure(BError error) { // handles panic and check_panic + public void handlePanic(BError error) { // handles panic and check_panic cleanupRequestMessage(); sendFailureResponse(error); System.exit(1); @@ -165,34 +163,24 @@ private void validateServiceReturnType(Object result, int interceptorId, BArray } private void returnResponse(Object result) { - Object[] paramFeed = new Object[8]; + Object[] paramFeed = new Object[4]; paramFeed[0] = result; - paramFeed[1] = true; + paramFeed[1] = null; paramFeed[2] = null; - paramFeed[3] = true; - paramFeed[4] = null; - paramFeed[5] = true; - paramFeed[6] = null; - paramFeed[7] = true; - + paramFeed[3] = null; invokeBalMethod(paramFeed, "returnResponse"); } public void invokeBalMethod(Object[] paramFeed, String methodName) { - Callback returnCallback = new Callback() { - @Override - public void notifySuccess(Object result) { - } - - @Override - public void notifyFailure(BError result) { + Thread.startVirtualThread(() -> { + try { + runtime.startNonIsolatedWorker(caller, methodName, null, ModuleUtils.getNotifySuccessMetaData(), null + , paramFeed); + } catch (BError error) { cleanupRequestMessage(); - HttpUtil.handleFailure(requestMessage, result); + HttpUtil.handleFailure(requestMessage, error); } - }; - runtime.invokeMethodAsyncSequentially( - caller, methodName, null, ModuleUtils.getNotifySuccessMetaData(), - returnCallback, null, PredefinedTypes.TYPE_NULL, paramFeed); + }); } private int getRequestInterceptorId() { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpResource.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpResource.java index 0f8fd0bd09..f3d1c9c85d 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpResource.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpResource.java @@ -97,7 +97,6 @@ public class HttpResource implements Resource { private MethodType balResource; private List methods; private String path; - private String entityBodyAttribute; private List consumes; private List produces; private List producesSubTypes; diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpResponseInterceptorUnitCallback.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpResponseInterceptorUnitCallback.java index 7c601addb5..2fe2d366a0 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpResponseInterceptorUnitCallback.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpResponseInterceptorUnitCallback.java @@ -19,9 +19,7 @@ package io.ballerina.stdlib.http.api; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.types.ServiceType; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -61,7 +59,7 @@ public HttpResponseInterceptorUnitCallback(HttpCarbonMessage requestMessage, BOb } @Override - public void notifySuccess(Object result) { + public void handleResult(Object result) { if (result instanceof BError) { requestMessage.setHttpStatusCode(500); invokeErrorInterceptors((BError) result, false); @@ -74,7 +72,7 @@ public void notifySuccess(Object result) { } @Override - public void notifyFailure(BError error) { // handles panic and check_panic + public void handlePanic(BError error) { // handles panic and check_panic cleanupRequestMessage(); sendFailureResponse(error); System.exit(1); @@ -146,37 +144,27 @@ private void validateServiceReturnType(Object result, int interceptorId, BArray } private void returnResponse(Object result) { - Object[] paramFeed = new Object[8]; + Object[] paramFeed = new Object[4]; paramFeed[0] = result; - paramFeed[1] = true; + paramFeed[1] = null; paramFeed[2] = null; - paramFeed[3] = true; - paramFeed[4] = null; - paramFeed[5] = true; - paramFeed[6] = null; - paramFeed[7] = true; - + paramFeed[3] = null; invokeBalMethod(paramFeed, "returnResponse"); } @Override public void invokeBalMethod(Object[] paramFeed, String methodName) { - Callback returnCallback = new Callback() { - @Override - public void notifySuccess(Object result) { + Thread.startVirtualThread(() -> { + try { + this.getRuntime().startIsolatedWorker(caller, methodName, null, + ModuleUtils.getNotifySuccessMetaData(), null, paramFeed); stopObserverContext(); dataContext.notifyOutboundResponseStatus(null); - } - - @Override - public void notifyFailure(BError result) { + } catch (BError error) { dataContext.notifyOutboundResponseStatus(null); - sendFailureResponse(result); + sendFailureResponse(error); } - }; - this.getRuntime().invokeMethodAsyncSequentially( - caller, methodName, null, ModuleUtils.getNotifySuccessMetaData(), - returnCallback, null, PredefinedTypes.TYPE_NULL, paramFeed); + }); } private int getResponseInterceptorId() { @@ -185,12 +173,9 @@ private int getResponseInterceptorId() { } public void returnErrorResponse(BError error) { - Object[] paramFeed = new Object[4]; + Object[] paramFeed = new Object[2]; paramFeed[0] = error; - paramFeed[1] = true; - paramFeed[2] = null; - paramFeed[3] = true; - + paramFeed[1] = null; invokeBalMethod(paramFeed, "returnErrorResponse"); } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpService.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpService.java index 7fbf323220..c3c3813620 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpService.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpService.java @@ -19,7 +19,6 @@ import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; @@ -53,7 +52,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -491,31 +489,17 @@ public static void populateInterceptorServicesRegistries(List config = (BMap) httpClient.getNativeData(CLIENT_ENDPOINT_CONFIG); HttpClientConnector clientConnector = (HttpClientConnector) httpClient.getNativeData(HttpConstants.CLIENT); HttpCarbonMessage outboundRequestMsg = createOutboundRequestMsg(config, url, verb.getValue(), path.getValue(), - requestObj); - DataContext dataContext = new DataContext(env, clientConnector, requestObj, outboundRequestMsg); - executeNonBlockingAction(dataContext, false); - return null; + requestObj); + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, requestObj, outboundRequestMsg); + executeNonBlockingAction(dataContext, false); + return getResult(balFuture); + }); } protected static HttpCarbonMessage createOutboundRequestMsg(BMap config, String serviceUri, diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Forward.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Forward.java index 381d1e943d..1f464d6e8e 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Forward.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Forward.java @@ -29,9 +29,11 @@ import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; import java.util.Locale; +import java.util.concurrent.CompletableFuture; import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_ENDPOINT_SERVICE_URI; import static io.ballerina.stdlib.http.api.HttpUtil.checkRequestBodySizeHeadersAvailability; +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; /** * {@code Forward} action can be used to invoke an http call with incoming request httpVerb. @@ -42,9 +44,12 @@ public static Object forward(Environment env, BObject httpClient, BString path, String url = (String) httpClient.getNativeData(CLIENT_ENDPOINT_SERVICE_URI); HttpCarbonMessage outboundRequestMsg = createOutboundRequestMsg(url, path.getValue(), requestObj); HttpClientConnector clientConnector = (HttpClientConnector) httpClient.getNativeData(HttpConstants.CLIENT); - DataContext dataContext = new DataContext(env, clientConnector, requestObj, outboundRequestMsg); - executeNonBlockingAction(dataContext, false); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, requestObj, outboundRequestMsg); + executeNonBlockingAction(dataContext, false); + return getResult(balFuture); + }); } protected static HttpCarbonMessage createOutboundRequestMsg(String serviceUri, String path, BObject requestObj) { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetNextPromise.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetNextPromise.java index 24b7533171..052fee23ba 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetNextPromise.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetNextPromise.java @@ -29,6 +29,10 @@ import io.ballerina.stdlib.http.transport.message.Http2PushPromise; import io.ballerina.stdlib.http.transport.message.ResponseHandle; +import java.util.concurrent.CompletableFuture; + +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; + /** * {@code GetNextPromise} action can be used to get the next available push promise message associated with * a previous asynchronous invocation. @@ -37,13 +41,16 @@ public class GetNextPromise extends AbstractHTTPAction { public static Object getNextPromise(Environment env, BObject clientObj, BObject handleObj) { HttpClientConnector clientConnector = (HttpClientConnector) clientObj.getNativeData(HttpConstants.CLIENT); - DataContext dataContext = new DataContext(env, clientConnector, handleObj, null); - ResponseHandle responseHandle = (ResponseHandle) handleObj.getNativeData(HttpConstants.TRANSPORT_HANDLE); - if (responseHandle == null) { - throw HttpUtil.createHttpError("invalid http handle"); - } - clientConnector.getNextPushPromise(responseHandle).setPushPromiseListener(new PromiseListener(dataContext)); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, handleObj, null); + ResponseHandle responseHandle = (ResponseHandle) handleObj.getNativeData(HttpConstants.TRANSPORT_HANDLE); + if (responseHandle == null) { + throw HttpUtil.createHttpError("invalid http handle"); + } + clientConnector.getNextPushPromise(responseHandle).setPushPromiseListener(new PromiseListener(dataContext)); + return getResult(balFuture); + }); } private static class PromiseListener implements HttpClientConnectorListener { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetPromisedResponse.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetPromisedResponse.java index 0d2836aabb..1124292fc4 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetPromisedResponse.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetPromisedResponse.java @@ -27,6 +27,10 @@ import io.ballerina.stdlib.http.transport.message.Http2PushPromise; import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; +import java.util.concurrent.CompletableFuture; + +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; + /** * {@code GetPromisedResponse} action can be used to get a push response message associated with a * previous asynchronous invocation. @@ -35,15 +39,18 @@ public class GetPromisedResponse extends AbstractHTTPAction { public static Object getPromisedResponse(Environment env, BObject clientObj, BObject pushPromiseObj) { HttpClientConnector clientConnector = (HttpClientConnector) clientObj.getNativeData(HttpConstants.CLIENT); - DataContext dataContext = new DataContext(env, clientConnector, - pushPromiseObj, null); - Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, null); - if (http2PushPromise == null) { - throw HttpUtil.createHttpError("invalid push promise"); - } - clientConnector.getPushResponse(http2PushPromise). - setPushResponseListener(new PushResponseListener(dataContext), http2PushPromise.getPromisedStreamId()); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, pushPromiseObj, null); + Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, null); + if (http2PushPromise == null) { + throw HttpUtil.createHttpError("invalid push promise"); + } + clientConnector.getPushResponse(http2PushPromise). + setPushResponseListener(new PushResponseListener(dataContext), + http2PushPromise.getPromisedStreamId()); + return getResult(balFuture); + }); } private static class PushResponseListener implements HttpClientConnectorListener { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetResponse.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetResponse.java index 4694cc3ca8..dc9a9875c3 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetResponse.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/GetResponse.java @@ -27,6 +27,10 @@ import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; import io.ballerina.stdlib.http.transport.message.ResponseHandle; +import java.util.concurrent.CompletableFuture; + +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; + /** * {@code GetResponse} action can be used to fetch the response message for a previous asynchronous invocation. */ @@ -34,15 +38,17 @@ public class GetResponse extends AbstractHTTPAction { public static Object getResponse(Environment env, BObject clientObj, BObject handleObj) { HttpClientConnector clientConnector = (HttpClientConnector) clientObj.getNativeData(HttpConstants.CLIENT); - DataContext dataContext = new DataContext(env, clientConnector, handleObj, - null); - ResponseHandle responseHandle = (ResponseHandle) handleObj.getNativeData(HttpConstants.TRANSPORT_HANDLE); - if (responseHandle == null) { - throw HttpUtil.createHttpError("invalid http handle"); - } - clientConnector.getResponse(responseHandle). - setHttpConnectorListener(new ResponseListener(dataContext)); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, handleObj, null); + ResponseHandle responseHandle = (ResponseHandle) handleObj.getNativeData(HttpConstants.TRANSPORT_HANDLE); + if (responseHandle == null) { + throw HttpUtil.createHttpError("invalid http handle"); + } + clientConnector.getResponse(responseHandle). + setHttpConnectorListener(new ResponseListener(dataContext)); + return getResult(balFuture); + }); } private static class ResponseListener implements HttpConnectorListener { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HasPromise.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HasPromise.java index c100b351fb..83d569d134 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HasPromise.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HasPromise.java @@ -17,7 +17,6 @@ package io.ballerina.stdlib.http.api.client.actions; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.values.BObject; import io.ballerina.stdlib.http.api.HttpConstants; import io.ballerina.stdlib.http.api.HttpUtil; @@ -25,6 +24,10 @@ import io.ballerina.stdlib.http.transport.contract.HttpClientConnectorListener; import io.ballerina.stdlib.http.transport.message.ResponseHandle; +import java.util.concurrent.CompletableFuture; + +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; + /** * {@code HasPromise} action can be used to check whether a push promise is available. */ @@ -36,16 +39,19 @@ public static boolean hasPromise(Environment env, BObject clientObj, BObject han throw HttpUtil.createHttpError("invalid http handle"); } HttpClientConnector clientConnector = (HttpClientConnector) clientObj.getNativeData(HttpConstants.CLIENT); - clientConnector.hasPushPromise(responseHandle). - setPromiseAvailabilityListener(new PromiseAvailabilityCheckListener(env.markAsync())); - return false; + return (boolean) env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + clientConnector.hasPushPromise(responseHandle). + setPromiseAvailabilityListener(new PromiseAvailabilityCheckListener(balFuture)); + return getResult(balFuture); + }); } private static class PromiseAvailabilityCheckListener implements HttpClientConnectorListener { - private Future balFuture; + private final CompletableFuture balFuture; - PromiseAvailabilityCheckListener(Future balFuture) { + PromiseAvailabilityCheckListener(CompletableFuture balFuture) { this.balFuture = balFuture; } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HttpClientAction.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HttpClientAction.java index 7533bb6208..8f0fbaf172 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HttpClientAction.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/HttpClientAction.java @@ -19,10 +19,7 @@ package io.ballerina.stdlib.http.api.client.actions; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BArray; @@ -46,29 +43,24 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static io.ballerina.runtime.observability.ObservabilityConstants.KEY_OBSERVER_CONTEXT; import static io.ballerina.stdlib.http.api.HttpConstants.AND_SIGN; import static io.ballerina.stdlib.http.api.HttpConstants.ANN_NAME_QUERY; import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_ENDPOINT_CONFIG; import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_ENDPOINT_SERVICE_URI; import static io.ballerina.stdlib.http.api.HttpConstants.COLON; -import static io.ballerina.stdlib.http.api.HttpConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY; import static io.ballerina.stdlib.http.api.HttpConstants.EMPTY; import static io.ballerina.stdlib.http.api.HttpConstants.EQUAL_SIGN; import static io.ballerina.stdlib.http.api.HttpConstants.ESCAPE_SLASH; -import static io.ballerina.stdlib.http.api.HttpConstants.INBOUND_MESSAGE; import static io.ballerina.stdlib.http.api.HttpConstants.MAIN_STRAND; -import static io.ballerina.stdlib.http.api.HttpConstants.ORIGIN_HOST; -import static io.ballerina.stdlib.http.api.HttpConstants.POOLED_BYTE_BUFFER_FACTORY; import static io.ballerina.stdlib.http.api.HttpConstants.QUESTION_MARK; import static io.ballerina.stdlib.http.api.HttpConstants.QUOTATION_MARK; import static io.ballerina.stdlib.http.api.HttpConstants.REGEX_FOR_FIELD; -import static io.ballerina.stdlib.http.api.HttpConstants.REMOTE_ADDRESS; import static io.ballerina.stdlib.http.api.HttpConstants.SINGLE_SLASH; -import static io.ballerina.stdlib.http.api.HttpConstants.SRC_HANDLER; +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; /** * Utilities related to HTTP client actions. @@ -85,9 +77,12 @@ public static Object executeClientAction(Environment env, BObject httpClient, BS HttpCarbonMessage outboundRequestMsg = createOutboundRequestMsg(url, config, path.getValue(). replaceAll(HttpConstants.REGEX, HttpConstants.SINGLE_SLASH), requestObj); outboundRequestMsg.setHttpMethod(httpMethod.getValue()); - DataContext dataContext = new DataContext(env, clientConnector, requestObj, outboundRequestMsg); - executeNonBlockingAction(dataContext, false); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, requestObj, outboundRequestMsg); + executeNonBlockingAction(dataContext, false); + return getResult(balFuture); + }); } public static void rejectPromise(BObject clientObj, BObject pushPromiseObj) { @@ -153,11 +148,9 @@ public static Object get(Environment env, BObject client, BString path, Object h } public static Object headResource(Environment env, BObject client, BArray path, Object headers, BMap params) { - Object[] paramFeed = new Object[4]; + Object[] paramFeed = new Object[2]; paramFeed[0] = constructRequestPath(path, params); - paramFeed[1] = true; - paramFeed[2] = headers; - paramFeed[3] = true; + paramFeed[1] = headers; return invokeClientMethod(env, client, "head", paramFeed); } @@ -173,98 +166,59 @@ public static Object options(Environment env, BObject client, BString path, Obje public static Object execute(Environment env, BObject client, BString httpVerb, BString path, Object message, Object headers, Object mediaType, BTypedesc targetType) { - Object[] paramFeed = new Object[12]; + Object[] paramFeed = new Object[6]; paramFeed[0] = httpVerb; - paramFeed[1] = true; - paramFeed[2] = path; - paramFeed[3] = true; - paramFeed[4] = message; - paramFeed[5] = true; - paramFeed[6] = targetType; - paramFeed[7] = true; - paramFeed[8] = mediaType; - paramFeed[9] = true; - paramFeed[10] = headers; - paramFeed[11] = true; + paramFeed[1] = path; + paramFeed[2] = message; + paramFeed[3] = targetType; + paramFeed[4] = mediaType; + paramFeed[5] = headers; return invokeClientMethod(env, client, "processExecute", paramFeed); } public static Object forward(Environment env, BObject client, BString path, BObject message, BTypedesc targetType) { - Object[] paramFeed = new Object[6]; + Object[] paramFeed = new Object[3]; paramFeed[0] = path; - paramFeed[1] = true; - paramFeed[2] = message; - paramFeed[3] = true; - paramFeed[4] = targetType; - paramFeed[5] = true; + paramFeed[1] = message; + paramFeed[2] = targetType; return invokeClientMethod(env, client, "processForward", paramFeed); } private static Object invokeClientMethod(Environment env, BObject client, BString path, Object message, BTypedesc targetType, String methodName) { - Object[] paramFeed = new Object[6]; + Object[] paramFeed = new Object[3]; paramFeed[0] = path; - paramFeed[1] = true; - paramFeed[2] = message; - paramFeed[3] = true; - paramFeed[4] = targetType; - paramFeed[5] = true; + paramFeed[1] = message; + paramFeed[2] = targetType; return invokeClientMethod(env, client, methodName, paramFeed); } private static Object invokeClientMethod(Environment env, BObject client, BString path, Object message, Object mediaType, Object headers, BTypedesc targetType, String methodName) { - Object[] paramFeed = new Object[10]; + Object[] paramFeed = new Object[5]; paramFeed[0] = path; - paramFeed[1] = true; - paramFeed[2] = message; - paramFeed[3] = true; - paramFeed[4] = targetType; - paramFeed[5] = true; - paramFeed[6] = mediaType; - paramFeed[7] = true; - paramFeed[8] = headers; - paramFeed[9] = true; + paramFeed[1] = message; + paramFeed[2] = targetType; + paramFeed[3] = mediaType; + paramFeed[4] = headers; return invokeClientMethod(env, client, methodName, paramFeed); } private static Object invokeClientMethod(Environment env, BObject client, String methodName, Object[] paramFeed) { - Future balFuture = env.markAsync(); - Map propertyMap = getPropertiesToPropagate(env); - env.getRuntime().invokeMethodAsync(client, methodName, null, null, new Callback() { - @Override - public void notifySuccess(Object result) { - balFuture.complete(result); + return env.yieldAndRun(() -> { + String strandParentFunctionName = Objects.isNull(env.getStrandMetadata()) ? null : + env.getStrandMetadata().getParentFunctionName(); + if (Objects.nonNull(strandParentFunctionName) && strandParentFunctionName.equals("onMessage")) { + env.setStrandLocal(MAIN_STRAND, true); } - - @Override - public void notifyFailure(BError bError) { - BError invocationError = - HttpUtil.createHttpError("client method invocation failed: " + bError.getErrorMessage(), - HttpErrorType.CLIENT_ERROR, bError); - balFuture.complete(invocationError); - } - }, propertyMap, PredefinedTypes.TYPE_NULL, paramFeed); - return null; - } - - private static Map getPropertiesToPropagate(Environment env) { - String[] keys = {CURRENT_TRANSACTION_CONTEXT_PROPERTY, KEY_OBSERVER_CONTEXT, SRC_HANDLER, MAIN_STRAND, - POOLED_BYTE_BUFFER_FACTORY, REMOTE_ADDRESS, ORIGIN_HOST, INBOUND_MESSAGE}; - Map subMap = new HashMap<>(); - for (String key : keys) { - Object value = env.getStrandLocal(key); - if (value != null) { - subMap.put(key, value); + try { + return env.getRuntime().call(client, methodName, paramFeed); + } catch (BError bError) { + return HttpUtil.createHttpError("client method invocation failed: " + bError.getErrorMessage(), + HttpErrorType.CLIENT_ERROR, bError); } - } - String strandParentFunctionName = Objects.isNull(env.getStrandMetadata()) ? null : - env.getStrandMetadata().getParentFunctionName(); - if (Objects.nonNull(strandParentFunctionName) && strandParentFunctionName.equals("onMessage")) { - subMap.put(MAIN_STRAND, true); - } - return subMap; + }); } private static BString constructRequestPath(BArray pathArray, BMap params) { diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Submit.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Submit.java index 0373b7321e..ce7c32285d 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Submit.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/actions/Submit.java @@ -25,8 +25,11 @@ import io.ballerina.stdlib.http.transport.contract.HttpClientConnector; import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; +import java.util.concurrent.CompletableFuture; + import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_ENDPOINT_CONFIG; import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_ENDPOINT_SERVICE_URI; +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; /** * {@code Submit} action can be used to invoke a http call with any httpVerb in asynchronous manner. @@ -40,8 +43,11 @@ public static Object submit(Environment env, BObject httpClient, BString httpVer HttpClientConnector clientConnector = (HttpClientConnector) httpClient.getNativeData(HttpConstants.CLIENT); HttpCarbonMessage outboundRequestMsg = createOutboundRequestMsg(url, config, path.getValue(), requestObj); outboundRequestMsg.setHttpMethod(httpVerb.getValue()); - DataContext dataContext = new DataContext(env, clientConnector, requestObj, outboundRequestMsg); - executeNonBlockingAction(dataContext, true); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, clientConnector, requestObj, outboundRequestMsg); + executeNonBlockingAction(dataContext, true); + return getResult(balFuture); + }); } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternHttpDataSourceBuilder.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternHttpDataSourceBuilder.java index fc9498b0b4..5f0463201a 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternHttpDataSourceBuilder.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternHttpDataSourceBuilder.java @@ -19,7 +19,6 @@ package io.ballerina.stdlib.http.api.nativeimpl; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BObject; import io.ballerina.stdlib.http.api.HttpUtil; @@ -39,6 +38,7 @@ import java.io.InputStream; import java.util.Locale; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import static io.ballerina.stdlib.mime.util.EntityBodyHandler.constructBlobDataSource; import static io.ballerina.stdlib.mime.util.EntityBodyHandler.constructJsonDataSource; @@ -65,81 +65,96 @@ public static Object getNonBlockingByteArray(Environment env, BObject entityObj) if (isStreamingRequired(entityObj) || transportMessage == null) { return getByteArray(entityObj); } - - // access payload in non blocking manner - Future balFuture = null; try { Object messageDataSource = EntityBodyHandler.getMessageDataSource(entityObj); if (messageDataSource != null) { return getAlreadyBuiltByteArray(entityObj, messageDataSource); } - balFuture = env.markAsync(); - constructNonBlockingDataSource(balFuture, entityObj, SourceType.BLOB); } catch (Exception exception) { - return notifyError(balFuture, exception, "blob"); + return createError(exception, "blob"); } - return null; + // access payload in non-blocking manner + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + constructNonBlockingDataSource(balFuture, entityObj, SourceType.BLOB); + try { + return balFuture.get(); + } catch (Exception exception) { + return createError(exception, "blob"); + } + }); } public static Object getNonBlockingJson(Environment env, BObject entityObj) { if (isStreamingRequired(entityObj)) { return getJson(entityObj); } - - // access payload in non blocking manner - Future balFuture = null; try { Object dataSource = EntityBodyHandler.getMessageDataSource(entityObj); if (dataSource != null) { return getAlreadyBuiltJson(dataSource); } - balFuture = env.markAsync(); - constructNonBlockingDataSource(balFuture, entityObj, SourceType.JSON); } catch (Exception exception) { - return notifyError(balFuture, exception, "json"); + return createError(exception, "json"); } - return null; + // access payload in non-blocking manner + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + constructNonBlockingDataSource(balFuture, entityObj, SourceType.JSON); + try { + return balFuture.get(); + } catch (Exception exception) { + return createError(exception, "json"); + } + }); } public static Object getNonBlockingText(Environment env, BObject entityObj) { if (isStreamingRequired(entityObj)) { return getText(entityObj); } - - // access payload in non blocking manner - Future balFuture = null; try { Object dataSource = EntityBodyHandler.getMessageDataSource(entityObj); if (dataSource != null) { return io.ballerina.runtime.api.utils.StringUtils.fromString(MimeUtil.getMessageAsString(dataSource)); } - balFuture = env.markAsync(); - constructNonBlockingDataSource(balFuture, entityObj, SourceType.TEXT); } catch (Exception exception) { - return notifyError(balFuture, exception, "text"); + return createError(exception, "text"); } - return null; + // access payload in non-blocking manner + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + constructNonBlockingDataSource(balFuture, entityObj, SourceType.TEXT); + try { + return balFuture.get(); + } catch (Exception exception) { + return createError(exception, "text"); + } + }); } public static Object getNonBlockingXml(Environment env, BObject entityObj) { if (isStreamingRequired(entityObj)) { return getXml(entityObj); } - - // access payload in non blocking manner - Future balFuture = null; try { Object dataSource = EntityBodyHandler.getMessageDataSource(entityObj); if (dataSource != null) { return getAlreadyBuiltXml(dataSource); } - - balFuture = env.markAsync(); - constructNonBlockingDataSource(balFuture, entityObj, SourceType.XML); } catch (Exception exception) { - return notifyError(balFuture, exception, "xml"); + return createError(exception, "text"); } - return null; + // access payload in non-blocking manner + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + constructNonBlockingDataSource(balFuture, entityObj, SourceType.XML); + try { + return balFuture.get(); + } catch (Exception exception) { + return createError(exception, "text"); + } + }); } public static Object getByteChannel(BObject entityObj) { @@ -164,7 +179,7 @@ public static void populateInputStream(BObject entityObj) { } } - public static void constructNonBlockingDataSource(Future balFuture, BObject entity, + public static void constructNonBlockingDataSource(CompletableFuture balFuture, BObject entity, SourceType sourceType) { HttpCarbonMessage inboundMessage = extractTransportMessageFromEntity(entity); if (inboundMessage.isContentReleased()) { @@ -214,7 +229,11 @@ public void onError(Exception ex) { }); } - private static Object notifyError(Future balFuture, Exception exception, String type) { + private static Object notifyError(Exception exception, String type) { + return createError(exception, type); + } + + private static Object notifyError(CompletableFuture balFuture, Exception exception, String type) { BError error = (BError) createError(exception, type); if (balFuture != null) { setReturnValuesAndNotify(balFuture, error); @@ -223,22 +242,22 @@ private static Object notifyError(Future balFuture, Exception exception, String return error; } - private static void createErrorAndNotify(Future balFuture, String errMsg) { + private static void createErrorAndNotify(CompletableFuture balFuture, String errMsg) { BError error = MimeUtil.createError(PARSER_ERROR, errMsg); setReturnValuesAndNotify(balFuture, error); } - private static void setReturnValuesAndNotify(Future balFuture, Object result) { + private static void setReturnValuesAndNotify(CompletableFuture balFuture, Object result) { balFuture.complete(result); } - private static void updateDataSourceAndNotify(Future balFuture, BObject entityObj, + private static void updateDataSourceAndNotify(CompletableFuture balFuture, BObject entityObj, Object result) { updateDataSource(entityObj, result); setReturnValuesAndNotify(balFuture, result); } - private static void updateJsonDataSourceAndNotify(Future balFuture, BObject entityObj, + private static void updateJsonDataSourceAndNotify(CompletableFuture balFuture, BObject entityObj, Object result) { updateJsonDataSource(entityObj, result); setReturnValuesAndNotify(balFuture, result); diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternResponseProcessor.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternResponseProcessor.java index ac590a6d6f..ff6fdf8bd3 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternResponseProcessor.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternResponseProcessor.java @@ -18,10 +18,9 @@ package io.ballerina.stdlib.http.api.nativeimpl; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.async.Callback; +import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; @@ -252,30 +251,18 @@ private static Object generateStatusCodeResponseType(BObject response, boolean r if (statusCodeRecordType.getFields().containsKey(STATUS_CODE_RESPONSE_BODY_FIELD)) { payloadType = statusCodeRecordType.getFields().get(STATUS_CODE_RESPONSE_BODY_FIELD).getFieldType(); } - Object[] paramFeed = getParamFeedForStatusCodeBinding(requireValidation, statusCodeRecordType, payloadType, - status, headers, mediaType); - return getStatusCodeResponse(env, response, paramFeed); - } - - private static Object[] getParamFeedForStatusCodeBinding(boolean requireValidation, RecordType statusCodeType, - Type payloadType, Object status, Object headers, - Object mediaType) { - Object[] paramFeed = new Object[14]; - paramFeed[0] = Objects.isNull(payloadType) ? null : ValueCreator.createTypedescValue(payloadType); - paramFeed[1] = true; - paramFeed[2] = ValueCreator.createTypedescValue(statusCodeType); - paramFeed[3] = true; - paramFeed[4] = requireValidation; - paramFeed[5] = true; - paramFeed[6] = status; - paramFeed[7] = true; - paramFeed[8] = headers; - paramFeed[9] = true; - paramFeed[10] = mediaType; - paramFeed[11] = true; - paramFeed[12] = isDefaultStatusCodeResponseType(statusCodeType); - paramFeed[13] = true; - return paramFeed; + try { + return env.getRuntime().call(response, BUILD_STATUS_CODE_RESPONSE, + Objects.isNull(payloadType) ? null : ValueCreator.createTypedescValue(payloadType), + ValueCreator.createTypedescValue(statusCodeRecordType).getDescribingType(), + requireValidation, status, headers, mediaType, + isDefaultStatusCodeResponseType(statusCodeRecordType)); + } catch (BError error) { + return createHttpError(STATUS_CODE_RES_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, error); + } catch (Throwable throwable) { + return createHttpError(STATUS_CODE_RES_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, + ErrorCreator.createError(throwable)); + } } private static Object getHeaders(BObject response, boolean requireValidation, RecordType statusCodeRecordType) { @@ -519,56 +506,29 @@ private static Object validateConstraints(boolean requireValidation, Object conv } private static Object getStatusCodeResponseBindingError(Environment env, BObject response, String reasonPhrase) { - Future balFuture = env.markAsync(); - Callback returnCallback = getReturnCallback(balFuture, APPLICATION_RES_ERROR_CREATION_FAILED); - Object[] paramFeed = new Object[2]; - paramFeed[0] = StringUtils.fromString(reasonPhrase); - paramFeed[1] = true; - env.getRuntime().invokeMethodAsyncSequentially(response, GET_STATUS_CODE_RESPONSE_BINDING_ERROR, null, - ModuleUtils.getNotifySuccessMetaData(), returnCallback, null, PredefinedTypes.TYPE_ERROR, paramFeed); - return null; + try { + return env.getRuntime().call(response, GET_STATUS_CODE_RESPONSE_BINDING_ERROR, + StringUtils.fromString(reasonPhrase)); + } catch (BError error) { + return createHttpError(APPLICATION_RES_ERROR_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, error); + } catch (Throwable throwable) { + return createHttpError(APPLICATION_RES_ERROR_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, + ErrorCreator.createError(throwable)); + } } private static Object getStatusCodeResponseDataBindingError(Environment env, BObject response, String reasonPhrase, BError cause, boolean isDefaultStatusCodeResponse, String errorType) { - Future balFuture = env.markAsync(); - Callback returnCallback = getReturnCallback(balFuture, APPLICATION_RES_ERROR_CREATION_FAILED); - Object[] paramFeed = new Object[8]; - paramFeed[0] = StringUtils.fromString(reasonPhrase); - paramFeed[1] = true; - paramFeed[2] = isDefaultStatusCodeResponse; - paramFeed[3] = true; - paramFeed[4] = StringUtils.fromString(errorType); - paramFeed[5] = true; - paramFeed[6] = cause; - paramFeed[7] = true; - env.getRuntime().invokeMethodAsyncSequentially(response, GET_STATUS_CODE_RESPONSE_DATA_BINDING_ERROR, null, - ModuleUtils.getNotifySuccessMetaData(), returnCallback, null, PredefinedTypes.TYPE_ERROR, paramFeed); - return null; - } - - private static Object getStatusCodeResponse(Environment env, BObject response, Object[] paramFeed) { - Future balFuture = env.markAsync(); - Callback returnCallback = getReturnCallback(balFuture, STATUS_CODE_RES_CREATION_FAILED); - env.getRuntime().invokeMethodAsyncSequentially(response, BUILD_STATUS_CODE_RESPONSE, null, - ModuleUtils.getNotifySuccessMetaData(), returnCallback, null, PredefinedTypes.TYPE_ANY, - paramFeed); - return null; - } - - private static Callback getReturnCallback(Future balFuture, String errorMessage) { - return new Callback() { - @Override - public void notifySuccess(Object result) { - balFuture.complete(result); - } - - @Override - public void notifyFailure(BError bError) { - BError error = createHttpError(errorMessage, STATUS_CODE_RESPONSE_BINDING_ERROR, bError); - balFuture.complete(error); - } - }; + try { + return env.getRuntime().call(response, GET_STATUS_CODE_RESPONSE_DATA_BINDING_ERROR, + StringUtils.fromString(reasonPhrase), isDefaultStatusCodeResponse, + StringUtils.fromString(errorType), cause); + } catch (BError error) { + return createHttpError(APPLICATION_RES_ERROR_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, error); + } catch (Throwable throwable) { + return createHttpError(APPLICATION_RES_ERROR_CREATION_FAILED, STATUS_CODE_RESPONSE_BINDING_ERROR, + ErrorCreator.createError(throwable)); + } } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternUtils.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternUtils.java index fcd128b41b..79e9e23422 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternUtils.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternUtils.java @@ -17,10 +17,12 @@ package io.ballerina.stdlib.http.api.nativeimpl; import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; @@ -29,6 +31,7 @@ import java.util.Objects; import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -115,4 +118,14 @@ private static Optional extractFieldName(BMap value) { } return Optional.of(overrideName); } + + public static Object getResult(CompletableFuture balFuture) { + try { + return balFuture.get(); + } catch (BError bError) { + return bError; + } catch (Throwable throwable) { + return ErrorCreator.createError(throwable); + } + } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Promise.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Promise.java index a5d1c5e88a..65c6943109 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Promise.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Promise.java @@ -26,20 +26,27 @@ import io.ballerina.stdlib.http.transport.message.Http2PushPromise; import io.ballerina.stdlib.http.transport.message.HttpCarbonMessage; +import java.util.concurrent.CompletableFuture; + +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; + /** * {@code Promise} is the extern function to respond back to the client with a PUSH_PROMISE frame. */ public class Promise extends ConnectionAction { public static Object promise(Environment env, BObject connectionObj, BObject pushPromiseObj) { HttpCarbonMessage inboundRequestMsg = HttpUtil.getCarbonMsg(connectionObj, null); - DataContext dataContext = new DataContext(env, inboundRequestMsg); - HttpUtil.serverConnectionStructCheck(inboundRequestMsg); + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, inboundRequestMsg); + HttpUtil.serverConnectionStructCheck(inboundRequestMsg); - Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, - HttpUtil.createHttpPushPromise(pushPromiseObj)); - HttpResponseFuture outboundRespStatusFuture = HttpUtil.pushPromise(inboundRequestMsg, http2PushPromise); - setResponseConnectorListener(dataContext, outboundRespStatusFuture); - return null; + Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, + HttpUtil.createHttpPushPromise(pushPromiseObj)); + HttpResponseFuture outboundRespStatusFuture = HttpUtil.pushPromise(inboundRequestMsg, http2PushPromise); + setResponseConnectorListener(dataContext, outboundRespStatusFuture); + return getResult(balFuture); + }); } private Promise() {} diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/PushPromisedResponse.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/PushPromisedResponse.java index 06766aa8e5..44fa345aca 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/PushPromisedResponse.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/PushPromisedResponse.java @@ -32,8 +32,10 @@ import io.ballerina.stdlib.mime.util.EntityBodyHandler; import java.io.OutputStream; +import java.util.concurrent.CompletableFuture; import static io.ballerina.stdlib.http.api.HttpUtil.extractEntity; +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; /** * {@code PushPromisedResponse} is the extern function to respond back the client with Server Push response. @@ -43,20 +45,22 @@ public class PushPromisedResponse extends ConnectionAction { public static Object pushPromisedResponse(Environment env, BObject connectionObj, BObject pushPromiseObj, BObject outboundResponseObj) { HttpCarbonMessage inboundRequestMsg = HttpUtil.getCarbonMsg(connectionObj, null); - DataContext dataContext = new DataContext(env, inboundRequestMsg); - HttpUtil.serverConnectionStructCheck(inboundRequestMsg); - - Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, null); - if (http2PushPromise == null) { - throw ErrorCreator.createError(StringUtils.fromString("invalid push promise")); - } - - HttpCarbonMessage outboundResponseMsg = HttpUtil - .getCarbonMsg(outboundResponseObj, HttpUtil.createHttpCarbonMessage(false)); - HttpUtil.prepareOutboundResponse(connectionObj, inboundRequestMsg, outboundResponseMsg, outboundResponseObj); - pushResponseRobust(dataContext, inboundRequestMsg, outboundResponseObj, outboundResponseMsg, - http2PushPromise); - return null; + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + DataContext dataContext = new DataContext(env, balFuture, inboundRequestMsg); + HttpUtil.serverConnectionStructCheck(inboundRequestMsg); + Http2PushPromise http2PushPromise = HttpUtil.getPushPromise(pushPromiseObj, null); + if (http2PushPromise == null) { + throw ErrorCreator.createError(StringUtils.fromString("invalid push promise")); + } + HttpCarbonMessage outboundResponseMsg = HttpUtil + .getCarbonMsg(outboundResponseObj, HttpUtil.createHttpCarbonMessage(false)); + HttpUtil.prepareOutboundResponse(connectionObj, inboundRequestMsg, outboundResponseMsg, + outboundResponseObj); + pushResponseRobust(dataContext, inboundRequestMsg, outboundResponseObj, outboundResponseMsg, + http2PushPromise); + return getResult(balFuture); + }); } private static void pushResponseRobust(DataContext dataContext, HttpCarbonMessage requestMessage, diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Respond.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Respond.java index 71e30ceaf8..155eaadf9c 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Respond.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/connection/Respond.java @@ -20,9 +20,6 @@ import io.ballerina.runtime.api.Environment; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.types.ObjectType; -import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.observability.ObserveUtils; @@ -46,12 +43,14 @@ import org.slf4j.LoggerFactory; import java.util.List; +import java.util.concurrent.CompletableFuture; import static io.ballerina.runtime.observability.ObservabilityConstants.PROPERTY_KEY_HTTP_STATUS_CODE; import static io.ballerina.stdlib.http.api.HttpConstants.INTERCEPTOR_SERVICES_REGISTRIES; import static io.ballerina.stdlib.http.api.HttpConstants.OBSERVABILITY_CONTEXT_PROPERTY; import static io.ballerina.stdlib.http.api.HttpConstants.RESPONSE_CACHE_CONTROL_FIELD; import static io.ballerina.stdlib.http.api.HttpConstants.RESPONSE_STATUS_CODE_FIELD; +import static io.ballerina.stdlib.http.api.nativeimpl.ExternUtils.getResult; import static io.ballerina.stdlib.http.api.nativeimpl.pipelining.PipeliningHandler.executePipeliningLogic; import static io.ballerina.stdlib.http.api.nativeimpl.pipelining.PipeliningHandler.pipeliningRequired; import static io.ballerina.stdlib.http.api.nativeimpl.pipelining.PipeliningHandler.setPipeliningListener; @@ -69,13 +68,21 @@ public static Object nativeRespondError(Environment env, BObject connectionObj, BError error) { HttpCarbonMessage inboundRequest = HttpUtil.getCarbonMsg(connectionObj, null); inboundRequest.setProperty(HttpConstants.INTERCEPTOR_SERVICE_ERROR, error); - return nativeRespondWithDataCtx(env, connectionObj, outboundResponseObj, - new DataContext(env, inboundRequest)); + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + nativeRespondWithDataCtx(env, connectionObj, outboundResponseObj, new DataContext(env, balFuture, + inboundRequest)); + return getResult(balFuture); + }); } public static Object nativeRespond(Environment env, BObject connectionObj, BObject outboundResponseObj) { - return nativeRespondWithDataCtx(env, connectionObj, outboundResponseObj, - new DataContext(env, HttpUtil.getCarbonMsg(connectionObj, null))); + return env.yieldAndRun(() -> { + CompletableFuture balFuture = new CompletableFuture<>(); + nativeRespondWithDataCtx(env, connectionObj, outboundResponseObj, new DataContext(env, + balFuture, HttpUtil.getCarbonMsg(connectionObj, null))); + return getResult(balFuture); + }); } public static Object nativeRespondWithDataCtx(Environment env, BObject connectionObj, BObject outboundResponseObj, @@ -247,20 +254,18 @@ private static void startInterceptResponseMethod(HttpCarbonMessage inboundMessag Runtime runtime = interceptorServicesRegistry.getRuntime(); Object[] signatureParams = HttpDispatcher.getRemoteSignatureParameters(service, outboundResponseObj, callerObj, inboundMessage, runtime); - Callback callback = new HttpResponseInterceptorUnitCallback(inboundMessage, callerObj, outboundResponseObj, + HttpResponseInterceptorUnitCallback callback = new HttpResponseInterceptorUnitCallback(inboundMessage, + callerObj, outboundResponseObj, env, dataContext, runtime, interceptorServicesRegistry.isPossibleLastInterceptor()); inboundMessage.removeProperty(HttpConstants.INTERCEPTOR_SERVICE_ERROR); String methodName = service.getServiceType().equals(HttpConstants.RESPONSE_ERROR_INTERCEPTOR) ? HttpConstants.INTERCEPT_RESPONSE_ERROR : HttpConstants.INTERCEPT_RESPONSE; - - ObjectType serviceType = (ObjectType) TypeUtils.getReferredType(TypeUtils.getType(serviceObj)); - if (serviceType.isIsolated() && serviceType.isIsolated(methodName)) { - runtime.invokeMethodAsyncConcurrently(serviceObj, methodName, null, null, - callback, null, service.getRemoteMethod().getReturnType(), signatureParams); - } else { - runtime.invokeMethodAsyncSequentially(serviceObj, methodName, null, null, - callback, null, service.getRemoteMethod().getReturnType(), signatureParams); + try { + Object result = runtime.call(serviceObj, methodName, signatureParams); + callback.handleResult(result); + } catch (BError bError) { + callback.handlePanic(bError); } } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/Util.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/Util.java index 8df9d9ada1..ef1a4a6ec6 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/Util.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/Util.java @@ -145,6 +145,7 @@ private Util() { private static final Logger LOG = LoggerFactory.getLogger(Util.class); public static final String HTTP_1_1 = "http/1.1"; + private static final float EPSILON = 0.00001f; private static String getStringValue(HttpCarbonMessage msg, String key, String defaultValue) { String value = (String) msg.getProperty(key); @@ -198,7 +199,7 @@ private static void setOutboundRespHeaders(HttpCarbonMessage outboundResponseMsg outboundResponseMsg.setHeader(HttpHeaderNames.CONNECTION.toString(), Constants.CONNECTION_CLOSE); } else if (keepAlive && (Float.valueOf(inboundReqHttpVersion) < Constants.HTTP_1_1)) { outboundResponseMsg.setHeader(HttpHeaderNames.CONNECTION.toString(), Constants.CONNECTION_KEEP_ALIVE); - } else if (Float.valueOf(inboundReqHttpVersion) == Constants.HTTP_1_1 + } else if (Math.abs(Float.valueOf(inboundReqHttpVersion) - Constants.HTTP_1_1) < EPSILON && HttpUtil.hasEventStreamContentType(outboundResponseMsg)) { outboundResponseMsg.setHeader(HttpHeaderNames.CONNECTION.toString(), Constants.CONNECTION_KEEP_ALIVE); } else { diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/sender/states/http2/SendingHeaders.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/sender/states/http2/SendingHeaders.java index 7298c3e1db..fbea225529 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/sender/states/http2/SendingHeaders.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/sender/states/http2/SendingHeaders.java @@ -77,7 +77,6 @@ public class SendingHeaders implements SenderState { private final Http2ConnectionEncoder encoder; private final Http2ClientChannel http2ClientChannel; private int streamId; - private boolean continueHeader; public SendingHeaders(Http2TargetHandler http2TargetHandler, Http2RequestWriter http2RequestWriter) { this.http2TargetHandler = http2TargetHandler; diff --git a/native/src/test/java/io/ballerina/stdlib/http/api/TestUtils.java b/native/src/test/java/io/ballerina/stdlib/http/api/TestUtils.java index c96790fcea..d85a2b5f9e 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/api/TestUtils.java +++ b/native/src/test/java/io/ballerina/stdlib/http/api/TestUtils.java @@ -71,11 +71,6 @@ public BMap getAnnotations() { return null; }; - @Override - public Type[] getParameterTypes() { - return new Type[0]; - } - @Override public Type getReturnType() { return null; diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolProxyTestCase.java b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolProxyTestCase.java index 2027b0d7b2..1a439793ff 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolProxyTestCase.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolProxyTestCase.java @@ -42,9 +42,7 @@ import java.net.URI; import java.util.HashMap; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; import static org.testng.Assert.assertEquals; import static org.testng.AssertJUnit.assertNotNull; @@ -56,9 +54,7 @@ public class ConnectionPoolProxyTestCase { private static final Logger LOG = LoggerFactory.getLogger(ConnectionPoolProxyTestCase.class); - private Future requestTwoResponse; - private ExecutorService executor = Executors.newFixedThreadPool(2); - + private CompletableFuture requestTwoResponse = new CompletableFuture<>(); private HttpWsConnectorFactory httpWsConnectorFactory; private ServerConnector serverConnector; private HttpServer httpServer; @@ -86,23 +82,29 @@ public void setup() { @Test public void testConnectionReuseForProxy() { try { - Future requestOneResponse; - Future requestThreeResponse; + final CompletableFuture requestOneResponse = new CompletableFuture<>(); + final CompletableFuture requestThreeResponse = new CompletableFuture<>(); ClientWorker clientWorkerOne = new ClientWorker(); ClientWorker clientWorkerTwo = new ClientWorker(); ClientWorker clientWorkerThree = new ClientWorker(); - requestOneResponse = executor.submit(clientWorkerOne); + Thread.startVirtualThread(() -> { + requestOneResponse.complete(clientWorkerOne.call()); + }); // While the first request is being processed by the back-end, // we send the second request which forces the client connector to // create a new connection. Thread.sleep(2500); - requestTwoResponse = executor.submit(clientWorkerTwo); + Thread.startVirtualThread(() -> { + requestTwoResponse.complete(clientWorkerTwo.call()); + }); assertNotNull(requestOneResponse.get()); - requestThreeResponse = executor.submit(clientWorkerThree); + Thread.startVirtualThread(() -> { + requestThreeResponse.complete(clientWorkerThree.call()); + }); assertEquals(requestOneResponse.get(), requestThreeResponse.get()); } catch (Exception e) { @@ -127,7 +129,7 @@ private class ClientWorker implements Callable { private String response; @Override - public String call() throws Exception { + public String call() { try { URI baseURI = URI.create(String.format("http://%s:%d", "localhost", TestUtil.SERVER_CONNECTOR_PORT)); HttpURLConnection urlConn = TestUtil diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolTimeoutProxyTestCase.java b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolTimeoutProxyTestCase.java index 1934959bbe..8c25529cc0 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolTimeoutProxyTestCase.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/ConnectionPoolTimeoutProxyTestCase.java @@ -44,9 +44,7 @@ import java.net.URI; import java.util.HashMap; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertNotNull; @@ -58,7 +56,6 @@ public class ConnectionPoolTimeoutProxyTestCase { private static final Logger LOG = LoggerFactory.getLogger(ConnectionPoolTimeoutProxyTestCase.class); - private ExecutorService executor = Executors.newFixedThreadPool(2); private HttpWsConnectorFactory httpWsConnectorFactory; private ServerConnector serverConnector; private HttpServer httpServer; @@ -91,15 +88,19 @@ public void setup() { + "This test case validates that.") public void connectionPoolTimeoutProxyTestCase() { try { - Future requestOneResponse; - Future requestTwoResponse; + final CompletableFuture requestOneResponse = new CompletableFuture<>(); + final CompletableFuture requestTwoResponse = new CompletableFuture<>(); ClientWorker clientWorker = new ClientWorker(); - requestOneResponse = executor.submit(clientWorker); + Thread.startVirtualThread(() -> { + requestOneResponse.complete(clientWorker.call()); + }); assertNotNull(requestOneResponse.get()); - requestTwoResponse = executor.submit(clientWorker); + Thread.startVirtualThread(() -> { + requestTwoResponse.complete(clientWorker.call()); + }); assertNotEquals(requestOneResponse.get(), requestTwoResponse.get()); } catch (Exception e) { TestUtil.handleException("IOException occurred while running testConnectionReuseForProxy", e); @@ -111,7 +112,7 @@ private class ClientWorker implements Callable { private String response; @Override - public String call() throws Exception { + public String call() { try { URI baseURI = URI.create(String.format("http://%s:%d", "localhost", TestUtil.SERVER_CONNECTOR_PORT)); HttpResponse httpResponse = Unirest.post(baseURI.resolve("/").toString()) diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/PerClientPoolTestCase.java b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/PerClientPoolTestCase.java index 61cdfd40cb..2e907587b9 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/PerClientPoolTestCase.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/connectionpool/PerClientPoolTestCase.java @@ -42,9 +42,7 @@ import java.net.URI; import java.util.HashMap; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; import static org.junit.Assert.assertNotEquals; import static org.testng.AssertJUnit.assertNotNull; @@ -58,8 +56,6 @@ public class PerClientPoolTestCase { private static final Logger LOG = LoggerFactory.getLogger(PerClientPoolTestCase.class); - private ExecutorService executor = Executors.newFixedThreadPool(2); - private HttpWsConnectorFactory httpWsConnectorFactory; private ServerConnector serverConnector; private HttpServer httpServer; @@ -86,15 +82,19 @@ public void setup() { @Test public void testPerClientConnectionPool() { try { - Future requestOneResponse; - Future requestTwoResponse; + final CompletableFuture requestOneResponse = new CompletableFuture<>(); + final CompletableFuture requestTwoResponse = new CompletableFuture<>(); ClientWorker clientWorkerOne = new ClientWorker(); ClientWorker clientWorkerTwo = new ClientWorker(); - requestOneResponse = executor.submit(clientWorkerOne); + Thread.startVirtualThread(() -> { + requestOneResponse.complete(clientWorkerOne.call()); + }); assertNotNull(requestOneResponse.get()); - requestTwoResponse = executor.submit(clientWorkerTwo); + Thread.startVirtualThread(() -> { + requestTwoResponse.complete(clientWorkerTwo.call()); + }); assertNotNull(requestTwoResponse.get()); assertNotEquals(requestOneResponse.get(), requestTwoResponse.get()); @@ -119,7 +119,7 @@ private class ClientWorker implements Callable { private String response; @Override - public String call() throws Exception { + public String call() { try { URI baseURI = URI.create(String.format("http://%s:%d", "localhost", TestUtil.SERVER_CONNECTOR_PORT)); HttpURLConnection urlConn = TestUtil.request(baseURI, "/", HttpMethod.POST.name(), true); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/DumbMessageListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/DumbMessageListener.java index e6bea3767a..6784e2b331 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/DumbMessageListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/DumbMessageListener.java @@ -26,9 +26,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * A class implements a DumbMessageListener. DumbMessageListener is responsible for just reading the inbound request * payload and doing nothing. @@ -36,11 +33,9 @@ public class DumbMessageListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(DumbMessageListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { do { HttpContent httpContent = httpRequest.getHttpContent(); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoMessageListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoMessageListener.java index 4ebcba078c..0c1778ff99 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoMessageListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoMessageListener.java @@ -34,20 +34,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * A Message processor which echos the incoming message. */ public class EchoMessageListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(EchoMessageListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoStreamingMessageListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoStreamingMessageListener.java index a3672caa17..5427268607 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoStreamingMessageListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/EchoStreamingMessageListener.java @@ -32,21 +32,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * A Message processor which echos the incoming message. */ public class EchoStreamingMessageListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(EchoStreamingMessageListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); private Exception receivedException; @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/GetFullMessageListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/GetFullMessageListener.java index 764a1696aa..b5cb5712be 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/GetFullMessageListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/GetFullMessageListener.java @@ -34,9 +34,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * This class implements GetFullMessageListener. GetFullMessageListener is responsible for echoing back the * request payload using getFullHttpCarbonMessage API. @@ -44,12 +41,11 @@ public class GetFullMessageListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(GetFullMessageListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> httpRequest.getFullHttpCarbonMessage().addListener(new FullHttpMessageListener() { - @Override + Thread.startVirtualThread(() -> httpRequest.getFullHttpCarbonMessage() + .addListener(new FullHttpMessageListener() { + @Override public void onComplete(HttpCarbonMessage httpCarbonMessage) { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/MockHalfResponseMessageListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/MockHalfResponseMessageListener.java index 2935d7220f..723f6ad366 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/MockHalfResponseMessageListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/MockHalfResponseMessageListener.java @@ -36,9 +36,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * This class implements a MockHalfResponseMessageListener. MockHalfResponseMessageListener is responsible for * reading the inbound response and sending back a half response. @@ -46,11 +43,9 @@ public class MockHalfResponseMessageListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(MockHalfResponseMessageListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationListener.java index b784d0abbb..796b18918f 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationListener.java @@ -39,8 +39,6 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * A Message Processor which creates Request and Response. @@ -49,7 +47,6 @@ public class RequestResponseCreationListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(RequestResponseCreationListener.class); private String responseValue; - private ExecutorService executor = Executors.newSingleThreadExecutor(); public RequestResponseCreationListener(String responseValue) { this.responseValue = responseValue; @@ -57,7 +54,7 @@ public RequestResponseCreationListener(String responseValue) { @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { String requestValue = TestUtil .getStringFromInputStream(new HttpMessageDataStreamer(httpRequest).getInputStream()); @@ -82,7 +79,7 @@ public void onMessage(HttpCarbonMessage httpRequest) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpResponse) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { String responseValue = TestUtil.getStringFromInputStream( new HttpMessageDataStreamer(httpResponse).getInputStream()); String responseStringValue = responseValue + ":" + requestValue; diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationStreamingListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationStreamingListener.java index e3121d0a90..40820877b9 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationStreamingListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseCreationStreamingListener.java @@ -38,8 +38,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * A class which read and write content through streams. @@ -48,11 +46,9 @@ public class RequestResponseCreationStreamingListener implements HttpConnectorLi private static final Logger LOG = LoggerFactory.getLogger(RequestResponseCreationStreamingListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpMessageDataStreamer streamer = new HttpMessageDataStreamer(httpRequest); InputStream inputStream = streamer.getInputStream(); @@ -73,7 +69,7 @@ public void onMessage(HttpCarbonMessage httpRequest) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { HttpCarbonMessage newMsg = httpMessage.cloneCarbonMessageWithOutData(); OutputStream outputStream = new HttpMessageDataStreamer(newMsg).getOutputStream(); try { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformListener.java index 1853600efd..549ae21aeb 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformListener.java @@ -39,8 +39,6 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * Transform message in request and response path. @@ -49,7 +47,6 @@ public class RequestResponseTransformListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(RequestResponseTransformListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); private String responseValue; private String requestValue; @@ -59,7 +56,7 @@ public RequestResponseTransformListener(String responseValue) { @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { requestValue = TestUtil.getStringFromInputStream( new HttpMessageDataStreamer(httpRequest).getInputStream()); @@ -83,7 +80,7 @@ public void onMessage(HttpCarbonMessage httpRequest) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { String content = TestUtil.getStringFromInputStream( new HttpMessageDataStreamer(httpMessage).getInputStream()); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformStreamingListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformStreamingListener.java index 7848c01621..7341339752 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformStreamingListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/RequestResponseTransformStreamingListener.java @@ -38,8 +38,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * Streaming processor which reads from same and write to same message. @@ -47,11 +45,10 @@ public class RequestResponseTransformStreamingListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(RequestResponseTransformStreamingListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequestMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { InputStream inputStream = new HttpMessageDataStreamer(httpRequestMessage).getInputStream(); OutputStream outputStream = new HttpMessageDataStreamer(httpRequestMessage).getOutputStream(); @@ -68,7 +65,7 @@ public void onMessage(HttpCarbonMessage httpRequestMessage) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpResponse) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { InputStream inputS = new HttpMessageDataStreamer(httpResponse).getInputStream(); OutputStream outputS = new HttpMessageDataStreamer(httpResponse).getOutputStream(); try { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/ResponseStreamingWithoutBufferingListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/ResponseStreamingWithoutBufferingListener.java index b89a4b4848..3b5e10009f 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/ResponseStreamingWithoutBufferingListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/ResponseStreamingWithoutBufferingListener.java @@ -28,9 +28,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderNames.TRANSFER_ENCODING; @@ -46,11 +43,10 @@ public class ResponseStreamingWithoutBufferingListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(RequestResponseTransformStreamingListener.class); - private ExecutorService executor = Executors.newCachedThreadPool(); @Override public void onMessage(HttpCarbonMessage inboundRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { HttpCarbonMessage outboundResponse = new HttpCarbonMessage(new DefaultHttpResponse(HTTP_1_1, OK)); outboundResponse.setHeader(CONNECTION.toString(), KEEP_ALIVE.toString()); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/TrailerHeaderListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/TrailerHeaderListener.java index 39350b864f..a2651159e2 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/TrailerHeaderListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contentaware/listeners/TrailerHeaderListener.java @@ -41,8 +41,6 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * {@code TrailerHeaderListener} is a HttpConnectorListener which receives messages and respond back with @@ -53,7 +51,6 @@ public class TrailerHeaderListener extends EchoMessageListener { private static final Logger LOG = LoggerFactory.getLogger(TrailerHeaderListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); private HttpHeaders expectedTrailer; private MessageType messageType; @@ -75,7 +72,7 @@ public void setTrailer(HttpHeaders trailers) { @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { switch (messageType) { case RESPONSE: HttpCarbonMessage httpResponse = getHttpCarbonMessage(); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/common/FrameLoggerTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/common/FrameLoggerTest.java index 9c5b4c2b67..752c94e4a9 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/common/FrameLoggerTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/common/FrameLoggerTest.java @@ -20,13 +20,12 @@ import io.ballerina.stdlib.http.transport.contract.Constants; import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http2.Http2FrameLogger; import org.junit.Assert; import org.testng.annotations.Test; -import java.nio.ByteBuffer; - import static io.netty.handler.logging.LogLevel.TRACE; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -42,18 +41,14 @@ public void testFrameLoggerLog() { Assert.assertNotNull(frameLogger); Http2FrameLogger.Direction direction = mock(Http2FrameLogger.Direction.class); ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); - ByteBuf data = mock(ByteBuf.class); - ByteBuffer buffer = mock(ByteBuffer.class); + ByteBuf data = Unpooled.buffer(); when(direction.name()).thenReturn("testDirection"); - when(data.readableBytes()).thenReturn(0); - when(data.nioBuffer()).thenReturn(buffer); - when(buffer.remaining()).thenReturn(0); + data.clear(); frameLogger.logData(direction, ctx, 5, data, 10, true); - - when(data.readableBytes()).thenReturn(16); + data.writeBytes(new byte[16]); frameLogger.logData(direction, ctx, 5, data, 10, true); - - when(data.readableBytes()).thenReturn(10); + data.clear(); + data.writeBytes(new byte[10]); frameLogger.logData(direction, ctx, 5, data, 10, true); } diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpTraceLoggingHandlerTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpTraceLoggingHandlerTest.java index b519cb8334..16cefeb67a 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpTraceLoggingHandlerTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpTraceLoggingHandlerTest.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufHolder; +import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelId; @@ -29,7 +30,6 @@ import org.testng.annotations.Test; import java.net.SocketAddress; -import java.nio.ByteBuffer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -113,24 +113,20 @@ public void testChannelRead() { @Test public void testChannelReadWithByteBuf() { HttpTraceLoggingHandler httpTraceLoggingHandler = new HttpTraceLoggingHandler(LogLevel.INFO); + ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); Channel channel = mock(Channel.class); ChannelId channelId = mock(ChannelId.class); - ByteBuf msg = mock(ByteBuf.class); when(ctx.channel()).thenReturn(channel); when(channel.id()).thenReturn(channelId); when(channelId.asShortText()).thenReturn("channelId"); + ByteBuf msg = Unpooled.buffer(); httpTraceLoggingHandler.channelRead(ctx, msg); - - ByteBuffer byteBuffer = mock(ByteBuffer.class); - when(byteBuffer.remaining()).thenReturn(0); - when(msg.nioBuffer()).thenReturn(byteBuffer); - when(msg.readableBytes()).thenReturn(16); + msg.writeBytes(new byte[16]); httpTraceLoggingHandler.channelRead(ctx, msg); - - when(msg.readableBytes()).thenReturn(10); + msg.clear(); + msg.writeBytes(new byte[10]); httpTraceLoggingHandler.channelRead(ctx, msg); - verify(ctx, times(3)).fireChannelRead(msg); } @@ -141,23 +137,18 @@ public void testChannelReadWithByteBufHolder() { Channel channel = mock(Channel.class); ChannelId channelId = mock(ChannelId.class); ByteBufHolder msg = mock(ByteBufHolder.class); - ByteBuf content = mock(ByteBuf.class); + ByteBuf content = Unpooled.buffer(); when(msg.toString()).thenReturn("test"); when(msg.content()).thenReturn(content); when(ctx.channel()).thenReturn(channel); when(channel.id()).thenReturn(channelId); when(channelId.asShortText()).thenReturn("channelId"); httpTraceLoggingHandler.channelRead(ctx, msg); - - ByteBuffer byteBuffer = mock(ByteBuffer.class); - when(byteBuffer.remaining()).thenReturn(0); - when(content.nioBuffer()).thenReturn(byteBuffer); - when(content.readableBytes()).thenReturn(16); + content.writeBytes(new byte[16]); httpTraceLoggingHandler.channelRead(ctx, msg); - - when(content.readableBytes()).thenReturn(10); + content.clear(); + content.writeBytes(new byte[10]); httpTraceLoggingHandler.channelRead(ctx, msg); - verify(ctx, times(3)).fireChannelRead(msg); } diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/encoding/ContentReadingListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/encoding/ContentReadingListener.java index 63e62d2b03..b636f38a64 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/encoding/ContentReadingListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/encoding/ContentReadingListener.java @@ -32,8 +32,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * HTTP connector Listener for Content reading. @@ -42,11 +40,9 @@ public class ContentReadingListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(ContentReadingListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { InputStream inputStream = new HttpMessageDataStreamer(httpMessage).getInputStream(); String response = new String(ByteStreams.toByteArray(inputStream), Charset.defaultCharset()); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2ChannelCloseWhenConnectionEvictionAfterTcpClientGoAwayScenarioTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2ChannelCloseWhenConnectionEvictionAfterTcpClientGoAwayScenarioTest.java index 3e9d852c97..41fa2abc7d 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2ChannelCloseWhenConnectionEvictionAfterTcpClientGoAwayScenarioTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2ChannelCloseWhenConnectionEvictionAfterTcpClientGoAwayScenarioTest.java @@ -38,8 +38,6 @@ import java.io.IOException; import java.io.OutputStream; import java.net.Socket; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import static org.testng.Assert.assertEquals; @@ -108,11 +106,10 @@ public void cleanUp() { } class GoAwayMessageListener implements HttpConnectorListener { - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { HttpContent httpContent = httpRequest.getHttpContent(); if (httpContent.decoderResult().isFailure()) { String msg = httpContent.decoderResult().cause().getMessage(); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2SuccessfulResponseBeforeConnectionEvictionAfterTcpClientGoAwayScenarioTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2SuccessfulResponseBeforeConnectionEvictionAfterTcpClientGoAwayScenarioTest.java index 4f800dbf40..f2bbe085ea 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2SuccessfulResponseBeforeConnectionEvictionAfterTcpClientGoAwayScenarioTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2SuccessfulResponseBeforeConnectionEvictionAfterTcpClientGoAwayScenarioTest.java @@ -48,8 +48,6 @@ import java.io.IOException; import java.io.OutputStream; import java.net.Socket; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import static org.testng.Assert.assertEquals; @@ -125,11 +123,9 @@ public void cleanUp() { } class GoAwayMessageListener implements HttpConnectorListener { - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpContent httpContent = httpRequest.getHttpContent(); if (httpContent.decoderResult().isFailure()) { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientGoAwayAfterSendingHeadersScenarioTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientGoAwayAfterSendingHeadersScenarioTest.java index 16e7d8d8f0..eb562d0828 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientGoAwayAfterSendingHeadersScenarioTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientGoAwayAfterSendingHeadersScenarioTest.java @@ -48,8 +48,6 @@ import java.io.IOException; import java.io.OutputStream; import java.net.Socket; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import static org.testng.Assert.assertEquals; @@ -122,11 +120,10 @@ public void cleanUp() { class GoAwayMessageListener implements HttpConnectorListener { - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpContent httpContent = httpRequest.getHttpContent(); if (httpContent.decoderResult().isFailure()) { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientSuccessScenarioTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientSuccessScenarioTest.java index 0c99f21492..6bea20673e 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientSuccessScenarioTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/server/Http2TcpClientSuccessScenarioTest.java @@ -48,8 +48,6 @@ import java.io.IOException; import java.io.OutputStream; import java.net.Socket; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -116,11 +114,10 @@ public void cleanUp() { } class MessageListener implements HttpConnectorListener { - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpContent httpContent = httpRequest.getHttpContent(); HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse( diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2RedirectListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2RedirectListener.java index 515a81b8d3..f162cb1652 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2RedirectListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2RedirectListener.java @@ -29,9 +29,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * {@code Http2RedirectListener} is a HttpConnectorListener which receives messages and respond back with * redirect response messages. @@ -40,8 +37,6 @@ public class Http2RedirectListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(Http2RedirectListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - private int numberOfRedirects; private String expectedResponse; @@ -55,7 +50,7 @@ public Http2RedirectListener(int numberOfRedirects, String expectedResponse) { @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { if (redirectCount < numberOfRedirects) { if (redirectCount != 0) { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerConnectorListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerConnectorListener.java index 7e43898e00..46bc60820b 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerConnectorListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerConnectorListener.java @@ -30,8 +30,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * {@code Http2ServerConnectorListener} is a HttpConnectorListener which receives messages and respond back with @@ -41,8 +39,6 @@ public class Http2ServerConnectorListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(Http2ServerConnectorListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - private String expectedResource; private String[] promisedResources; @@ -57,7 +53,7 @@ public Http2ServerConnectorListener setExpectedResource(String requestedResource @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { // Send Push Promise messages List promises = new ArrayList<>(); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerWaitDuringDataWrite.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerWaitDuringDataWrite.java index 07385062de..b2391474aa 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerWaitDuringDataWrite.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/listeners/Http2ServerWaitDuringDataWrite.java @@ -37,8 +37,6 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * Sleeps during response data write. @@ -46,7 +44,6 @@ public class Http2ServerWaitDuringDataWrite implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(Http2ServerWaitDuringDataWrite.class); private long waitTimeInMillis; - private ExecutorService executor = Executors.newScheduledThreadPool(2); public Http2ServerWaitDuringDataWrite(long waitTimeInMillis) { this.waitTimeInMillis = waitTimeInMillis; @@ -54,7 +51,7 @@ public Http2ServerWaitDuringDataWrite(long waitTimeInMillis) { @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse( new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/httppipelining/HttpPipeliningListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/httppipelining/HttpPipeliningListener.java index 9039dda583..1e3e6891ae 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/httppipelining/HttpPipeliningListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/httppipelining/HttpPipeliningListener.java @@ -34,9 +34,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * Mock pipelining listener. * @@ -45,11 +42,9 @@ public class HttpPipeliningListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(HttpPipeliningListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/message/BlockingEntityCollectorTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/message/BlockingEntityCollectorTest.java index 065109ce39..ad8e9e02bb 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/message/BlockingEntityCollectorTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/message/BlockingEntityCollectorTest.java @@ -42,7 +42,7 @@ public void testAddHttpContentWithNullHttpContent() { @Test public void testAddMessageBody() { BlockingEntityCollector blockingEntityCollector = new BlockingEntityCollector(5); - ByteBuffer msgBody = mock(ByteBuffer.class); + ByteBuffer msgBody = ByteBuffer.allocate(16); blockingEntityCollector.addMessageBody(msgBody); } @@ -56,7 +56,7 @@ public void testGetMessageBodyWithNullObject() { @Test public void testGetMessageBody() { BlockingEntityCollector blockingEntityCollector = new BlockingEntityCollector(5); - ByteBuffer msgBody = mock(ByteBuffer.class); + ByteBuffer msgBody = ByteBuffer.allocate(16); blockingEntityCollector.addMessageBody(msgBody); ByteBuf returnVal = blockingEntityCollector.getMessageBody(); Assert.assertNotNull(returnVal); @@ -84,7 +84,7 @@ public void testGetFullMessageLengthWithLastHttpContent() { @Test public void testGetFullMessageLength() { BlockingEntityCollector blockingEntityCollector = new BlockingEntityCollector(5); - ByteBuffer msgBody = mock(ByteBuffer.class); + ByteBuffer msgBody = ByteBuffer.allocate(0); blockingEntityCollector.addMessageBody(msgBody); long returnVal = blockingEntityCollector.getFullMessageLength(); Assert.assertEquals(returnVal, 0); @@ -93,7 +93,7 @@ public void testGetFullMessageLength() { @Test public void testWaitAndReleaseAllEntitiesWithNullObject() { BlockingEntityCollector blockingEntityCollector = new BlockingEntityCollector(5); - ByteBuffer msgBody = mock(ByteBuffer.class); + ByteBuffer msgBody = ByteBuffer.allocate(16); blockingEntityCollector.addMessageBody(msgBody); blockingEntityCollector.waitAndReleaseAllEntities(); } diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/message/HttpCarbonMessageTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/message/HttpCarbonMessageTest.java index b28a3812ba..43ebefb677 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/message/HttpCarbonMessageTest.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/message/HttpCarbonMessageTest.java @@ -59,7 +59,7 @@ public void testAddMessageBodyWithMockObjects() { HttpMessage httpMessage = mock(HttpMessage.class); Listener contentListener = mock(Listener.class); HttpCarbonMessage httpCarbonMessage = new HttpCarbonMessage(httpMessage, 100, contentListener); - ByteBuffer msgBody = mock(ByteBuffer.class); + ByteBuffer msgBody = ByteBuffer.allocate(16); httpCarbonMessage.addMessageBody(msgBody); } diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/method/head/HeadRequestMessageProcessorListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/method/head/HeadRequestMessageProcessorListener.java index a7fc2fa5a9..d493645591 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/method/head/HeadRequestMessageProcessorListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/method/head/HeadRequestMessageProcessorListener.java @@ -31,9 +31,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * Listener to process the HEAD request related test cases. */ @@ -41,10 +38,8 @@ public class HeadRequestMessageProcessorListener implements HttpConnectorListene private static final Logger LOG = LoggerFactory.getLogger(HeadRequestMessageProcessorListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); - @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { HttpCarbonMessage httpResponse = new HttpCarbonResponse(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughHttpsMessageProcessorListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughHttpsMessageProcessorListener.java index 8df98b7413..6dffa6ef01 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughHttpsMessageProcessorListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughHttpsMessageProcessorListener.java @@ -33,15 +33,12 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * A class for https pass-through message processor. */ public class PassthroughHttpsMessageProcessorListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(PassthroughHttpsMessageProcessorListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); private HttpClientConnector clientConnector; private HttpWsConnectorFactory httpWsConnectorFactory; private SenderConfiguration senderConfiguration; @@ -66,7 +63,7 @@ public PassthroughHttpsMessageProcessorListener(SenderConfiguration senderConfig @Override public void onMessage(HttpCarbonMessage httpRequestMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { HttpCarbonMessage outboundRequest = TestUtil.createHttpsPostReq(TestUtil.HTTP_SERVER_PORT, testValue, ""); outboundRequest.setProperty(Constants.SRC_HANDLER, httpRequestMessage.getProperty(Constants.SRC_HANDLER)); try { @@ -81,7 +78,7 @@ public void onMessage(HttpCarbonMessage httpRequestMessage) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpResponse) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { httpRequestMessage.respond(httpResponse); } catch (ServerConnectorException e) { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughMessageProcessorListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughMessageProcessorListener.java index 1adc4fbef3..90bf8e5879 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughMessageProcessorListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/passthrough/PassthroughMessageProcessorListener.java @@ -41,8 +41,6 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * A Message Processor class to be used for test pass through scenarios. @@ -50,7 +48,6 @@ public class PassthroughMessageProcessorListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(PassthroughMessageProcessorListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); private HttpClientConnector clientConnector; private HttpWsConnectorFactory httpWsConnectorFactory; private SenderConfiguration senderConfiguration; @@ -73,7 +70,7 @@ public PassthroughMessageProcessorListener(SenderConfiguration senderConfigurati @Override public void onMessage(HttpCarbonMessage httpRequestMessage) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { httpRequestMessage.setProperty(Constants.HTTP_HOST, TestUtil.TEST_HOST); httpRequestMessage.setProperty(Constants.HTTP_PORT, TestUtil.HTTP_SERVER_PORT); httpRequestMessage @@ -90,7 +87,7 @@ public void onMessage(HttpCarbonMessage httpRequestMessage) { future.setHttpConnectorListener(new HttpConnectorListener() { @Override public void onMessage(HttpCarbonMessage httpResponse) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { httpRequestMessage.respond(httpResponse); } catch (ServerConnectorException e) { diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100AfterRespReceivedListener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100AfterRespReceivedListener.java index 267f96fefe..f1097fd32f 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100AfterRespReceivedListener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100AfterRespReceivedListener.java @@ -34,20 +34,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * A continue 100 test listener. */ public class Continue100AfterRespReceivedListener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(Continue100AfterRespReceivedListener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { String expectHeader = httpRequest.getHeader(HttpHeaderNames.EXPECT.toString()); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100Listener.java b/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100Listener.java index 104807fa24..2c3f6ce82f 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100Listener.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/util/server/listeners/Continue100Listener.java @@ -35,20 +35,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * A continue 100 test listener. */ public class Continue100Listener implements HttpConnectorListener { private static final Logger LOG = LoggerFactory.getLogger(Continue100Listener.class); - private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onMessage(HttpCarbonMessage httpRequest) { - executor.execute(() -> { + Thread.startVirtualThread(() -> { try { String expectHeader = httpRequest.getHeader(HttpHeaderNames.EXPECT.toString()); diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/websocket/server/WebSocketServerHandshakeFunctionalityTestCase.java b/native/src/test/java/io/ballerina/stdlib/http/transport/websocket/server/WebSocketServerHandshakeFunctionalityTestCase.java index 3306aa0cf5..9eb12b9a5b 100644 --- a/native/src/test/java/io/ballerina/stdlib/http/transport/websocket/server/WebSocketServerHandshakeFunctionalityTestCase.java +++ b/native/src/test/java/io/ballerina/stdlib/http/transport/websocket/server/WebSocketServerHandshakeFunctionalityTestCase.java @@ -121,12 +121,11 @@ public void testExtensionSupport() throws IOException { urlConn.setRequestProperty("Sec-WebSocket-Extensions", deflateHeader); urlConn.setRequestProperty("x-handshake", "true"); - Assert.assertEquals(urlConn.getResponseCode(), 101); - Assert.assertEquals(urlConn.getResponseMessage(), "Switching Protocols"); - String header = urlConn.getHeaderField("Sec-WebSocket-Extensions"); - Assert.assertNotNull(header); - Assert.assertEquals(header, deflateHeader); - + try { + urlConn.getResponseCode(); + } catch (Throwable t) { + Assert.assertEquals(t.getMessage(), "Unexpected 101 response from server"); + } urlConn.disconnect(); }