nacos-sdk-rust-binding-node 0.0.1-ALPHA → 0.0.1-BETA

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.toml CHANGED
@@ -2,6 +2,13 @@
2
2
  edition = "2021"
3
3
  name = "nacos-sdk-rust-binding-node"
4
4
  version = "0.0.1"
5
+ authors = ["CheirshCai <785427346@qq.com>"]
6
+ license = "Apache-2.0"
7
+ readme = "README.md"
8
+ repository = "https://github.com/opc-source/nacos-sdk-rust-binding-node"
9
+ description = "nacos-sdk-rust binding for NodeJs with napi."
10
+ categories = ["network-programming", "development-tools"]
11
+ keywords = ["nacos", "ffi", "napi", "bingding", "nodejs"]
5
12
 
6
13
  [lib]
7
14
  crate-type = ["cdylib"]
@@ -12,7 +19,7 @@ napi = { version = "2", default-features = false, features = ["napi4"] }
12
19
  napi-derive = "2"
13
20
 
14
21
  # version = ^0.2
15
- nacos-sdk = { git = "https://github.com/CherishCai/nacos-sdk-rust.git", branch = "chore_try_grpcio-sys_exlude_openssl"}
22
+ nacos-sdk = { git = "https://github.com/nacos-group/nacos-sdk-rust.git"}
16
23
  tracing-subscriber = "0.3"
17
24
  tracing-appender = "0.2"
18
25
 
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ const { NacosConfigClient, NacosConfigResponse } = require('../index')
4
+
5
+ // If it fails, pay attention to err
6
+ const nacos_config_client = new NacosConfigClient({
7
+ serverAddr: '0.0.0.0:8848',
8
+ namespace: "hongwen",
9
+ appName: "binding-node-example-app"
10
+ });
11
+
12
+ try {
13
+ // If it fails, pay attention to err
14
+ var conf_content = nacos_config_client.getConfig('hongwen.properties', 'LOVE');
15
+ console.log(conf_content);
16
+
17
+ var config_resp = nacos_config_client.getConfigResp('hongwen.properties', 'LOVE');
18
+ console.log(config_resp.content);
19
+ } catch(e) {
20
+ console.log(e);
21
+ }
22
+
23
+ nacos_config_client.addListener('hongwen.properties', 'LOVE', (err, config_resp) => { console.log(config_resp) });
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ const { NacosNamingClient, NacosServiceInstance } = require('../index')
4
+
5
+ // If it fails, pay attention to err
6
+ const nacos_naming_client = new NacosNamingClient({
7
+ serverAddr: '0.0.0.0:8848',
8
+ namespace: "hongwen",
9
+ appName: "binding-node-example-app"
10
+ });
11
+
12
+ const instance1 = {
13
+ ip: '127.0.0.1',
14
+ port: 9090,
15
+ weight: 1.0,
16
+ healthy: true,
17
+ enabled: true,
18
+ ephemeral: true,
19
+ metadata: { 'application' : 'example-naming' },
20
+ }
21
+
22
+
23
+ const instance2 = {
24
+ ip: '127.0.0.2',
25
+ port: 9099,
26
+ weight: 2.0,
27
+ healthy: true,
28
+ enabled: true,
29
+ ephemeral: true,
30
+ metadata: { 'application' : 'example-naming' },
31
+ }
32
+
33
+ function sleep(time){
34
+ return new Promise((resolve) => {
35
+ setTimeout(() => {
36
+ resolve();
37
+ }, time);
38
+ })
39
+ }
40
+
41
+ (async () => {
42
+
43
+ const serviceName = 'TestServiceName';
44
+ const group = 'LOVE';
45
+
46
+ nacos_naming_client.subscribe(serviceName, group, null, (err, instance_array) => { console.log('subscribe instance_array => ' + JSON.stringify(instance_array)) });
47
+ await sleep(2000);
48
+
49
+ console.log('--------- registerInstance instance1 ------------');
50
+ nacos_naming_client.registerInstance(serviceName, group, instance1); // If it fails, pay attention to err
51
+ await sleep(1000);
52
+
53
+ console.log('--------- get all instances 1 ------------');
54
+ var instance_arr = nacos_naming_client.getAllInstances(serviceName, group); // If it fails, pay attention to err
55
+ console.log(instance_arr);
56
+ await sleep(1000);
57
+
58
+ console.log('--------- batchRegisterInstance instance2 ------------');
59
+ nacos_naming_client.batchRegisterInstance(serviceName, group, [instance1, instance2]); // If it fails, pay attention to err
60
+ await sleep(1000);
61
+
62
+ console.log('--------- get all instances 2 ------------');
63
+ var instance_arr = nacos_naming_client.getAllInstances(serviceName, group); // If it fails, pay attention to err
64
+ console.log(instance_arr);
65
+
66
+ await sleep(300000);
67
+ process.exit(0);
68
+ })();
69
+
70
+
package/index.d.ts CHANGED
@@ -4,6 +4,18 @@
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
6
  export function sum(a: number, b: number): number
