1use std::collections::HashMap;
2
3use prost_types::Any;
4use serde::{Deserialize, Serialize};
5
6use crate::api::remote::{Request, RequestTrait, Response, ResponseTrait};
7use crate::api::Payload;
8use crate::common::{NAMING_MODULE, REGISTER_INSTANCE, DEREGISTER_INSTANCE, UPDATE_INSTANCE};
9
10#[derive(Clone, Debug, Default, Serialize, Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct Instance {
16 pub instance_id: String,
17 pub ip: String,
18 pub port: i32,
19 pub weight: f64,
20 pub healthy: bool,
21 pub enabled: bool,
22 pub ephemeral: bool,
23 pub cluster_name: String,
24 pub service_name: String,
25 pub metadata: HashMap<String, String>,
26 pub instance_heart_beat_interval: i64,
27 pub instance_heart_beat_time_out: i64,
28 pub ip_delete_timeout: i64,
29 pub instance_id_generator: String,
30}
31
32impl Instance {
33 pub fn new(ip: &str, port: i32) -> Self {
34 Self {
35 ip: ip.to_string(),
36 port,
37 weight: 1.0,
38 healthy: true,
39 enabled: true,
40 ephemeral: true,
41 cluster_name: crate::common::DEFAULT_CLUSTER.to_string(),
42 metadata: HashMap::new(),
43 instance_heart_beat_interval: 5000,
44 instance_heart_beat_time_out: 15000,
45 ip_delete_timeout: 30000,
46 ..Default::default()
47 }
48 }
49
50 pub fn with_weight(mut self, weight: f64) -> Self {
51 self.weight = weight;
52 self
53 }
54
55 pub fn with_cluster(mut self, cluster: &str) -> Self {
56 self.cluster_name = cluster.to_string();
57 self
58 }
59
60 pub fn with_metadata(mut self, key: &str, value: &str) -> Self {
61 self.metadata.insert(key.to_string(), value.to_string());
62 self
63 }
64
65 pub fn with_ephemeral(mut self, ephemeral: bool) -> Self {
66 self.ephemeral = ephemeral;
67 self
68 }
69
70 pub fn with_enabled(mut self, enabled: bool) -> Self {
71 self.enabled = enabled;
72 self
73 }
74
75 pub fn generate_instance_id(&mut self) {
77 if self.instance_id.is_empty() {
78 self.instance_id = format!("{}#{}#{}", self.ip, self.port, self.cluster_name);
79 }
80 }
81
82 pub fn key(&self) -> String {
84 format!("{}#{}#{}", self.ip, self.port, self.cluster_name)
85 }
86}
87
88#[derive(Clone, Debug, Default, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93pub struct Service {
94 pub name: String,
95 pub group_name: String,
96 pub clusters: String,
97 pub cache_millis: i64,
98 pub hosts: Vec<Instance>,
99 pub last_ref_time: i64,
100 pub checksum: String,
101 pub all_ips: bool,
102 pub reach_protection_threshold: bool,
103}
104
105impl Service {
106 pub fn new(name: &str, group_name: &str) -> Self {
107 Self {
108 name: name.to_string(),
109 group_name: group_name.to_string(),
110 cache_millis: 10000,
111 hosts: Vec::new(),
112 ..Default::default()
113 }
114 }
115
116 pub fn key(&self) -> String {
117 format!("{}@@{}", self.group_name, self.name)
118 }
119
120 pub fn healthy_instances(&self) -> Vec<&Instance> {
122 self.hosts.iter().filter(|i| i.healthy && i.enabled).collect()
123 }
124
125 pub fn enabled_instances(&self) -> Vec<&Instance> {
127 self.hosts.iter().filter(|i| i.enabled).collect()
128 }
129}
130
131#[derive(Clone, Debug, Default, Serialize, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct NamingRequest {
137 #[serde(flatten)]
138 pub request: Request,
139 pub namespace: String,
140 pub service_name: String,
141 pub group_name: String,
142 pub module: String,
143}
144
145impl NamingRequest {
146 pub fn new(namespace: &str, service_name: &str, group_name: &str) -> Self {
147 Self {
148 request: Request::new(),
149 namespace: namespace.to_string(),
150 service_name: service_name.to_string(),
151 group_name: group_name.to_string(),
152 module: NAMING_MODULE.to_string(),
153 }
154 }
155}
156
157impl RequestTrait for NamingRequest {
158 fn headers(&self) -> HashMap<String, String> {
159 self.request.headers()
160 }
161
162 fn insert_headers(&mut self, headers: HashMap<String, String>) {
163 self.request.insert_headers(headers);
164 }
165
166 fn request_id(&self) -> String {
167 self.request.request_id.clone()
168 }
169}
170
171#[derive(Clone, Debug, Default, Serialize, Deserialize)]
175#[serde(rename_all = "camelCase")]
176pub struct InstanceRequest {
177 #[serde(flatten)]
178 pub naming_request: NamingRequest,
179 pub r#type: String,
180 pub instance: Instance,
181}
182
183impl InstanceRequest {
184 pub fn register(namespace: &str, service_name: &str, group_name: &str, instance: Instance) -> Self {
185 Self {
186 naming_request: NamingRequest::new(namespace, service_name, group_name),
187 r#type: REGISTER_INSTANCE.to_string(),
188 instance,
189 }
190 }
191
192 pub fn deregister(namespace: &str, service_name: &str, group_name: &str, instance: Instance) -> Self {
193 Self {
194 naming_request: NamingRequest::new(namespace, service_name, group_name),
195 r#type: DEREGISTER_INSTANCE.to_string(),
196 instance,
197 }
198 }
199
200 pub fn update(namespace: &str, service_name: &str, group_name: &str, instance: Instance) -> Self {
201 Self {
202 naming_request: NamingRequest::new(namespace, service_name, group_name),
203 r#type: UPDATE_INSTANCE.to_string(),
204 instance,
205 }
206 }
207}
208
209impl RequestTrait for InstanceRequest {
210 fn headers(&self) -> HashMap<String, String> {
211 self.naming_request.headers()
212 }
213
214 fn request_type(&self) -> &'static str {
215 "InstanceRequest"
216 }
217
218 fn insert_headers(&mut self, headers: HashMap<String, String>) {
219 self.naming_request.insert_headers(headers);
220 }
221
222 fn request_id(&self) -> String {
223 self.naming_request.request_id()
224 }
225}
226
227#[derive(Clone, Debug, Default, Serialize, Deserialize)]
229#[serde(rename_all = "camelCase")]
230pub struct InstanceResponse {
231 #[serde(flatten)]
232 pub response: Response,
233 pub r#type: String,
234}
235
236impl ResponseTrait for InstanceResponse {
237 fn response_type(&self) -> &'static str {
238 "InstanceResponse"
239 }
240
241 fn set_request_id(&mut self, request_id: String) {
242 self.response.request_id = request_id;
243 }
244
245 fn error_code(&self) -> i32 {
246 self.response.error_code
247 }
248
249 fn result_code(&self) -> i32 {
250 self.response.result_code
251 }
252
253 fn message(&self) -> String {
254 self.response.message.clone()
255 }
256}
257
258#[derive(Clone, Debug, Default, Serialize, Deserialize)]
262#[serde(rename_all = "camelCase")]
263pub struct BatchInstanceRequest {
264 #[serde(flatten)]
265 pub naming_request: NamingRequest,
266 pub r#type: String,
267 pub instances: Vec<Instance>,
268}
269
270impl BatchInstanceRequest {
271 pub fn register(namespace: &str, service_name: &str, group_name: &str, instances: Vec<Instance>) -> Self {
272 Self {
273 naming_request: NamingRequest::new(namespace, service_name, group_name),
274 r#type: REGISTER_INSTANCE.to_string(),
275 instances,
276 }
277 }
278
279 pub fn deregister(namespace: &str, service_name: &str, group_name: &str, instances: Vec<Instance>) -> Self {
280 Self {
281 naming_request: NamingRequest::new(namespace, service_name, group_name),
282 r#type: DEREGISTER_INSTANCE.to_string(),
283 instances,
284 }
285 }
286}
287
288impl RequestTrait for BatchInstanceRequest {
289 fn headers(&self) -> HashMap<String, String> {
290 self.naming_request.headers()
291 }
292
293 fn request_type(&self) -> &'static str {
294 "BatchInstanceRequest"
295 }
296
297 fn insert_headers(&mut self, headers: HashMap<String, String>) {
298 self.naming_request.insert_headers(headers);
299 }
300
301 fn request_id(&self) -> String {
302 self.naming_request.request_id()
303 }
304}
305
306#[derive(Clone, Debug, Default, Serialize, Deserialize)]
308#[serde(rename_all = "camelCase")]
309pub struct BatchInstanceResponse {
310 #[serde(flatten)]
311 pub response: Response,
312 pub r#type: String,
313}
314
315impl ResponseTrait for BatchInstanceResponse {
316 fn response_type(&self) -> &'static str {
317 "BatchInstanceResponse"
318 }
319
320 fn set_request_id(&mut self, request_id: String) {
321 self.response.request_id = request_id;
322 }
323
324 fn error_code(&self) -> i32 {
325 self.response.error_code
326 }
327
328 fn result_code(&self) -> i32 {
329 self.response.result_code
330 }
331
332 fn message(&self) -> String {
333 self.response.message.clone()
334 }
335}
336
337#[derive(Clone, Debug, Default, Serialize, Deserialize)]
341#[serde(rename_all = "camelCase")]
342pub struct ServiceQueryRequest {
343 #[serde(flatten)]
344 pub naming_request: NamingRequest,
345 pub cluster: String,
346 pub healthy_only: bool,
347 pub udp_port: i32,
348}
349
350impl ServiceQueryRequest {
351 pub fn new(namespace: &str, service_name: &str, group_name: &str) -> Self {
352 Self {
353 naming_request: NamingRequest::new(namespace, service_name, group_name),
354 cluster: String::new(),
355 healthy_only: false,
356 udp_port: 0,
357 }
358 }
359
360 pub fn with_cluster(mut self, cluster: &str) -> Self {
361 self.cluster = cluster.to_string();
362 self
363 }
364
365 pub fn with_healthy_only(mut self, healthy_only: bool) -> Self {
366 self.healthy_only = healthy_only;
367 self
368 }
369}
370
371impl RequestTrait for ServiceQueryRequest {
372 fn headers(&self) -> HashMap<String, String> {
373 self.naming_request.headers()
374 }
375
376 fn request_type(&self) -> &'static str {
377 "ServiceQueryRequest"
378 }
379
380 fn insert_headers(&mut self, headers: HashMap<String, String>) {
381 self.naming_request.insert_headers(headers);
382 }
383
384 fn request_id(&self) -> String {
385 self.naming_request.request_id()
386 }
387}
388
389#[derive(Clone, Debug, Default, Serialize, Deserialize)]
391#[serde(rename_all = "camelCase")]
392pub struct QueryServiceResponse {
393 #[serde(flatten)]
394 pub response: Response,
395 pub service_info: Service,
396}
397
398impl ResponseTrait for QueryServiceResponse {
399 fn response_type(&self) -> &'static str {
400 "QueryServiceResponse"
401 }
402
403 fn set_request_id(&mut self, request_id: String) {
404 self.response.request_id = request_id;
405 }
406
407 fn error_code(&self) -> i32 {
408 self.response.error_code
409 }
410
411 fn result_code(&self) -> i32 {
412 self.response.result_code
413 }
414
415 fn message(&self) -> String {
416 self.response.message.clone()
417 }
418}
419
420#[derive(Clone, Debug, Default, Serialize, Deserialize)]
424#[serde(rename_all = "camelCase")]
425pub struct ServiceListRequest {
426 #[serde(flatten)]
427 pub naming_request: NamingRequest,
428 pub page_no: i32,
429 pub page_size: i32,
430 pub selector: String,
431}
432
433impl ServiceListRequest {
434 pub fn new(namespace: &str, group_name: &str) -> Self {
435 Self {
436 naming_request: NamingRequest::new(namespace, "", group_name),
437 page_no: 1,
438 page_size: 100,
439 selector: String::new(),
440 }
441 }
442
443 pub fn with_page(mut self, page_no: i32, page_size: i32) -> Self {
444 self.page_no = page_no;
445 self.page_size = page_size;
446 self
447 }
448}
449
450impl RequestTrait for ServiceListRequest {
451 fn headers(&self) -> HashMap<String, String> {
452 self.naming_request.headers()
453 }
454
455 fn request_type(&self) -> &'static str {
456 "ServiceListRequest"
457 }
458
459 fn insert_headers(&mut self, headers: HashMap<String, String>) {
460 self.naming_request.insert_headers(headers);
461 }
462
463 fn request_id(&self) -> String {
464 self.naming_request.request_id()
465 }
466}
467
468#[derive(Clone, Debug, Default, Serialize, Deserialize)]
470#[serde(rename_all = "camelCase")]
471pub struct ServiceListResponse {
472 #[serde(flatten)]
473 pub response: Response,
474 pub count: i32,
475 pub service_names: Vec<String>,
476}
477
478impl ResponseTrait for ServiceListResponse {
479 fn response_type(&self) -> &'static str {
480 "ServiceListResponse"
481 }
482
483 fn set_request_id(&mut self, request_id: String) {
484 self.response.request_id = request_id;
485 }
486
487 fn error_code(&self) -> i32 {
488 self.response.error_code
489 }
490
491 fn result_code(&self) -> i32 {
492 self.response.result_code
493 }
494
495 fn message(&self) -> String {
496 self.response.message.clone()
497 }
498}
499
500#[derive(Clone, Debug, Default, Serialize, Deserialize)]
504#[serde(rename_all = "camelCase")]
505pub struct SubscribeServiceRequest {
506 #[serde(flatten)]
507 pub naming_request: NamingRequest,
508 pub subscribe: bool,
509 pub clusters: String,
510}
511
512impl SubscribeServiceRequest {
513 pub fn subscribe(namespace: &str, service_name: &str, group_name: &str) -> Self {
514 Self {
515 naming_request: NamingRequest::new(namespace, service_name, group_name),
516 subscribe: true,
517 clusters: String::new(),
518 }
519 }
520
521 pub fn unsubscribe(namespace: &str, service_name: &str, group_name: &str) -> Self {
522 Self {
523 naming_request: NamingRequest::new(namespace, service_name, group_name),
524 subscribe: false,
525 clusters: String::new(),
526 }
527 }
528
529 pub fn with_clusters(mut self, clusters: &str) -> Self {
530 self.clusters = clusters.to_string();
531 self
532 }
533}
534
535impl RequestTrait for SubscribeServiceRequest {
536 fn headers(&self) -> HashMap<String, String> {
537 self.naming_request.headers()
538 }
539
540 fn request_type(&self) -> &'static str {
541 "SubscribeServiceRequest"
542 }
543
544 fn insert_headers(&mut self, headers: HashMap<String, String>) {
545 self.naming_request.insert_headers(headers);
546 }
547
548 fn request_id(&self) -> String {
549 self.naming_request.request_id()
550 }
551}
552
553#[derive(Clone, Debug, Default, Serialize, Deserialize)]
555#[serde(rename_all = "camelCase")]
556pub struct SubscribeServiceResponse {
557 #[serde(flatten)]
558 pub response: Response,
559 pub service_info: Service,
560}
561
562impl ResponseTrait for SubscribeServiceResponse {
563 fn response_type(&self) -> &'static str {
564 "SubscribeServiceResponse"
565 }
566
567 fn set_request_id(&mut self, request_id: String) {
568 self.response.request_id = request_id;
569 }
570
571 fn error_code(&self) -> i32 {
572 self.response.error_code
573 }
574
575 fn result_code(&self) -> i32 {
576 self.response.result_code
577 }
578
579 fn message(&self) -> String {
580 self.response.message.clone()
581 }
582}
583
584#[derive(Clone, Debug, Default, Serialize, Deserialize)]
588#[serde(rename_all = "camelCase")]
589pub struct NotifySubscriberRequest {
590 #[serde(flatten)]
591 pub request: Request,
592 pub namespace: String,
593 pub service_name: String,
594 pub group_name: String,
595 pub service_info: Service,
596 pub module: String,
597}
598
599impl RequestTrait for NotifySubscriberRequest {
600 fn headers(&self) -> HashMap<String, String> {
601 self.request.headers()
602 }
603
604 fn request_type(&self) -> &'static str {
605 "NotifySubscriberRequest"
606 }
607
608 fn insert_headers(&mut self, headers: HashMap<String, String>) {
609 self.request.insert_headers(headers);
610 }
611
612 fn request_id(&self) -> String {
613 self.request.request_id()
614 }
615}
616
617#[derive(Clone, Debug, Default, Serialize, Deserialize)]
619#[serde(rename_all = "camelCase")]
620pub struct NotifySubscriberResponse {
621 #[serde(flatten)]
622 pub response: Response,
623}
624
625impl NotifySubscriberResponse {
626 pub fn new() -> Self {
627 Self {
628 response: Response::new(),
629 }
630 }
631
632 pub fn to_payload(&self, request_id: &str) -> Payload {
633 let mut headers = HashMap::new();
634 headers.insert("requestId".to_string(), request_id.to_string());
635
636 let body = serde_json::to_vec(self).unwrap_or_default();
637
638 Payload {
639 metadata: Some(crate::api::Metadata {
640 r#type: "NotifySubscriberResponse".to_string(),
641 client_ip: String::new(),
642 headers,
643 }),
644 body: Some(Any {
645 type_url: String::new(),
646 value: body,
647 }),
648 }
649 }
650}
651
652impl ResponseTrait for NotifySubscriberResponse {
653 fn response_type(&self) -> &'static str {
654 "NotifySubscriberResponse"
655 }
656
657 fn set_request_id(&mut self, request_id: String) {
658 self.response.request_id = request_id;
659 }
660
661 fn error_code(&self) -> i32 {
662 self.response.error_code
663 }
664
665 fn result_code(&self) -> i32 {
666 self.response.result_code
667 }
668}