From 122240201127622bd4d8130a010a0fa0891eaaf5 Mon Sep 17 00:00:00 2001 From: bhashinee Date: Wed, 12 Jun 2024 12:02:02 +0530 Subject: [PATCH 1/6] [Automated] Update the native jar versions --- ballerina/Ballerina.toml | 8 +- ballerina/CompilerPlugin.toml | 2 +- ballerina/Dependencies.toml | 353 ---------------------------------- 3 files changed, 5 insertions(+), 358 deletions(-) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 6975e692c..b52f62b88 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -1,7 +1,7 @@ [package] org = "ballerina" name = "websocket" -version = "2.11.0" +version = "2.11.1" authors = ["Ballerina"] keywords = ["ws", "network", "bi-directional", "streaming", "service", "client"] repository = "https://github.com/ballerina-platform/module-ballerina-websocket" @@ -15,8 +15,8 @@ graalvmCompatible = true [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "websocket-native" -version = "2.11.0" -path = "../native/build/libs/websocket-native-2.11.0.jar" +version = "2.11.1" +path = "../native/build/libs/websocket-native-2.11.1-SNAPSHOT.jar" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" @@ -85,5 +85,5 @@ version = "4.1.108.Final" path = "./lib/netty-handler-proxy-4.1.108.Final.jar" [[platform.java17.dependency]] -path = "../test-utils/build/libs/websocket-test-utils-2.11.0.jar" +path = "../test-utils/build/libs/websocket-test-utils-2.11.1-SNAPSHOT.jar" scope = "testOnly" diff --git a/ballerina/CompilerPlugin.toml b/ballerina/CompilerPlugin.toml index 2be486f75..f535bf7e8 100644 --- a/ballerina/CompilerPlugin.toml +++ b/ballerina/CompilerPlugin.toml @@ -3,4 +3,4 @@ id = "websocket-compiler-plugin" class = "io.ballerina.stdlib.websocket.plugin.WebSocketCompilerPlugin" [[dependency]] -path = "../compiler-plugin/build/libs/websocket-compiler-plugin-2.11.0.jar" +path = "../compiler-plugin/build/libs/websocket-compiler-plugin-2.11.1-SNAPSHOT.jar" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 21bb542c4..e69de29bb 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -1,353 +0,0 @@ -# AUTO-GENERATED FILE. DO NOT MODIFY. - -# This file is auto-generated by Ballerina for managing dependency versions. -# It should not be modified by hand. - -[ballerina] -dependencies-toml-version = "2" -distribution-version = "2201.9.0" - -[[package]] -org = "ballerina" -name = "auth" -version = "2.11.0" -dependencies = [ - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "log"} -] -modules = [ - {org = "ballerina", packageName = "auth", moduleName = "auth"} -] - -[[package]] -org = "ballerina" -name = "cache" -version = "3.8.0" -dependencies = [ - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "task"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "constraint" -version = "1.5.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "constraint", moduleName = "constraint"} -] - -[[package]] -org = "ballerina" -name = "crypto" -version = "2.7.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "file" -version = "1.9.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "os"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "http" -version = "2.11.0" -dependencies = [ - {org = "ballerina", name = "auth"}, - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "file"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "jwt"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.decimal"}, - {org = "ballerina", name = "lang.int"}, - {org = "ballerina", name = "lang.regexp"}, - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "lang.value"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "mime"}, - {org = "ballerina", name = "oauth2"}, - {org = "ballerina", name = "observe"}, - {org = "ballerina", name = "time"}, - {org = "ballerina", name = "url"} -] -modules = [ - {org = "ballerina", packageName = "http", moduleName = "http"}, - {org = "ballerina", packageName = "http", moduleName = "http.httpscerr"} -] - -[[package]] -org = "ballerina" -name = "io" -version = "1.6.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.value"} -] -modules = [ - {org = "ballerina", packageName = "io", moduleName = "io"} -] - -[[package]] -org = "ballerina" -name = "jballerina.java" -version = "0.0.0" -modules = [ - {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "jwt" -version = "2.11.0" -dependencies = [ - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.int"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "time"} -] -modules = [ - {org = "ballerina", packageName = "jwt", moduleName = "jwt"} -] - -[[package]] -org = "ballerina" -name = "lang.__internal" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.object"} -] - -[[package]] -org = "ballerina" -name = "lang.array" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.__internal"} -] -modules = [ - {org = "ballerina", packageName = "lang.array", moduleName = "lang.array"} -] - -[[package]] -org = "ballerina" -name = "lang.decimal" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.error" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.int" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.__internal"}, - {org = "ballerina", name = "lang.object"} -] - -[[package]] -org = "ballerina" -name = "lang.object" -version = "0.0.0" - -[[package]] -org = "ballerina" -name = "lang.regexp" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.runtime" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "lang.runtime", moduleName = "lang.runtime"} -] - -[[package]] -org = "ballerina" -name = "lang.string" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.regexp"} -] -modules = [ - {org = "ballerina", packageName = "lang.string", moduleName = "lang.string"} -] - -[[package]] -org = "ballerina" -name = "lang.value" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "lang.value", moduleName = "lang.value"} -] - -[[package]] -org = "ballerina" -name = "log" -version = "2.9.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.value"}, - {org = "ballerina", name = "observe"} -] -modules = [ - {org = "ballerina", packageName = "log", moduleName = "log"} -] - -[[package]] -org = "ballerina" -name = "mime" -version = "2.9.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.int"} -] - -[[package]] -org = "ballerina" -name = "oauth2" -version = "2.11.0" -dependencies = [ - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "time"}, - {org = "ballerina", name = "url"} -] -modules = [ - {org = "ballerina", packageName = "oauth2", moduleName = "oauth2"} -] - -[[package]] -org = "ballerina" -name = "observe" -version = "1.2.3" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "os" -version = "1.8.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "task" -version = "2.5.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "test" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.error"} -] -modules = [ - {org = "ballerina", packageName = "test", moduleName = "test"} -] - -[[package]] -org = "ballerina" -name = "time" -version = "2.4.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "time", moduleName = "time"} -] - -[[package]] -org = "ballerina" -name = "url" -version = "2.4.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "websocket" -version = "2.11.0" -dependencies = [ - {org = "ballerina", name = "auth"}, - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "http"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "jwt"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "lang.value"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "oauth2"}, - {org = "ballerina", name = "test"}, - {org = "ballerina", name = "time"} -] -modules = [ - {org = "ballerina", packageName = "websocket", moduleName = "websocket"} -] - From e4e47e9ae803cc8f8d567349535a3fc0ff54c45e Mon Sep 17 00:00:00 2001 From: bhashinee Date: Wed, 12 Jun 2024 12:16:54 +0530 Subject: [PATCH 2/6] [Automated] Update the native jar versions --- ballerina/Dependencies.toml | 354 ++++++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index e69de29bb..d0ec0de9e 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -0,0 +1,354 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "auth" +version = "2.11.0" +dependencies = [ + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"} +] +modules = [ + {org = "ballerina", packageName = "auth", moduleName = "auth"} +] + +[[package]] +org = "ballerina" +name = "cache" +version = "3.8.0" +dependencies = [ + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "task"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "constraint" +version = "1.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "constraint", moduleName = "constraint"} +] + +[[package]] +org = "ballerina" +name = "crypto" +version = "2.7.2" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "file" +version = "1.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "os"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "http" +version = "2.11.1" +dependencies = [ + {org = "ballerina", name = "auth"}, + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "file"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "jwt"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.decimal"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.regexp"}, + {org = "ballerina", name = "lang.runtime"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "mime"}, + {org = "ballerina", name = "oauth2"}, + {org = "ballerina", name = "observe"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] +modules = [ + {org = "ballerina", packageName = "http", moduleName = "http"}, + {org = "ballerina", packageName = "http", moduleName = "http.httpscerr"} +] + +[[package]] +org = "ballerina" +name = "io" +version = "1.6.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"} +] +modules = [ + {org = "ballerina", packageName = "io", moduleName = "io"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +modules = [ + {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "jwt" +version = "2.12.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "jwt", moduleName = "jwt"} +] + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] +modules = [ + {org = "ballerina", packageName = "lang.array", moduleName = "lang.array"} +] + +[[package]] +org = "ballerina" +name = "lang.decimal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.int" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" + +[[package]] +org = "ballerina" +name = "lang.regexp" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.runtime" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "lang.runtime", moduleName = "lang.runtime"} +] + +[[package]] +org = "ballerina" +name = "lang.string" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.regexp"} +] +modules = [ + {org = "ballerina", packageName = "lang.string", moduleName = "lang.string"} +] + +[[package]] +org = "ballerina" +name = "lang.value" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "lang.value", moduleName = "lang.value"} +] + +[[package]] +org = "ballerina" +name = "log" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "observe"} +] +modules = [ + {org = "ballerina", packageName = "log", moduleName = "log"} +] + +[[package]] +org = "ballerina" +name = "mime" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"} +] + +[[package]] +org = "ballerina" +name = "oauth2" +version = "2.11.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] +modules = [ + {org = "ballerina", packageName = "oauth2", moduleName = "oauth2"} +] + +[[package]] +org = "ballerina" +name = "observe" +version = "1.2.3" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "os" +version = "1.8.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "task" +version = "2.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "time" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "time", moduleName = "time"} +] + +[[package]] +org = "ballerina" +name = "url" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "websocket" +version = "2.11.1" +dependencies = [ + {org = "ballerina", name = "auth"}, + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "http"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "jwt"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.runtime"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "oauth2"}, + {org = "ballerina", name = "test"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "websocket", moduleName = "websocket"} +] + From 1184e5210b6ecfde60cda9582d7a6489e0973a94 Mon Sep 17 00:00:00 2001 From: Bhashinee Date: Thu, 20 Jun 2024 14:26:22 +0530 Subject: [PATCH 3/6] Implement dispatching to custom remote functions --- ballerina/Ballerina.toml | 8 +- ballerina/CompilerPlugin.toml | 2 +- ballerina/Dependencies.toml | 8 +- ballerina/tests/custom_remote_functions.bal | 33 ++ .../WebSocketResourceDispatcher.java | 306 +++++++++++------- 5 files changed, 227 insertions(+), 130 deletions(-) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 6975e692c..b52f62b88 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -1,7 +1,7 @@ [package] org = "ballerina" name = "websocket" -version = "2.11.0" +version = "2.11.1" authors = ["Ballerina"] keywords = ["ws", "network", "bi-directional", "streaming", "service", "client"] repository = "https://github.com/ballerina-platform/module-ballerina-websocket" @@ -15,8 +15,8 @@ graalvmCompatible = true [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "websocket-native" -version = "2.11.0" -path = "../native/build/libs/websocket-native-2.11.0.jar" +version = "2.11.1" +path = "../native/build/libs/websocket-native-2.11.1-SNAPSHOT.jar" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" @@ -85,5 +85,5 @@ version = "4.1.108.Final" path = "./lib/netty-handler-proxy-4.1.108.Final.jar" [[platform.java17.dependency]] -path = "../test-utils/build/libs/websocket-test-utils-2.11.0.jar" +path = "../test-utils/build/libs/websocket-test-utils-2.11.1-SNAPSHOT.jar" scope = "testOnly" diff --git a/ballerina/CompilerPlugin.toml b/ballerina/CompilerPlugin.toml index 2be486f75..f535bf7e8 100644 --- a/ballerina/CompilerPlugin.toml +++ b/ballerina/CompilerPlugin.toml @@ -3,4 +3,4 @@ id = "websocket-compiler-plugin" class = "io.ballerina.stdlib.websocket.plugin.WebSocketCompilerPlugin" [[dependency]] -path = "../compiler-plugin/build/libs/websocket-compiler-plugin-2.11.0.jar" +path = "../compiler-plugin/build/libs/websocket-compiler-plugin-2.11.1-SNAPSHOT.jar" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 21bb542c4..757e65940 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -47,7 +47,7 @@ modules = [ [[package]] org = "ballerina" name = "crypto" -version = "2.7.0" +version = "2.7.2" dependencies = [ {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "time"} @@ -67,7 +67,7 @@ dependencies = [ [[package]] org = "ballerina" name = "http" -version = "2.11.0" +version = "2.11.2" dependencies = [ {org = "ballerina", name = "auth"}, {org = "ballerina", name = "cache"}, @@ -119,7 +119,7 @@ modules = [ [[package]] org = "ballerina" name = "jwt" -version = "2.11.0" +version = "2.12.1" dependencies = [ {org = "ballerina", name = "cache"}, {org = "ballerina", name = "crypto"}, @@ -330,7 +330,7 @@ dependencies = [ [[package]] org = "ballerina" name = "websocket" -version = "2.11.0" +version = "2.11.1" dependencies = [ {org = "ballerina", name = "auth"}, {org = "ballerina", name = "constraint"}, diff --git a/ballerina/tests/custom_remote_functions.bal b/ballerina/tests/custom_remote_functions.bal index 67ccf042b..50bd4e0a9 100644 --- a/ballerina/tests/custom_remote_functions.bal +++ b/ballerina/tests/custom_remote_functions.bal @@ -113,6 +113,28 @@ service class OnErrorService { } } +@ServiceConfig {dispatcherKey: "event"} +service /oncustomerror on customDispatchingLis { + resource function get .() returns Service|Error { + return new OnCustomErrorService(); + } +} + +service class OnCustomErrorService { + *Service; + remote function onMessages(Caller caller, byte[] data) returns Error? { + check caller->writeMessage({"event": "onMessages"}); + } + + remote function onMessage(Caller caller, string data) returns Error? { + check caller->writeMessage({"event": "onMessage"}); + } + + remote function onMessagesError(Caller caller, error err) returns Error? { + check caller->writeMessage({"event": "onCustomError"}); + } +} + @ServiceConfig {dispatcherKey: "type"} service /underscore on customDispatchingLis { resource function get .() returns Service|Error { @@ -216,6 +238,17 @@ public function testDatabindingFailureWithOnError() returns Error? { test:assertEquals(resp2, {"event": "onError"}); } +@test:Config {} +public function testDatabindingFailureWithCustomOnError() returns Error? { + Client cl = check new("ws://localhost:21401/oncustomerror"); + check cl->writeMessage({"event": "Messages"}); + json resp2 = check cl->readMessage(); + test:assertEquals(resp2, {"event": "onCustomError"}); + check cl->writeMessage({"event123": "Messages"}); + json resp3 = check cl->readMessage(); + test:assertEquals(resp3, {"event": "onMessage"}); +} + @test:Config {} public function testUnderscore() returns Error? { Client cl = check new("ws://localhost:21401/underscore"); diff --git a/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java b/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java index 3e94d35d9..eadf6d8f9 100644 --- a/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java +++ b/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java @@ -408,19 +408,21 @@ public static void dispatchOnText(WebSocketConnectionInfo connectionInfo, WebSoc WebSocketService wsService = connectionInfo.getService(); WebSocketConnectionInfo.StringAggregator stringAggregator = connectionInfo .createIfNullAndGetStringAggregator(); + stringAggregator.appendAggregateString(textMessage.getText()); + boolean finalFragment = textMessage.isFinalFragment(); + if (!finalFragment) { + webSocketConnection.readNextFrame(); + return; + } String dispatchingKey = ((WebSocketServerService) wsService).getDispatchingKey(); - String methodName; - methodName = getCustomRemoteMethodName(textMessage, webSocketConnection, stringAggregator, - dispatchingKey); + String customRemoteMethodName = getCustomRemoteMethodName(dispatchingKey, stringAggregator); MethodType onTextMessageResource = null; - BObject balservice; BObject wsEndpoint = connectionInfo.getWebSocketEndpoint(); Object dispatchingService = wsService.getWsService(connectionInfo.getWebSocketConnection().getChannelId()); - balservice = (BObject) dispatchingService; MethodType[] remoteFunctions = ((ServiceType) (((BValue) dispatchingService).getType())).getMethods(); for (MethodType remoteFunc : remoteFunctions) { String funcName = remoteFunc.getName(); - if (funcName.equals(methodName)) { + if (funcName.equals(customRemoteMethodName)) { onTextMessageResource = remoteFunc; break; } @@ -431,6 +433,12 @@ public static void dispatchOnText(WebSocketConnectionInfo connectionInfo, WebSoc } boolean hasOnError = Arrays.stream(remoteFunctions).anyMatch(remoteFunc -> remoteFunc.getName() .equals(WebSocketConstants.RESOURCE_NAME_ON_ERROR)); + String errorMethodName = null; + boolean hasOnCustomError = false; + if (customRemoteMethodName != null) { + errorMethodName = customRemoteMethodName + "Error"; + hasOnCustomError = hasCustomErrorRemoteFunction(remoteFunctions, errorMethodName); + } if (onTextMessageResource == null) { stringAggregator.resetAggregateString(); webSocketConnection.readNextFrame(); @@ -440,99 +448,116 @@ public static void dispatchOnText(WebSocketConnectionInfo connectionInfo, WebSoc Type[] parameterTypes = onTextMessageResource.getParameterTypes(); Object[] bValues = new Object[parameterTypes.length * 2]; - boolean finalFragment = textMessage.isFinalFragment(); - if (finalFragment) { - if (null == dispatchingKey) { - // If the dispatching key is there, appending is already done. - stringAggregator.appendAggregateString(textMessage.getText()); - } - int index = 0; - try { - for (Type param : parameterTypes) { - int typeTag = TypeUtils.getReferredType(param).getTag(); - boolean readOnly = false; - if (typeTag == INTERSECTION_TAG) { - List memberTypes = ((IntersectionType) param).getConstituentTypes(); - if (invalidInputParams(webSocketConnection, param, memberTypes)) { - return; - } - readOnly = true; - for (Type type : memberTypes) { - if (type.getTag() == TypeTags.READONLY_TAG) { - continue; - } - param = type; - typeTag = type.getTag(); - break; - } - } - Object bValue; - switch (typeTag) { - case OBJECT_TYPE_TAG: - bValue = wsEndpoint; - break; - case STRING_TAG: - bValue = StringUtils.fromString(stringAggregator.getAggregateString()); - break; - case TypeTags.XML_TAG: - bValue = XmlUtils.parse(stringAggregator.getAggregateString()); - break; - case TypeTags.RECORD_TYPE_TAG: - bValue = ValueUtils.convert(JsonUtils.parse(stringAggregator.getAggregateString()), - param); - break; - case TypeTags.UNION_TAG: - if (WebSocketUtil.hasStringType(param)) { - bValue = ValueUtils.convert( - StringUtils.fromString(stringAggregator.getAggregateString()), param); - break; - } - // fall through - default: - bValue = FromJsonStringWithType.fromJsonStringWithType(StringUtils.fromString( - stringAggregator.getAggregateString()), - ValueCreator.createTypedescValue(param)); - break; - } - if (bValue instanceof BError) { - handleDataBindingError(connectionInfo, hasOnError, (BError) bValue); + int index = 0; + try { + for (Type param : parameterTypes) { + int typeTag = TypeUtils.getReferredType(param).getTag(); + boolean readOnly = false; + if (typeTag == INTERSECTION_TAG) { + List memberTypes = ((IntersectionType) param).getConstituentTypes(); + if (invalidInputParams(webSocketConnection, param, memberTypes)) { return; } - if (readOnly) { - bValue = CloneReadOnly.cloneReadOnly(bValue); - } - if (typeTag != OBJECT_TYPE_TAG && validationEnabled) { - Object validationResult = Constraints.validate(bValue, - ValueCreator.createTypedescValue(param)); - if (validationResult instanceof BError) { - BError validationErr = WebSocketUtil.createWebsocketErrorWithCause( - String.format("data validation failed: %s", validationResult), - WebSocketConstants.ErrorCode.PayloadValidationError, (BError) validationResult); - dispatchOnError(connectionInfo, validationErr, true); - return; + readOnly = true; + for (Type type : memberTypes) { + if (type.getTag() == TypeTags.READONLY_TAG) { + continue; } + param = type; + typeTag = type.getTag(); + break; } - bValues[index++] = bValue; - bValues[index++] = true; } - } catch (BError error) { - handleDataBindingError(connectionInfo, hasOnError, error); - return; + Object bValue = getBvaluesForTextMessage(param, typeTag, wsEndpoint, stringAggregator); + if (bValue instanceof BError bError) { + handleError(connectionInfo, bError, hasOnCustomError, errorMethodName, hasOnError); + stringAggregator.resetAggregateString(); + return; + } + if (readOnly) { + bValue = CloneReadOnly.cloneReadOnly(bValue); + } + if (typeTag != OBJECT_TYPE_TAG && validationEnabled) { + Object validationResult = Constraints.validate(bValue, + ValueCreator.createTypedescValue(param)); + if (validationResult instanceof BError) { + BError validationErr = WebSocketUtil.createWebsocketErrorWithCause( + String.format("data validation failed: %s", validationResult), + WebSocketConstants.ErrorCode.PayloadValidationError, (BError) validationResult); + dispatchOnError(connectionInfo, validationErr, true); + stringAggregator.resetAggregateString(); + return; + } + } + bValues[index++] = bValue; + bValues[index++] = true; } - executeResource(wsService, balservice, - new WebSocketResourceCallback(connectionInfo, onTextMessageResource.getName(), - wsService.getRuntime()), bValues, connectionInfo, onTextMessageResource.getName(), - ModuleUtils.getOnTextMetaData()); + } catch (BError error) { + handleError(connectionInfo, error, hasOnCustomError, errorMethodName, hasOnError); stringAggregator.resetAggregateString(); - } else { - stringAggregator.appendAggregateString(textMessage.getText()); - webSocketConnection.readNextFrame(); + return; } + executeResource(wsService, (BObject) dispatchingService, + new WebSocketResourceCallback(connectionInfo, onTextMessageResource.getName(), + wsService.getRuntime()), bValues, connectionInfo, onTextMessageResource.getName(), + ModuleUtils.getOnTextMetaData()); + stringAggregator.resetAggregateString(); } catch (IllegalAccessException e) { observeError(connectionInfo, ERROR_TYPE_MESSAGE_RECEIVED, MESSAGE_TYPE_TEXT, e.getMessage()); } } + private static Object getBvaluesForTextMessage(Type param, int typeTag, BObject wsEndpoint, + WebSocketConnectionInfo.StringAggregator stringAggregator) { + Object bValue; + switch (typeTag) { + case OBJECT_TYPE_TAG: + bValue = wsEndpoint; + break; + case STRING_TAG: + bValue = StringUtils.fromString(stringAggregator.getAggregateString()); + break; + case TypeTags.XML_TAG: + bValue = XmlUtils.parse(stringAggregator.getAggregateString()); + break; + case TypeTags.RECORD_TYPE_TAG: + bValue = ValueUtils.convert(JsonUtils.parse(stringAggregator.getAggregateString()), + param); + break; + case TypeTags.UNION_TAG: + if (WebSocketUtil.hasStringType(param)) { + bValue = ValueUtils.convert( + StringUtils.fromString(stringAggregator.getAggregateString()), param); + break; + } + // fall through + default: + bValue = FromJsonStringWithType.fromJsonStringWithType(StringUtils.fromString( + stringAggregator.getAggregateString()), + ValueCreator.createTypedescValue(param)); + break; + } + return bValue; + } + + private static boolean hasCustomErrorRemoteFunction(MethodType[] remoteFunctions, String errorMethodName) { + for (MethodType remoteFunc : remoteFunctions) { + if (remoteFunc.getName().equals(errorMethodName)) { + return true; + } + } + return false; + } + + private static void handleError(WebSocketConnectionInfo connectionInfo, BError error, boolean hasOnCustomError, + String errorMethodName, boolean hasOnError) throws IllegalAccessException { + if (hasOnCustomError) { + dispatchOnCustomError(connectionInfo, error, errorMethodName); + } else { + handleDataBindingError(connectionInfo, hasOnError, error); + } + } + private static void handleDataBindingError(WebSocketConnectionInfo connectionInfo, boolean hasOnError, BError bValue) throws IllegalAccessException { if (hasOnError) { @@ -542,24 +567,21 @@ private static void handleDataBindingError(WebSocketConnectionInfo connectionInf } } - private static String getCustomRemoteMethodName(WebSocketTextMessage textMessage, - WebSocketConnection webSocketConnection, WebSocketConnectionInfo.StringAggregator stringAggregator, - String dispatchingKey) { - String methodName = null; - if (null != dispatchingKey) { - boolean finalFragment = textMessage.isFinalFragment(); - if (finalFragment) { - stringAggregator.appendAggregateString(textMessage.getText()); - } else { - stringAggregator.appendAggregateString(textMessage.getText()); - webSocketConnection.readNextFrame(); - } + private static String getCustomRemoteMethodName(String dispatchingKey, + WebSocketConnectionInfo.StringAggregator stringAggregator) { + if (null == dispatchingKey) { + return null; + } + try { BString dispatchingValue = ((BMap) FromJsonString.fromJsonString(StringUtils .fromString(stringAggregator.getAggregateString()))) .getStringValue(StringUtils.fromString(dispatchingKey)); - methodName = createCustomRemoteFunction(dispatchingValue.getValue()); + return createCustomRemoteFunction(dispatchingValue.getValue()); + // If any runtime error occurs while retrieving the dispatching value, the default method(onMessage) + // name will be used. + } catch (RuntimeException e) { + return null; } - return methodName; } private static String createCustomRemoteFunction(String dispatchingValue) { @@ -960,14 +982,8 @@ public static void dispatchOnError(WebSocketConnectionInfo connectionInfo, Throw dispatchingService = webSocketService .getWsService(connectionInfo.getWebSocketConnection().getChannelId()); balservice = (BObject) dispatchingService; - MethodType[] remoteFunctions = ((ServiceType) (((BValue) dispatchingService) - .getType())).getMethods(); - for (MethodType remoteFunc : remoteFunctions) { - if (remoteFunc.getName().equals(WebSocketConstants.RESOURCE_NAME_ON_ERROR)) { - onErrorResource = remoteFunc; - break; - } - } + onErrorResource = getErrorMethod((BValue) dispatchingService, + WebSocketConstants.RESOURCE_NAME_ON_ERROR); } catch (IllegalAccessException ex) { connectionInfo.getWebSocketEndpoint().set(WebSocketConstants.LISTENER_IS_OPEN_FIELD, false); } @@ -980,6 +996,59 @@ public static void dispatchOnError(WebSocketConnectionInfo connectionInfo, Throw Type[] paramDetails = onErrorResource.getParameterTypes(); Object[] bValues = new Object[paramDetails.length * 2]; + getErrorBValues(connectionInfo, throwable, paramDetails, bValues); + Callback onErrorCallback = getOnErrorCallback(connectionInfo); + executeResource(webSocketService, balservice, onErrorCallback, bValues, connectionInfo, + WebSocketConstants.RESOURCE_NAME_ON_ERROR, ModuleUtils.getOnErrorMetaData()); + } + + public static void dispatchOnCustomError(WebSocketConnectionInfo connectionInfo, Throwable throwable, + String errorMethodName) { + try { + WebSocketUtil.setListenerOpenField(connectionInfo); + WebSocketService webSocketService = connectionInfo.getService(); + Object dispatchingService = webSocketService + .getWsService(connectionInfo.getWebSocketConnection().getChannelId()); + BObject balservice = (BObject) dispatchingService; + MethodType onErrorRemoteFunction = getErrorMethod((BValue) dispatchingService, + errorMethodName); + Type[] paramDetails = onErrorRemoteFunction.getParameterTypes(); + Object[] bValues = new Object[paramDetails.length * 2]; + + getErrorBValues(connectionInfo, throwable, paramDetails, bValues); + Callback onErrorCallback = getOnErrorCallback(connectionInfo); + executeResource(webSocketService, balservice, onErrorCallback, bValues, connectionInfo, + errorMethodName, ModuleUtils.getOnErrorMetaData()); + } catch (IllegalAccessException e) { + connectionInfo.getWebSocketEndpoint().set(WebSocketConstants.LISTENER_IS_OPEN_FIELD, false); + } + } + + private static Callback getOnErrorCallback(WebSocketConnectionInfo connectionInfo) { + return new Callback() { + @Override + public void notifySuccess(Object result) { + try { + WebSocketConnection webSocketConnection = connectionInfo.getWebSocketConnection(); + if (webSocketConnection.isOpen()) { + webSocketConnection.readNextFrame(); + } + } catch (IllegalAccessException e) { + observeError(connectionInfo, ERROR_TYPE_MESSAGE_RECEIVED, MESSAGE_TYPE_TEXT, e.getMessage()); + } + } + + @Override + public void notifyFailure(BError error) { + error.printStackTrace(); + observeError(connectionInfo, ERROR_TYPE_RESOURCE_INVOCATION, WebSocketConstants.RESOURCE_NAME_ON_ERROR, + error.getMessage()); + } + }; + } + + private static void getErrorBValues(WebSocketConnectionInfo connectionInfo, Throwable throwable, + Type[] paramDetails, Object[] bValues) { int index = 0; for (Type param : paramDetails) { int typeName = param.getTag(); @@ -996,21 +1065,16 @@ public static void dispatchOnError(WebSocketConnectionInfo connectionInfo, Throw break; } } - Callback onErrorCallback = new Callback() { - @Override - public void notifySuccess(Object result) { - // Do nothing. - } + } - @Override - public void notifyFailure(BError error) { - error.printStackTrace(); - observeError(connectionInfo, ERROR_TYPE_RESOURCE_INVOCATION, WebSocketConstants.RESOURCE_NAME_ON_ERROR, - error.getMessage()); + private static MethodType getErrorMethod(BValue dispatchingService, String onErrorFunctionName) { + MethodType[] remoteFunctions = ((ServiceType) (dispatchingService.getType())).getMethods(); + for (MethodType remoteFunc : remoteFunctions) { + if (remoteFunc.getName().equals(onErrorFunctionName)) { + return remoteFunc; } - }; - executeResource(webSocketService, balservice, onErrorCallback, bValues, connectionInfo, - WebSocketConstants.RESOURCE_NAME_ON_ERROR, ModuleUtils.getOnErrorMetaData()); + } + return null; } private static boolean isUnexpectedError(Throwable throwable) { From 334e158d62e454d3434b9d06c5ce5789d19b7c02 Mon Sep 17 00:00:00 2001 From: bhashinee Date: Thu, 20 Jun 2024 14:49:54 +0530 Subject: [PATCH 4/6] Update the docs --- changelog.md | 3 +++ docs/spec/spec.md | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 40d6b6097..1ecd0049e 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added +- [Implement custom error remote functions for onXXXError](https://github.com/ballerina-platform/ballerina-library/issues/6625) + ## [2.10.0] - 2023-09-15 ### Fixed diff --git a/docs/spec/spec.md b/docs/spec/spec.md index dfeb6a7d6..b3381378b 100644 --- a/docs/spec/spec.md +++ b/docs/spec/spec.md @@ -34,7 +34,8 @@ The conforming implementation of the specification is released and included in t * [onIdleTimeout](#onidletimeout) * [onClose](#onclose) * [onError](#onerror) - * 3.2.2. [Dispatching to custom remote methods](#322-dispatching-to-custom-remote-methods) + * 3.2.2. [Dispatching custom remote methods](#322-dispatching-custom-remote-methods) + * [Dispatching custom error remote methods](#Dispatching custom error remote methods) 4. [Client](#4-client) * 4.1. [Client Configurations](#41-client-configurations) * 4.2. [Initialization](#42-initialization) @@ -341,7 +342,7 @@ remote function onError(websocket:Caller caller, error err) { } ``` -#### 3.2.2. [Dispatching to custom remote methods](#322-dispatching-to-custom-remote-methods) +#### 3.2.2. [Dispatching custom remote methods](#322-dispatching-custom-remote-methods) The WebSocket service also supports dispatching messages to custom remote functions based on the message type(declared by a field in the received message) with the end goal of generating meaningful Async APIs. @@ -366,6 +367,19 @@ dispatching to remote function = "onHeartbeat" service / on new websocket:Listener(9090) {} ``` +##### [Dispatching custom error remote methods](#Dispatching custom error remote methods) + +If the user has defined a remote function with the name `customRemoteFunction` + `Error` in the WebSocket service, the error messages will get dispatched to that remote function when there is a data binding error. If that is not defined, the generic `onError` remote function gets dispatched. + +```ballerina +Ex: +incoming message = ` {"event": "heartbeat"}` +dispatcherKey = "event" +event/message type = "heartbeat" +dispatching remote function = "onHeartbeat" +dispatching error remote function = "onHeartbeatError" +``` + 2. Naming of the remote function. - If there are spaces and underscores between message types, those will be removed and made camel case("un subscribe" -> "onUnSubscribe"). From 9e4b1238a93e8eba16f14088441f08bde4f6f5b3 Mon Sep 17 00:00:00 2001 From: bhashinee Date: Thu, 27 Jun 2024 15:27:26 +0530 Subject: [PATCH 5/6] [Automated] Update the native jar versions --- ballerina/Dependencies.toml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 757e65940..316d72886 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -40,9 +40,6 @@ version = "1.5.0" dependencies = [ {org = "ballerina", name = "jballerina.java"} ] -modules = [ - {org = "ballerina", packageName = "constraint", moduleName = "constraint"} -] [[package]] org = "ballerina" @@ -104,9 +101,6 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "lang.value"} ] -modules = [ - {org = "ballerina", packageName = "io", moduleName = "io"} -] [[package]] org = "ballerina" @@ -201,9 +195,6 @@ version = "0.0.0" dependencies = [ {org = "ballerina", name = "jballerina.java"} ] -modules = [ - {org = "ballerina", packageName = "lang.runtime", moduleName = "lang.runtime"} -] [[package]] org = "ballerina" @@ -213,9 +204,6 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "lang.regexp"} ] -modules = [ - {org = "ballerina", packageName = "lang.string", moduleName = "lang.string"} -] [[package]] org = "ballerina" @@ -333,14 +321,10 @@ name = "websocket" version = "2.11.1" dependencies = [ {org = "ballerina", name = "auth"}, - {org = "ballerina", name = "constraint"}, {org = "ballerina", name = "http"}, - {org = "ballerina", name = "io"}, {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "jwt"}, {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "lang.string"}, {org = "ballerina", name = "lang.value"}, {org = "ballerina", name = "log"}, {org = "ballerina", name = "oauth2"}, From affa6f834df93e94b88ce5252af1d82b17e7fbad Mon Sep 17 00:00:00 2001 From: bhashinee Date: Thu, 27 Jun 2024 15:35:16 +0530 Subject: [PATCH 6/6] Address review suggestions --- .../WebSocketResourceDispatcher.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java b/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java index eadf6d8f9..2e49feb74 100644 --- a/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java +++ b/native/src/main/java/io/ballerina/stdlib/websocket/WebSocketResourceDispatcher.java @@ -83,6 +83,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import static io.ballerina.runtime.api.TypeTags.ARRAY_TAG; @@ -415,14 +416,14 @@ public static void dispatchOnText(WebSocketConnectionInfo connectionInfo, WebSoc return; } String dispatchingKey = ((WebSocketServerService) wsService).getDispatchingKey(); - String customRemoteMethodName = getCustomRemoteMethodName(dispatchingKey, stringAggregator); + Optional customRemoteMethodName = getCustomRemoteMethodName(dispatchingKey, stringAggregator); MethodType onTextMessageResource = null; BObject wsEndpoint = connectionInfo.getWebSocketEndpoint(); Object dispatchingService = wsService.getWsService(connectionInfo.getWebSocketConnection().getChannelId()); MethodType[] remoteFunctions = ((ServiceType) (((BValue) dispatchingService).getType())).getMethods(); for (MethodType remoteFunc : remoteFunctions) { String funcName = remoteFunc.getName(); - if (funcName.equals(customRemoteMethodName)) { + if (customRemoteMethodName.isPresent() && funcName.equals(customRemoteMethodName.get())) { onTextMessageResource = remoteFunc; break; } @@ -435,8 +436,8 @@ public static void dispatchOnText(WebSocketConnectionInfo connectionInfo, WebSoc .equals(WebSocketConstants.RESOURCE_NAME_ON_ERROR)); String errorMethodName = null; boolean hasOnCustomError = false; - if (customRemoteMethodName != null) { - errorMethodName = customRemoteMethodName + "Error"; + if (customRemoteMethodName.isPresent()) { + errorMethodName = customRemoteMethodName.get() + "Error"; hasOnCustomError = hasCustomErrorRemoteFunction(remoteFunctions, errorMethodName); } if (onTextMessageResource == null) { @@ -567,21 +568,20 @@ private static void handleDataBindingError(WebSocketConnectionInfo connectionInf } } - private static String getCustomRemoteMethodName(String dispatchingKey, - WebSocketConnectionInfo.StringAggregator stringAggregator) { - if (null == dispatchingKey) { - return null; - } - try { - BString dispatchingValue = ((BMap) FromJsonString.fromJsonString(StringUtils - .fromString(stringAggregator.getAggregateString()))) - .getStringValue(StringUtils.fromString(dispatchingKey)); - return createCustomRemoteFunction(dispatchingValue.getValue()); - // If any runtime error occurs while retrieving the dispatching value, the default method(onMessage) - // name will be used. - } catch (RuntimeException e) { - return null; - } + private static Optional getCustomRemoteMethodName(String dispatchingKey, + WebSocketConnectionInfo.StringAggregator + stringAggregator) { + return Optional.ofNullable(dispatchingKey) + .flatMap(key -> { + try { + BString dispatchingValue = ((BMap) FromJsonString.fromJsonString( + StringUtils.fromString(stringAggregator.getAggregateString()))) + .getStringValue(StringUtils.fromString(dispatchingKey)); + return Optional.of(createCustomRemoteFunction(dispatchingValue.getValue())); + } catch (RuntimeException e) { + return Optional.empty(); + } + }); } private static String createCustomRemoteFunction(String dispatchingValue) {