7
+ export interface ClientOptions {
8
+ /** Server Addr, e.g. address:port[,address:port],...] */
9
+ serverAddr: string
10
+ /** Namespace/Tenant */
11
+ namespace: string
12
+ /** AppName */
13
+ appName?: string
14
+ /** Username for Auth */
15
+ username?: string
16
+ /** Password for Auth */
17
+ password?: string
18
+ }
7
19
  export interface NacosConfigResponse {
8
20
  /** Namespace/Tenant */
9
21
  namespace: string
@@ -18,11 +30,95 @@ export interface NacosConfigResponse {
18
30
  /** Content's md5 */
19
31
  md5: string
20
32
  }
33
+ export interface NacosServiceInstance {
34
+ /** Instance Id */
35
+ instanceId?: string
36
+ /** Ip */
37
+ ip: string
38
+ /** Port */
39
+ port: number
40
+ /** Weight */
41
+ weight: number
42
+ /** Healthy or not */
43
+ healthy: boolean
44
+ /** Enabled ot not */
45
+ enabled: boolean
46
+ /** Ephemeral or not */
47
+ ephemeral: boolean
48
+ /** Cluster Name */
49
+ clusterName?: string
50
+ /** Service Name */
51
+ serviceName?: string
52
+ /** Metadata */
53
+ metadata: Record<string, string>
54
+ }
21
55
  /** Client api of Nacos Config. */
22
56
  export class NacosConfigClient {
23
- constructor(serverAddr: string, namespace: string, appName: string, username?: string | undefined | null, password?: string | undefined | null)
24
- /** Get a NacosConfigResponse from server. */
25
- getConfig(dataId: string, group: string): NacosConfigResponse
26
- /** Add a NacosConfigChangeListener callback func, which listen the config change. */
57
+ /** Build a Config Client. */
58
+ constructor(clientOptions: ClientOptions)
59
+ /**
60
+ * Get config's content.
61
+ * If it fails, pay attention to err
62
+ */
63
+ getConfig(dataId: string, group: string): string
64
+ /**
65
+ * Get NacosConfigResponse.
66
+ * If it fails, pay attention to err
67
+ */
68
+ getConfigResp(dataId: string, group: string): NacosConfigResponse
69
+ /**
70
+ * Publish config.
71
+ * If it fails, pay attention to err
72
+ */
73
+ publishConfig(dataId: string, group: string, content: string): boolean
74
+ /**
75
+ * Remove config.
76
+ * If it fails, pay attention to err
77
+ */
78
+ removeConfig(dataId: string, group: string): boolean
79
+ /**
80
+ * Add NacosConfigChangeListener callback func, which listen the config change.
81
+ * If it fails, pay attention to err
82
+ */
27
83
  addListener(dataId: string, group: string, listener: (err: Error | null, value: NacosConfigResponse) => any): void
28
84
  }
85
+ /** Client api of Nacos Naming. */
86
+ export class NacosNamingClient {
87
+ /** Build a Naming Client. */
88
+ constructor(clientOptions: ClientOptions)
89
+ /**
90
+ * Register instance.
91
+ * If it fails, pay attention to err
92
+ */
93
+ registerInstance(serviceName: string, group: string, serviceInstance: NacosServiceInstance): void
94
+ /**
95
+ * Deregister instance.
96
+ * If it fails, pay attention to err
97
+ */
98
+ deregisterInstance(serviceName: string, group: string, serviceInstance: NacosServiceInstance): void
99
+ /**
100
+ * Batch register instance, improve interaction efficiency.
101
+ * If it fails, pay attention to err
102
+ */
103
+ batchRegisterInstance(serviceName: string, group: string, serviceInstances: Array<NacosServiceInstance>): void
104
+ /**
105
+ * Get all instances by service and group. default cluster=[], subscribe=true.
106
+ * If it fails, pay attention to err
107
+ */
108
+ getAllInstances(serviceName: string, group: string, clusters?: Array<string> | undefined | null, subscribe?: boolean = true): Array<NacosServiceInstance>
109
+ /**
110
+ * Select instances whether healthy or not. default cluster=[], subscribe=true, healthy=true.
111
+ * If it fails, pay attention to err
112
+ */
113
+ selectInstances(serviceName: string, group: string, clusters?: Array<string> | undefined | null, subscribe?: boolean = true, healthy?: boolean = true): Array<NacosServiceInstance>
114
+ /**
115
+ * Select one healthy instance. default cluster=[], subscribe=true.
116
+ * If it fails, pay attention to err
117
+ */
118
+ selectOneHealthyInstance(serviceName: string, group: string, clusters?: Array<string> | undefined | null, subscribe?: boolean = true): NacosServiceInstance
119
+ /**
120
+ * Add NacosNamingEventListener callback func, which listen the instance change.
121
+ * If it fails, pay attention to err
122
+ */
123
+ subscribe(serviceName: string, group: string, clusters: Array<string> | undefined | null, listener: (err: Error | null, value: Array<NacosServiceInstance>) => any): void
124
+ }
package/index.js CHANGED
@@ -246,7 +246,8 @@ if (!nativeBinding) {
246
246
  throw new Error(`Failed to load native binding`)
247
247
  }
248
248
 
249
- const { sum, NacosConfigClient } = nativeBinding
249
+ const { sum, NacosConfigClient, NacosNamingClient } = nativeBinding
250
250
 
251
251
  module.exports.sum = sum
252
252
  module.exports.NacosConfigClient = NacosConfigClient
253
+ module.exports.NacosNamingClient = NacosNamingClient
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nacos-sdk-rust-binding-node",
3
- "version": "0.0.1-ALPHA",
3
+ "version": "0.0.1-BETA",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "napi": {
@@ -43,19 +43,19 @@
43
43
  },
44
44
  "packageManager": "yarn@3.4.1",
45
45
  "optionalDependencies": {
46
- "nacos-sdk-rust-binding-node-win32-x64-msvc": "0.0.1-ALPHA",
47
- "nacos-sdk-rust-binding-node-darwin-x64": "0.0.1-ALPHA",
48
- "nacos-sdk-rust-binding-node-linux-x64-gnu": "0.0.1-ALPHA",
49
- "nacos-sdk-rust-binding-node-darwin-arm64": "0.0.1-ALPHA",
50
- "nacos-sdk-rust-binding-node-android-arm64": "0.0.1-ALPHA",
51
- "nacos-sdk-rust-binding-node-linux-arm64-gnu": "0.0.1-ALPHA",
52
- "nacos-sdk-rust-binding-node-linux-arm64-musl": "0.0.1-ALPHA",
53
- "nacos-sdk-rust-binding-node-win32-arm64-msvc": "0.0.1-ALPHA",
54
- "nacos-sdk-rust-binding-node-linux-arm-gnueabihf": "0.0.1-ALPHA",
55
- "nacos-sdk-rust-binding-node-linux-x64-musl": "0.0.1-ALPHA",
56
- "nacos-sdk-rust-binding-node-freebsd-x64": "0.0.1-ALPHA",
57
- "nacos-sdk-rust-binding-node-win32-ia32-msvc": "0.0.1-ALPHA",
58
- "nacos-sdk-rust-binding-node-android-arm-eabi": "0.0.1-ALPHA",
59
- "nacos-sdk-rust-binding-node-darwin-universal": "0.0.1-ALPHA"
46
+ "nacos-sdk-rust-binding-node-win32-x64-msvc": "0.0.1-BETA",
47
+ "nacos-sdk-rust-binding-node-darwin-x64": "0.0.1-BETA",
48
+ "nacos-sdk-rust-binding-node-linux-x64-gnu": "0.0.1-BETA",
49
+ "nacos-sdk-rust-binding-node-darwin-arm64": "0.0.1-BETA",
50
+ "nacos-sdk-rust-binding-node-android-arm64": "0.0.1-BETA",
51
+ "nacos-sdk-rust-binding-node-linux-arm64-gnu": "0.0.1-BETA",
52
+ "nacos-sdk-rust-binding-node-linux-arm64-musl": "0.0.1-BETA",
53
+ "nacos-sdk-rust-binding-node-win32-arm64-msvc": "0.0.1-BETA",
54
+ "nacos-sdk-rust-binding-node-linux-arm-gnueabihf": "0.0.1-BETA",
55
+ "nacos-sdk-rust-binding-node-linux-x64-musl": "0.0.1-BETA",
56
+ "nacos-sdk-rust-binding-node-freebsd-x64": "0.0.1-BETA",
57
+ "nacos-sdk-rust-binding-node-win32-ia32-msvc": "0.0.1-BETA",
58
+ "nacos-sdk-rust-binding-node-android-arm-eabi": "0.0.1-BETA",
59
+ "nacos-sdk-rust-binding-node-darwin-universal": "0.0.1-BETA"
60
60
  }
61
61
  }
