Skip to content

Commit

Permalink
Merge pull request #1356 from Bhashinee/fixIssues
Browse files Browse the repository at this point in the history
Implement dispatching custom error remote functions
  • Loading branch information
Bhashinee authored Jul 22, 2024
2 parents ab96107 + 34c677b commit abc2f93
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 152 deletions.
8 changes: 4 additions & 4 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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"
2 changes: 1 addition & 1 deletion ballerina/CompilerPlugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
24 changes: 4 additions & 20 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ 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"
version = "2.7.2"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "time"}
Expand All @@ -67,7 +64,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
version = "2.11.0"
version = "2.11.2"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
Expand Down Expand Up @@ -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"
Expand All @@ -119,7 +113,7 @@ modules = [
[[package]]
org = "ballerina"
name = "jwt"
version = "2.11.0"
version = "2.12.1"
dependencies = [
{org = "ballerina", name = "cache"},
{org = "ballerina", name = "crypto"},
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -330,17 +318,13 @@ dependencies = [
[[package]]
org = "ballerina"
name = "websocket"
version = "2.11.0"
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"},
Expand Down
33 changes: 33 additions & 0 deletions ballerina/tests/custom_remote_functions.bal
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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");
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 16 additions & 2 deletions docs/spec/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.

Expand All @@ -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").
Expand Down
Loading

0 comments on commit abc2f93

Please sign in to comment.