package/src/config.rs ADDED
@@ -0,0 +1,163 @@
1
+ #![deny(clippy::all)]
2
+
3
+ use napi::{bindgen_prelude::*, threadsafe_function::*};
4
+ use std::sync::Arc;
5
+
6
+ /// Client api of Nacos Config.
7
+ #[napi]
8
+ pub struct NacosConfigClient {
9
+ inner: Box<dyn nacos_sdk::api::config::ConfigService>,
10
+ }
11
+
12
+ #[napi]
13
+ impl NacosConfigClient {
14
+ /// Build a Config Client.
15
+ #[napi(constructor)]
16
+ pub fn new(client_options: crate::ClientOptions) -> Result<NacosConfigClient> {
17
+ // print to console or file
18
+ crate::log_print_to_console_or_file();
19
+
20
+ let props = nacos_sdk::api::props::ClientProps::new()
21
+ .server_addr(client_options.server_addr)
22
+ .namespace(client_options.namespace)
23
+ .app_name(
24
+ client_options
25
+ .app_name
26
+ .unwrap_or(nacos_sdk::api::constants::UNKNOWN.to_string()),
27
+ );
28
+
29
+ // need enable_auth_plugin_http with username & password
30
+ let is_enable_auth = client_options.username.is_some() && client_options.password.is_some();
31
+
32
+ let props = if is_enable_auth {
33
+ props
34
+ .auth_username(client_options.username.unwrap())
35
+ .auth_password(client_options.password.unwrap())
36
+ } else {
37
+ props
38
+ };
39
+
40
+ let config_service_builder = if is_enable_auth {
41
+ nacos_sdk::api::config::ConfigServiceBuilder::new(props).enable_auth_plugin_http()
42
+ } else {
43
+ nacos_sdk::api::config::ConfigServiceBuilder::new(props)
44
+ };
45
+
46
+ let config_service = config_service_builder
47
+ .build()
48
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
49
+
50
+ Ok(NacosConfigClient {
51
+ inner: Box::new(config_service),
52
+ })
53
+ }
54
+
55
+ /// Get config's content.
56
+ /// If it fails, pay attention to err
57
+ #[napi]
58
+ pub fn get_config(&mut self, data_id: String, group: String) -> Result<String> {
59
+ Ok(self.get_config_resp(data_id, group)?.content)
60
+ }
61
+
62
+ /// Get NacosConfigResponse.
63
+ /// If it fails, pay attention to err
64
+ #[napi]
65
+ pub fn get_config_resp(&mut self, data_id: String, group: String) -> Result<NacosConfigResponse> {
66
+ let config_resp = self
67
+ .inner
68
+ .get_config(data_id, group)
69
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
70
+
71
+ Ok(transfer_conf_resp(config_resp))
72
+ }
73
+
74
+ /// Publish config.
75
+ /// If it fails, pay attention to err
76
+ #[napi]
77
+ pub fn publish_config(
78
+ &mut self,
79
+ data_id: String,
80
+ group: String,
81
+ content: String,
82
+ ) -> Result<bool> {
83
+ self
84
+ .inner
85
+ .publish_config(data_id, group, content, None)
86
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))
87
+ }
88
+
89
+ /// Remove config.
90
+ /// If it fails, pay attention to err
91
+ #[napi]
92
+ pub fn remove_config(&mut self, data_id: String, group: String) -> Result<bool> {
93
+ self
94
+ .inner
95
+ .remove_config(data_id, group)
96
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))
97
+ }
98
+
99
+ /// Add NacosConfigChangeListener callback func, which listen the config change.
100
+ /// If it fails, pay attention to err
101
+ #[napi]
102
+ pub fn add_listener(
103
+ &mut self,
104
+ data_id: String,
105
+ group: String,
106
+ listener: ThreadsafeFunction<NacosConfigResponse>,
107
+ ) -> Result<()> {
108
+ self
109
+ .inner
110
+ .add_listener(
111
+ data_id,
112
+ group,
113
+ Arc::new(NacosConfigChangeListener {
114
+ func: Arc::new(listener),
115
+ }),
116
+ )
117
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
118
+ Ok(())
119
+ }
120
+ }
121
+
122
+ #[napi(object)]
123
+ pub struct NacosConfigResponse {
124
+ /// Namespace/Tenant
125
+ pub namespace: String,
126
+ /// DataId
127
+ pub data_id: String,
128
+ /// Group
129
+ pub group: String,
130
+ /// Content
131
+ pub content: String,
132
+ /// Content's Type; e.g. json,properties,xml,html,text,yaml
133
+ pub content_type: String,
134
+ /// Content's md5
135
+ pub md5: String,
136
+ }
137
+
138
+ pub struct NacosConfigChangeListener {
139
+ func: Arc<ThreadsafeFunction<NacosConfigResponse>>,
140
+ }
141
+
142
+ impl nacos_sdk::api::config::ConfigChangeListener for NacosConfigChangeListener {
143
+ fn notify(&self, config_resp: nacos_sdk::api::config::ConfigResponse) {
144
+ let listen = self.func.clone();
145
+
146
+ let conf_resp = transfer_conf_resp(config_resp);
147
+
148
+ std::thread::spawn(move || {
149
+ listen.call(Ok(conf_resp), ThreadsafeFunctionCallMode::NonBlocking);
150
+ });
151
+ }
152
+ }
153
+
154
+ fn transfer_conf_resp(config_resp: nacos_sdk::api::config::ConfigResponse) -> NacosConfigResponse {
155
+ NacosConfigResponse {
156
+ namespace: config_resp.namespace().to_string(),
157
+ data_id: config_resp.data_id().to_string(),
158
+ group: config_resp.group().to_string(),
159
+ content: config_resp.content().to_string(),
160
+ content_type: config_resp.content_type().to_string(),
161
+ md5: config_resp.md5().to_string(),
162
+ }
163
+ }
package/src/lib.rs CHANGED
@@ -3,12 +3,6 @@
3
3
  #[macro_use]
4
4
  extern crate napi_derive;
5
5
 
6
- use napi::{
7
- bindgen_prelude::*, threadsafe_function::*, JsGlobal, JsNull, JsObject,
8
- JsUndefined, Property,
9
- };
10
- use std::sync::Arc;
11
-
12
6
  #[napi]
13
7
  pub fn sum(a: i32, b: i32) -> i32 {
14
8
  a + b
@@ -16,145 +10,44 @@ pub fn sum(a: i32, b: i32) -> i32 {
16
10
 
17
11
  static INIT_ONCE: std::sync::Once = std::sync::Once::new();
18
12
 
19
- /// Client api of Nacos Config.
20
- #[napi]
21
- pub struct NacosConfigClient {
22
- inner: Box<dyn nacos_sdk::api::config::ConfigService>,
23
- }
24
-
25
- #[napi]
26
- impl NacosConfigClient {
27
- #[napi(constructor)]
28
- pub fn new(
29
- server_addr: String,
30
- namespace: String,
31
- app_name: String,
32
- username: Option<String>,
33
- password: Option<String>,
34
- ) -> Result<NacosConfigClient> {
35
- // print to console or file
36
- INIT_ONCE.call_once(|| {
37
- let home_dir = match std::env::var("HOME") {
38
- Ok(dir) => dir,
39
- Err(_) => "/tmp".to_string(),
40
- };
41
- let file_appender = tracing_appender::rolling::daily(home_dir + "/logs/nacos", "nacos.log");
42
- let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
43
-
44
- tracing_subscriber::fmt()
45
- .with_writer(non_blocking)
46
- .with_thread_names(true)
47
- .with_file(true)
48
- .with_level(true)
49
- .with_line_number(true)
50
- .with_thread_ids(true)
51
- .with_max_level(tracing_subscriber::filter::LevelFilter::INFO)
52
- .init();
53
- });
54
-
55
- // enable_auth_plugin_http with username & password
56
- if username.is_some() && password.is_some() {
57
- let props = nacos_sdk::api::props::ClientProps::new()
58
- .server_addr(server_addr)
59
- .namespace(namespace)
60
- .app_name(app_name)
61
- .auth_username(username.unwrap())
62
- .auth_password(password.unwrap());
63
-
64
- let config_service = nacos_sdk::api::config::ConfigServiceBuilder::new(props)
65
- .enable_auth_plugin_http()
66
- .build()
67
- .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
68
-
69
- Ok(NacosConfigClient {
70
- inner: Box::new(config_service),
71
- })
72
- } else {
73
- let props = nacos_sdk::api::props::ClientProps::new()
74
- .server_addr(server_addr)
75
- .namespace(namespace)
76
- .app_name(app_name);
77
-
78
- let config_service = nacos_sdk::api::config::ConfigServiceBuilder::new(props)
79
- .build()
80
- .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
81
-
82
- Ok(NacosConfigClient {
83
- inner: Box::new(config_service),
84
- })
85
- }
86
- }
87
-
88
- /// Get a NacosConfigResponse from server.
89
- #[napi]
90
- pub fn get_config(&mut self, data_id: String, group: String) -> Result<NacosConfigResponse> {
91
- let config_resp = self.inner.get_config(data_id, group)
92
- .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
93
-
94
- Ok(transfer_conf_resp(config_resp))
95
- }
96
-
97
- /// Add a NacosConfigChangeListener callback func, which listen the config change.
98
- #[napi]
99
- pub fn add_listener(
100
- &mut self,
101
- data_id: String,
102
- group: String,
103
- listener: ThreadsafeFunction<NacosConfigResponse>,
104
- ) -> Result<()> {
105
- self
106
- .inner
107
- .add_listener(
108
- data_id,
109
- group,
110
- Arc::new(NacosConfigChangeListener {
111
- func: Arc::new(listener),
112
- }),
113
- )
114
- .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
115
- Ok(())
116
- }
13
+ /// log print to console or file
14
+ fn log_print_to_console_or_file() {
15
+ INIT_ONCE.call_once(|| {
16
+ let home_dir = match std::env::var("HOME") {
17
+ Ok(dir) => dir,
18
+ Err(_) => "/tmp".to_string(),
19
+ };
20
+ let file_appender = tracing_appender::rolling::daily(home_dir + "/logs/nacos", "nacos.log");
21
+ let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
22
+
23
+ tracing_subscriber::fmt()
24
+ .with_writer(non_blocking)
25
+ .with_thread_names(true)
26
+ .with_file(true)
27
+ .with_level(true)
28
+ .with_line_number(true)
29
+ .with_thread_ids(true)
30
+ .with_max_level(tracing_subscriber::filter::LevelFilter::INFO)
31
+ .init();
32
+ });
117
33
  }
118
34
 
119
35
  #[napi(object)]
120
- pub struct NacosConfigResponse {
36
+ pub struct ClientOptions {
37
+ /// Server Addr, e.g. address:port[,address:port],...]
38
+ pub server_addr: String,
121
39
  /// Namespace/Tenant
122
40
  pub namespace: String,
123
- /// DataId
124
- pub data_id: String,
125
- /// Group
126
- pub group: String,
127
- /// Content
128
- pub content: String,
129
- /// Content's Type; e.g. json,properties,xml,html,text,yaml
130
- pub content_type: String,
131
- /// Content's md5
132
- pub md5: String,
133
- }
134
-
135
- pub struct NacosConfigChangeListener {
136
- func: Arc<ThreadsafeFunction<NacosConfigResponse>>,
137
- }
138
-
139
- fn transfer_conf_resp(config_resp: nacos_sdk::api::config::ConfigResponse) -> NacosConfigResponse {
140
- NacosConfigResponse {
141
- namespace: config_resp.namespace().to_string(),
142
- data_id: config_resp.data_id().to_string().to_string(),
143
- group: config_resp.group().to_string(),
144
- content: config_resp.content().to_string(),
145
- content_type: config_resp.content_type().to_string(),
146
- md5: config_resp.md5().to_string(),
147
- }
41
+ /// AppName
42
+ pub app_name: Option<String>,
43
+ /// Username for Auth
44
+ pub username: Option<String>,
45
+ /// Password for Auth
46
+ pub password: Option<String>,
148
47
  }
149
48
 
150
- impl nacos_sdk::api::config::ConfigChangeListener for NacosConfigChangeListener {
151
- fn notify(&self, config_resp: nacos_sdk::api::config::ConfigResponse) {
152
- let listen = self.func.clone();
49
+ mod config;
50
+ pub use config::*;
153
51
 
154
- let conf_resp = transfer_conf_resp(config_resp);
155
-
156
- std::thread::spawn(move || {
157
- listen.call(Ok(conf_resp), ThreadsafeFunctionCallMode::NonBlocking);
158
- });
159
- }
160
- }
52
+ mod naming;
53
+ pub use naming::*;
package/src/naming.rs ADDED
@@ -0,0 +1,304 @@
1
+ #![deny(clippy::all)]
2
+
3
+ use napi::{bindgen_prelude::*, threadsafe_function::*};
4
+ use std::sync::Arc;
5
+
6
+ /// Client api of Nacos Naming.
7
+ #[napi]
8
+ pub struct NacosNamingClient {
9
+ inner: Box<dyn nacos_sdk::api::naming::NamingService>,
10
+ }
11
+
12
+ #[napi]
13
+ impl NacosNamingClient {
14
+ /// Build a Naming Client.
15
+ #[napi(constructor)]
16
+ pub fn new(client_options: crate::ClientOptions) -> Result<NacosNamingClient> {
17
+ // print to console or file
18
+ crate::log_print_to_console_or_file();
19
+
20
+ let props = nacos_sdk::api::props::ClientProps::new()
21
+ .server_addr(client_options.server_addr)
22
+ .namespace(client_options.namespace)
23
+ .app_name(
24
+ client_options
25
+ .app_name
26
+ .unwrap_or(nacos_sdk::api::constants::UNKNOWN.to_string()),
27
+ );
28
+
29
+ // need enable_auth_plugin_http with username & password
30
+ let is_enable_auth = client_options.username.is_some() && client_options.password.is_some();
31
+
32
+ let props = if is_enable_auth {
33
+ props
34
+ .auth_username(client_options.username.unwrap())
35
+ .auth_password(client_options.password.unwrap())
36
+ } else {
37
+ props
38
+ };
39
+
40
+ let naming_service_builder = if is_enable_auth {
41
+ nacos_sdk::api::naming::NamingServiceBuilder::new(props).enable_auth_plugin_http()
42
+ } else {
43
+ nacos_sdk::api::naming::NamingServiceBuilder::new(props)
44
+ };
45
+
46
+ let naming_service = naming_service_builder
47
+ .build()
48
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
49
+
50
+ Ok(NacosNamingClient {
51
+ inner: Box::new(naming_service),
52
+ })
53
+ }
54
+
55
+ /// Register instance.
56
+ /// If it fails, pay attention to err
57
+ #[napi]
58
+ pub fn register_instance(
59
+ &self,
60
+ service_name: String,
61
+ group: String,
62
+ service_instance: NacosServiceInstance,
63
+ ) -> Result<()> {
64
+ self
65
+ .inner
66
+ .register_service(
67
+ service_name,
68
+ Some(group),
69
+ transfer_js_instance_to_rust(&service_instance),
70
+ )
71
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))
72
+ }
73
+
74
+ /// Deregister instance.
75
+ /// If it fails, pay attention to err
76
+ #[napi]
77
+ pub fn deregister_instance(
78
+ &self,
79
+ service_name: String,
80
+ group: String,
81
+ service_instance: NacosServiceInstance,
82
+ ) -> Result<()> {
83
+ self
84
+ .inner
85
+ .deregister_instance(
86
+ service_name,
87
+ Some(group),
88
+ transfer_js_instance_to_rust(&service_instance),
89
+ )
90
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))
91
+ }
92
+
93
+ /// Batch register instance, improve interaction efficiency.
94
+ /// If it fails, pay attention to err
95
+ #[napi]
96
+ pub fn batch_register_instance(
97
+ &self,
98
+ service_name: String,
99
+ group: String,
100
+ service_instances: Vec<NacosServiceInstance>,
101
+ ) -> Result<()> {
102
+ let rust_instances = service_instances
103
+ .iter()
104
+ .map(transfer_js_instance_to_rust)
105
+ .collect();
106
+
107
+ self
108
+ .inner
109
+ .batch_register_instance(service_name, Some(group), rust_instances)
110
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))
111
+ }
112
+
113
+ /// Get all instances by service and group. default cluster=[], subscribe=true.
114
+ /// If it fails, pay attention to err
115
+ #[napi]
116
+ pub fn get_all_instances(
117
+ &self,
118
+ service_name: String,
119
+ group: String,
120
+ clusters: Option<Vec<String>>,
121
+ #[napi(ts_arg_type = "boolean = true")]
122
+ subscribe: Option<bool>,
123
+ ) -> Result<Vec<NacosServiceInstance>> {
124
+ let rust_instances = self
125
+ .inner
126
+ .get_all_instances(
127
+ service_name,
128
+ Some(group),
129
+ clusters.unwrap_or_default(),
130
+ subscribe.unwrap_or(true),
131
+ )
132
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
133
+
134
+ Ok(
135
+ rust_instances
136
+ .iter()
137
+ .map(transfer_rust_instance_to_js)
138
+ .collect(),
139
+ )
140
+ }
141
+
142
+ /// Select instances whether healthy or not. default cluster=[], subscribe=true, healthy=true.
143
+ /// If it fails, pay attention to err
144
+ #[napi]
145
+ pub fn select_instances(
146
+ &self,
147
+ service_name: String,
148
+ group: String,
149
+ clusters: Option<Vec<String>>,
150
+ #[napi(ts_arg_type = "boolean = true")]
151
+ subscribe: Option<bool>,
152
+ #[napi(ts_arg_type = "boolean = true")]
153
+ healthy: Option<bool>,
154
+ ) -> Result<Vec<NacosServiceInstance>> {
155
+ let rust_instances = self
156
+ .inner
157
+ .select_instance(
158
+ service_name,
159
+ Some(group),
160
+ clusters.unwrap_or_default(),
161
+ subscribe.unwrap_or(true),
162
+ healthy.unwrap_or(true),
163
+ )
164
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
165
+
166
+ Ok(
167
+ rust_instances
168
+ .iter()
169
+ .map(transfer_rust_instance_to_js)
170
+ .collect(),
171
+ )
172
+ }
173
+
174
+ /// Select one healthy instance. default cluster=[], subscribe=true.
175
+ /// If it fails, pay attention to err
176
+ #[napi]
177
+ pub fn select_one_healthy_instance(
178
+ &self,
179
+ service_name: String,
180
+ group: String,
181
+ clusters: Option<Vec<String>>,
182
+ #[napi(ts_arg_type = "boolean = true")]
183
+ subscribe: Option<bool>,
184
+ ) -> Result<NacosServiceInstance> {
185
+ let rust_instance = self
186
+ .inner
187
+ .select_one_healthy_instance(
188
+ service_name,
189
+ Some(group),
190
+ clusters.unwrap_or_default(),
191
+ subscribe.unwrap_or(true),
192
+ )
193
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
194
+
195
+ Ok(transfer_rust_instance_to_js(&rust_instance))
196
+ }
197
+
198
+ /// Add NacosNamingEventListener callback func, which listen the instance change.
199
+ /// If it fails, pay attention to err
200
+ #[napi]
201
+ pub fn subscribe(
202
+ &self,
203
+ service_name: String,
204
+ group: String,
205
+ clusters: Option<Vec<String>>,
206
+ listener: ThreadsafeFunction<Vec<NacosServiceInstance>>,
207
+ ) -> Result<()> {
208
+ self
209
+ .inner
210
+ .subscribe(
211
+ service_name,
212
+ Some(group),
213
+ clusters.unwrap_or_default(),
214
+ Arc::new(NacosNamingEventListener {
215
+ func: Arc::new(listener),
216
+ }),
217
+ )
218
+ .map_err(|nacos_err| Error::from_reason(nacos_err.to_string()))?;
219
+ Ok(())
220
+ }
221
+ }
222
+
223
+ pub struct NacosNamingEventListener {
224
+ func: Arc<ThreadsafeFunction<Vec<NacosServiceInstance>>>,
225
+ }
226
+
227
+ impl nacos_sdk::api::naming::NamingEventListener for NacosNamingEventListener {
228
+ fn event(&self, event: Arc<nacos_sdk::api::naming::NamingChangeEvent>) {
229
+ let listen = self.func.clone();
230
+
231
+ if event.instances.is_none() {
232
+ return;
233
+ }
234
+
235
+ let rust_instances = event.instances.clone().unwrap();
236
+
237
+ let js_instances = rust_instances
238
+ .iter()
239
+ .map(transfer_rust_instance_to_js)
240
+ .collect();
241
+
242
+ std::thread::spawn(move || {
243
+ listen.call(Ok(js_instances), ThreadsafeFunctionCallMode::NonBlocking);
244
+ });
245
+ }
246
+ }
247
+
248
+ #[napi(object)]
249
+ pub struct NacosServiceInstance {
250
+ /// Instance Id
251
+ pub instance_id: Option<String>,
252
+ /// Ip
253
+ pub ip: String,
254
+ /// Port
255
+ pub port: i32,
256
+ /// Weight
257
+ pub weight: f64,
258
+ /// Healthy or not
259
+ pub healthy: bool,
260
+ /// Enabled ot not
261
+ pub enabled: bool,
262
+ /// Ephemeral or not
263
+ pub ephemeral: bool,
264
+ /// Cluster Name
265
+ pub cluster_name: Option<String>,
266
+ /// Service Name
267
+ pub service_name: Option<String>,
268
+ /// Metadata
269
+ pub metadata: std::collections::HashMap<String, String>,
270
+ }
271
+
272
+ fn transfer_js_instance_to_rust(
273
+ js_instance: &NacosServiceInstance,
274
+ ) -> nacos_sdk::api::naming::ServiceInstance {
275
+ nacos_sdk::api::naming::ServiceInstance {
276
+ instance_id: js_instance.instance_id.clone(),
277
+ ip: js_instance.ip.clone(),
278
+ port: js_instance.port,
279
+ weight: js_instance.weight,
280
+ healthy: js_instance.healthy,
281
+ enabled: js_instance.enabled,
282
+ ephemeral: js_instance.ephemeral,
283
+ cluster_name: js_instance.cluster_name.clone(),
284
+ service_name: js_instance.service_name.clone(),
285
+ metadata: js_instance.metadata.clone(),
286
+ }
287
+ }
288
+
289
+ fn transfer_rust_instance_to_js(
290
+ rust_instance: &nacos_sdk::api::naming::ServiceInstance,
291
+ ) -> NacosServiceInstance {
292
+ NacosServiceInstance {
293
+ instance_id: rust_instance.instance_id.clone(),
294
+ ip: rust_instance.ip.clone(),
295
+ port: rust_instance.port,
296
+ weight: rust_instance.weight,
297
+ healthy: rust_instance.healthy,
298
+ enabled: rust_instance.enabled,
299
+ ephemeral: rust_instance.ephemeral,
300
+ cluster_name: rust_instance.cluster_name.clone(),
301
+ service_name: rust_instance.service_name.clone(),
302
+ metadata: rust_instance.metadata.clone(),
303
+ }
304
+ }
@@ -1,11 +0,0 @@
1
- 'use strict';
2
-
3
- const { NacosConfigClient, NacosConfigResponse } = require('../index')
4
-
5
- const nacos_config_client = new NacosConfigClient('0.0.0.0:8848', "hongwen", "binding-node-example-app");
6
-
7
- var conf_resp = nacos_config_client.getConfig('hongwen.properties', 'LOVE');
8
- console.log(conf_resp);
9
- console.log(conf_resp.content);
10
-
11
- nacos_config_client.addListener('hongwen.properties', 'LOVE', (err, conf_resp) => { console.log(conf_resp) });