cx_sdk/client/
notifications.rs

1// Copyright 2024 Coralogix Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::str::FromStr;
16
17use cx_api::proto::com::coralogixapis::notification_center::{
18    connectors::v1::{
19        BatchGetConnectorsRequest,
20        BatchGetConnectorsResponse,
21        CreateConnectorRequest,
22        CreateConnectorResponse,
23        DeleteConnectorRequest,
24        DeleteConnectorResponse,
25        GetConnectorRequest,
26        GetConnectorResponse,
27        GetConnectorTypeSummariesRequest,
28        GetConnectorTypeSummariesResponse,
29        ListConnectorsRequest,
30        ListConnectorsResponse,
31        ReplaceConnectorRequest,
32        ReplaceConnectorResponse,
33        connectors_service_client::ConnectorsServiceClient,
34    },
35    notifications::v1::{
36        TestConnectorConfigRequest,
37        TestConnectorConfigResponse,
38        TestDestinationRequest,
39        TestDestinationResponse,
40        TestExistingConnectorRequest,
41        TestExistingConnectorResponse,
42        TestExistingPresetRequest,
43        TestExistingPresetResponse,
44        TestPresetConfigRequest,
45        TestPresetConfigResponse,
46        TestRoutingConditionValidRequest,
47        TestRoutingConditionValidResponse,
48        TestTemplateRenderRequest,
49        TestTemplateRenderResponse,
50        testing_service_client::TestingServiceClient,
51    },
52    presets::v1::{
53        BatchGetPresetsRequest,
54        BatchGetPresetsResponse,
55        CreateCustomPresetRequest,
56        CreateCustomPresetResponse,
57        DeleteCustomPresetRequest,
58        DeleteCustomPresetResponse,
59        GetDefaultPresetSummaryRequest,
60        GetDefaultPresetSummaryResponse,
61        GetPresetRequest,
62        GetPresetResponse,
63        GetSystemDefaultPresetSummaryRequest,
64        GetSystemDefaultPresetSummaryResponse,
65        ListPresetSummariesRequest,
66        ListPresetSummariesResponse,
67        ReplaceCustomPresetRequest,
68        ReplaceCustomPresetResponse,
69        SetPresetAsDefaultRequest,
70        SetPresetAsDefaultResponse,
71        presets_service_client::PresetsServiceClient,
72    },
73    routers::v1::{
74        BatchGetGlobalRoutersRequest,
75        BatchGetGlobalRoutersResponse,
76        CreateOrReplaceGlobalRouterRequest,
77        CreateOrReplaceGlobalRouterResponse,
78        DeleteGlobalRouterRequest,
79        DeleteGlobalRouterResponse,
80        GetGlobalRouterRequest,
81        GetGlobalRouterResponse,
82        ListGlobalRoutersRequest,
83        ListGlobalRoutersResponse,
84        global_routers_service_client::GlobalRoutersServiceClient,
85    },
86};
87
88pub use cx_api::proto::com::coralogixapis::notification_center::{
89    ConditionType,
90    ConfigOverrides,
91    ConnectorConfigField,
92    ConnectorType,
93    EntityType,
94    MatchEntityTypeAndSubTypeCondition,
95    MatchEntityTypeCondition,
96    MessageConfig,
97    MessageConfigField,
98    TemplatedConnectorConfigField,
99    condition_type,
100    connectors::v1::{
101        Connector,
102        ConnectorConfig,
103        EntityTypeConfigOverrides,
104    },
105    notifications::v1::{
106        TestResult,
107        test_result,
108        test_template_render_result,
109    },
110    presets::v1::Preset,
111    presets::v1::PresetType,
112    routers::v1::GlobalRouter,
113    routing::{
114        RoutingRule,
115        RoutingTarget,
116    },
117};
118
119use tokio::sync::Mutex;
120use tonic::{
121    metadata::MetadataMap,
122    transport::{
123        Channel,
124        ClientTlsConfig,
125        Endpoint,
126    },
127};
128
129use crate::{
130    CoralogixRegion,
131    auth::AuthContext,
132    error::{
133        Result,
134        SdkApiError,
135        SdkError,
136    },
137    metadata::CallProperties,
138    util::make_request_with_metadata,
139};
140
141const NOTIFICATIONS_FEATURE_GROUP_ID: &str = "notifications";
142
143/// A client for interacting with the Coralogix Notification Center APIs.
144pub struct NotificationsClient {
145    metadata_map: MetadataMap,
146    connectors_client: Mutex<ConnectorsServiceClient<Channel>>,
147    presets_client: Mutex<PresetsServiceClient<Channel>>,
148    global_routers_client: Mutex<GlobalRoutersServiceClient<Channel>>,
149    testing_client: Mutex<TestingServiceClient<Channel>>,
150}
151
152impl NotificationsClient {
153    /// Creates a new client for the Notification Center.
154    /// # Arguments
155    /// * `auth_context` - The [`AuthContext`] to use for authentication.
156    /// * `region` - The [`CoralogixRegion`] to connect to.
157    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
158        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
159            .tls_config(ClientTlsConfig::new().with_native_roots())?
160            .connect_lazy();
161        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
162        Ok(Self {
163            metadata_map: request_metadata.to_metadata_map(),
164            connectors_client: Mutex::new(ConnectorsServiceClient::new(channel.clone())),
165            presets_client: Mutex::new(PresetsServiceClient::new(channel.clone())),
166            global_routers_client: Mutex::new(GlobalRoutersServiceClient::new(channel.clone())),
167            testing_client: Mutex::new(TestingServiceClient::new(channel)),
168        })
169    }
170
171    /// Get a connector by ID.
172    /// # Arguments
173    /// * `connector_id` - The ID of the connector to get.
174    pub async fn get_connector(&self, connector_id: String) -> Result<GetConnectorResponse> {
175        let request = make_request_with_metadata(
176            GetConnectorRequest { id: connector_id },
177            &self.metadata_map,
178        );
179        {
180            let mut client = self.connectors_client.lock().await.clone();
181            client
182                .get_connector(request)
183                .await
184                .map(|r| r.into_inner())
185                .map_err(
186                    |status| SdkError::ApiError(SdkApiError {
187                        status,
188                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/GetConnector".into(),
189                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
190                    },
191                ))
192        }
193    }
194
195    /// List all connectors.
196    /// # Arguments
197    /// * `connector_type` - The [`ConnectorType`] to filter by.
198    pub async fn list_connectors(
199        &self,
200        connector_type: ConnectorType,
201    ) -> Result<ListConnectorsResponse> {
202        let request = make_request_with_metadata(
203            ListConnectorsRequest {
204                connector_type: connector_type.into(),
205            },
206            &self.metadata_map,
207        );
208        {
209            let mut client = self.connectors_client.lock().await.clone();
210
211            client
212                .list_connectors(request)
213                .await
214                .map(|r| r.into_inner())
215                .map_err(
216                    |status| SdkError::ApiError(SdkApiError {
217                        status,
218                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/ListConnectors".into(),
219                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
220                    },
221                ))
222        }
223    }
224
225    /// Create a new connector.
226    /// # Arguments
227    /// * `connector` - The [`Connector`] to create.
228    pub async fn create_connector(&self, connector: Connector) -> Result<CreateConnectorResponse> {
229        let request = make_request_with_metadata(
230            CreateConnectorRequest {
231                connector: Some(connector),
232            },
233            &self.metadata_map,
234        );
235        {
236            let mut client = self.connectors_client.lock().await.clone();
237
238            client
239                .create_connector(request)
240                .await
241                .map(|r| r.into_inner())
242                .map_err(
243                    |status| SdkError::ApiError(SdkApiError {
244                        status,
245                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/CreateConnector".into(),
246                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
247                    },
248                ))
249        }
250    }
251
252    /// Replace an existing connector.
253    /// # Arguments
254    /// * `connector` - The [`Connector`] to replace.
255    pub async fn replace_connector(
256        &self,
257        connector: Connector,
258    ) -> Result<ReplaceConnectorResponse> {
259        let request = make_request_with_metadata(
260            ReplaceConnectorRequest {
261                connector: Some(connector),
262            },
263            &self.metadata_map,
264        );
265        {
266            let mut client = self.connectors_client.lock().await.clone();
267
268            client
269                .replace_connector(request)
270                .await
271                .map(|r| r.into_inner())
272                .map_err(
273                    |status| SdkError::ApiError(SdkApiError {
274                        status,
275                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/ReplaceConnector".into(),
276                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
277                    },
278                ))
279        }
280    }
281
282    /// Delete a connector by ID.
283    /// # Arguments
284    /// * `connector_id` - The ID of the connector to delete.
285    pub async fn delete_connector(&self, connector_id: String) -> Result<DeleteConnectorResponse> {
286        let request = make_request_with_metadata(
287            DeleteConnectorRequest { id: connector_id },
288            &self.metadata_map,
289        );
290        {
291            let mut client = self.connectors_client.lock().await.clone();
292
293            client
294                .delete_connector(request)
295                .await
296                .map(|r| r.into_inner())
297                .map_err(
298                    |status| SdkError::ApiError(SdkApiError {
299                        status,
300                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/DeleteConnector".into(),
301                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
302                    },
303                ))
304        }
305    }
306
307    /// Batch get connectors by ID.
308    /// # Arguments
309    /// * `connector_ids` - The IDs of the connectors to get.
310    pub async fn batch_get_connectors(
311        &self,
312        connector_ids: Vec<String>,
313    ) -> Result<BatchGetConnectorsResponse> {
314        let request = make_request_with_metadata(
315            BatchGetConnectorsRequest { connector_ids },
316            &self.metadata_map,
317        );
318        {
319            let mut client = self.connectors_client.lock().await.clone();
320
321            client
322                .batch_get_connectors(request)
323                .await
324                .map(|r| r.into_inner())
325                .map_err(
326                    |status| SdkError::ApiError(SdkApiError {
327                        status,
328                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/BatchGetConnectors".into(),
329                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
330                    },
331                ))
332        }
333    }
334
335    /// Get summaries of connector types.
336    pub async fn get_connector_type_summaries(&self) -> Result<GetConnectorTypeSummariesResponse> {
337        let request =
338            make_request_with_metadata(GetConnectorTypeSummariesRequest {}, &self.metadata_map);
339        {
340            let mut client = self.connectors_client.lock().await.clone();
341
342            client
343                .get_connector_type_summaries(request)
344                .await
345                .map(|r| r.into_inner())
346                .map_err(
347                    |status| SdkError::ApiError(SdkApiError {
348                        status,
349                        endpoint: "/com.coralogixapis.notification_center.connectors.v1.ConnectorsService/GetConnectorTypeSummaries".into(),
350                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
351                    },
352                ))
353        }
354    }
355
356    /// Create a new custom preset.
357    /// # Arguments
358    /// * `preset` - The [`Preset`] to create.
359    pub async fn create_custom_preset(&self, preset: Preset) -> Result<CreateCustomPresetResponse> {
360        let request = make_request_with_metadata(
361            CreateCustomPresetRequest {
362                preset: Some(preset),
363            },
364            &self.metadata_map,
365        );
366        {
367            let mut client = self.presets_client.lock().await.clone();
368
369            client
370                .create_custom_preset(request)
371                .await
372                .map(|r| r.into_inner())
373                .map_err(
374                    |status| SdkError::ApiError(SdkApiError {
375                        status,
376                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/CreateCustomPreset".into(),
377                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
378                    },
379                ))
380        }
381    }
382
383    /// Replace an existing custom preset.
384    /// # Arguments
385    /// * `preset` - The [`Preset`] to replace.
386    pub async fn replace_custom_preset(
387        &self,
388        preset: Preset,
389    ) -> Result<ReplaceCustomPresetResponse> {
390        let request = make_request_with_metadata(
391            ReplaceCustomPresetRequest {
392                preset: Some(preset),
393            },
394            &self.metadata_map,
395        );
396        {
397            let mut client = self.presets_client.lock().await.clone();
398
399            client
400                .replace_custom_preset(request)
401                .await
402                .map(|r| r.into_inner())
403                .map_err(
404                    |status| SdkError::ApiError(SdkApiError {
405                        status,
406                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/ReplaceCustomPreset".into(),
407                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
408                    },
409                ))
410        }
411    }
412
413    /// Delete a custom preset by ID.
414    /// # Arguments
415    /// * `id` - The ID of the preset to delete.
416    pub async fn delete_custom_preset(&self, id: String) -> Result<DeleteCustomPresetResponse> {
417        let request =
418            make_request_with_metadata(DeleteCustomPresetRequest { id }, &self.metadata_map);
419        {
420            let mut client = self.presets_client.lock().await.clone();
421
422            client
423                .delete_custom_preset(request)
424                .await
425                .map(|r| r.into_inner())
426                .map_err(
427                    |status| SdkError::ApiError(SdkApiError {
428                        status,
429                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/DeleteCustomPreset".into(),
430                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
431                    },
432                ))
433        }
434    }
435
436    /// Set a preset as the default.
437    /// # Arguments
438    /// * `id` - The user-facing ID of the preset to set as the default.
439    pub async fn set_preset_as_default(&self, id: String) -> Result<SetPresetAsDefaultResponse> {
440        let request =
441            make_request_with_metadata(SetPresetAsDefaultRequest { id }, &self.metadata_map);
442
443        let mut client = self.presets_client.lock().await.clone();
444
445        client
446            .set_preset_as_default(request)
447            .await
448            .map(|r| r.into_inner())
449            .map_err(|status| {
450                SdkError::ApiError(SdkApiError {
451                    status,
452                    endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/SetPresetAsDefault".into(),
453                    feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
454                })
455            })
456    }
457
458    /// Get a preset by ID.
459    /// # Arguments
460    /// * `id` - The ID of the preset to get.
461    pub async fn get_preset(&self, id: String) -> Result<GetPresetResponse> {
462        let request = make_request_with_metadata(GetPresetRequest { id }, &self.metadata_map);
463        {
464            let mut client = self.presets_client.lock().await.clone();
465
466            client
467                .get_preset(request)
468                .await
469                .map(|r| r.into_inner())
470                .map_err(
471                    |status| SdkError::ApiError(SdkApiError {
472                        status,
473                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/GetPreset".into(),
474                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
475                    },
476                ))
477        }
478    }
479
480    /// List summaries of presets.
481    /// # Arguments
482    /// * `connector_type` - The [`ConnectorType`] to list presets for.
483    /// * `entity_type` - The [`EntityType`] to list presets for.
484    pub async fn list_preset_summaries(
485        &self,
486        connector_type: Option<ConnectorType>,
487        entity_type: EntityType,
488    ) -> Result<ListPresetSummariesResponse> {
489        let request = make_request_with_metadata(
490            ListPresetSummariesRequest {
491                connector_type: connector_type.map(From::from),
492                entity_type: entity_type.into(),
493            },
494            &self.metadata_map,
495        );
496        {
497            let mut client = self.presets_client.lock().await.clone();
498
499            client
500                .list_preset_summaries(request)
501                .await
502                .map(|r| r.into_inner())
503                .map_err(
504                    |status| SdkError::ApiError(SdkApiError {
505                        status,
506                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/ListPresetSummaries".into(),
507                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
508                    },
509                ))
510        }
511    }
512
513    /// Batch get presets by ID.
514    /// # Arguments
515    /// * `preset_ids` - The IDs of the presets to get.
516    pub async fn batch_get_presets(
517        &self,
518        preset_ids: Vec<String>,
519    ) -> Result<BatchGetPresetsResponse> {
520        let request =
521            make_request_with_metadata(BatchGetPresetsRequest { preset_ids }, &self.metadata_map);
522        {
523            let mut client = self.presets_client.lock().await.clone();
524
525            client
526                .batch_get_presets(request)
527                .await
528                .map(|r| r.into_inner())
529                .map_err(
530                    |status| SdkError::ApiError(SdkApiError {
531                        status,
532                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/BatchGetPresets".into(),
533                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
534                    },
535                ))
536        }
537    }
538
539    /// Get the default preset summary.
540    /// # Arguments
541    /// * `connector_type` - The [`ConnectorType`] to get the default preset summary for.
542    /// * `entity_type` - The [`EntityType`] to get the default preset summary for.
543    pub async fn get_default_preset_summary(
544        &self,
545        connector_type: ConnectorType,
546        entity_type: EntityType,
547    ) -> Result<GetDefaultPresetSummaryResponse> {
548        let request = make_request_with_metadata(
549            GetDefaultPresetSummaryRequest {
550                connector_type: connector_type.into(),
551                entity_type: entity_type.into(),
552            },
553            &self.metadata_map,
554        );
555        {
556            let mut client = self.presets_client.lock().await.clone();
557
558            client
559                .get_default_preset_summary(request)
560                .await
561                .map(|r| r.into_inner())
562                .map_err(
563                    |status| SdkError::ApiError(SdkApiError {
564                        status,
565                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/GetDefaultPresetSummary".into(),
566                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
567                    },
568                ))
569        }
570    }
571
572    /// Get the system default preset summary.
573    /// # Arguments
574    /// * `connector_type` - The [`ConnectorType`] to get the system default preset summary for.
575    /// * `entity_type` - The [`EntityType`] to get the system default preset summary for.
576    pub async fn get_system_default_preset_summary(
577        &self,
578        connector_type: ConnectorType,
579        entity_type: EntityType,
580    ) -> Result<GetSystemDefaultPresetSummaryResponse> {
581        let request = make_request_with_metadata(
582            GetSystemDefaultPresetSummaryRequest {
583                connector_type: connector_type as i32,
584                entity_type: entity_type.into(),
585            },
586            &self.metadata_map,
587        );
588        {
589            let mut client = self.presets_client.lock().await.clone();
590
591            client
592                .get_system_default_preset_summary(request)
593                .await
594                .map(|r| r.into_inner())
595                .map_err(
596                    |status| SdkError::ApiError(SdkApiError {
597                        status,
598                        endpoint: "/com.coralogixapis.notification_center.presets.v1.PresetsService/GetSystemDefaultPresetSummary".into(),
599                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
600                    },
601                ))
602        }
603    }
604
605    /// Create or replace a global router.
606    /// # Arguments
607    /// * `global_router` - The [`GlobalRouter`] to create or replace.
608    pub async fn create_or_replace_global_router(
609        &self,
610        global_router: GlobalRouter,
611    ) -> Result<CreateOrReplaceGlobalRouterResponse> {
612        let request = make_request_with_metadata(
613            CreateOrReplaceGlobalRouterRequest {
614                router: Some(global_router),
615            },
616            &self.metadata_map,
617        );
618        let mut client = self.global_routers_client.lock().await.clone();
619
620        client
621            .create_or_replace_global_router(request)
622            .await
623            .map(|r| r.into_inner())
624            .map_err(|status| SdkError::ApiError(SdkApiError {
625                status,
626                endpoint: "/com.coralogixapis.notification_center.routers.v1.GlobalRoutersService/CreateOrReplaceGlobalRouter".into(),
627                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
628            }))
629    }
630
631    /// Delete a global router by identifier.
632    /// # Arguments
633    /// * `id` - The identifier of the global router to delete.
634    pub async fn delete_global_router(&self, id: String) -> Result<DeleteGlobalRouterResponse> {
635        let request =
636            make_request_with_metadata(DeleteGlobalRouterRequest { id }, &self.metadata_map);
637        let mut client = self.global_routers_client.lock().await.clone();
638
639        client
640            .delete_global_router(request)
641            .await
642            .map(|r| r.into_inner())
643            .map_err(|status| SdkError::ApiError(SdkApiError {
644                status,
645                endpoint: "/com.coralogixapis.notification_center.routers.v1.GlobalRoutersService/DeleteGlobalRouter".into(),
646                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
647            }))
648    }
649
650    /// Get a global router by identifier.
651    /// # Arguments
652    /// * `id` - The identifier of the global router to get.
653    pub async fn get_global_router(&self, id: String) -> Result<GetGlobalRouterResponse> {
654        let request = make_request_with_metadata(GetGlobalRouterRequest { id }, &self.metadata_map);
655        let mut client = self.global_routers_client.lock().await.clone();
656
657        client
658            .get_global_router(request)
659            .await
660            .map(|r| r.into_inner())
661            .map_err(|status| SdkError::ApiError(SdkApiError {
662                status,
663                endpoint: "/com.coralogixapis.notification_center.routers.v1.GlobalRoutersService/GetGlobalRouter".into(),
664                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
665            }))
666    }
667
668    /// List all global routers.
669    /// # Arguments
670    /// * `entity_type` - The [`EntityType`] to filter global routers by.
671    pub async fn list_global_routers(
672        &self,
673        entity_type: EntityType,
674    ) -> Result<ListGlobalRoutersResponse> {
675        let request = make_request_with_metadata(
676            ListGlobalRoutersRequest {
677                entity_type: Some(entity_type.into()),
678            },
679            &self.metadata_map,
680        );
681        let mut client = self.global_routers_client.lock().await.clone();
682
683        client
684            .list_global_routers(request)
685            .await
686            .map(|r| r.into_inner())
687            .map_err(|status| SdkError::ApiError(SdkApiError {
688                status,
689                endpoint: "/com.coralogixapis.notification_center.routers.v1.GlobalRoutersService/ListGlobalRouters".into(),
690                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
691            }))
692    }
693
694    /// Batch get global routers by identifiers.
695    /// # Arguments
696    /// * `ids` - The identifiers of the global routers to retrieve.
697    pub async fn batch_get_global_routers(
698        &self,
699        ids: Vec<String>,
700    ) -> Result<BatchGetGlobalRoutersResponse> {
701        let request = make_request_with_metadata(
702            BatchGetGlobalRoutersRequest {
703                global_router_ids: ids,
704            },
705            &self.metadata_map,
706        );
707        let mut client = self.global_routers_client.lock().await.clone();
708
709        client
710            .batch_get_global_routers(request)
711            .await
712            .map(|r| r.into_inner())
713            .map_err(|status| SdkError::ApiError(SdkApiError {
714                status,
715                endpoint: "/com.coralogixapis.notification_center.routers.v1.GlobalRoutersService/BatchGetGlobalRouters".into(),
716                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into(),
717            }))
718    }
719
720    /// Test a connector configuration.
721    /// # Arguments
722    /// * `connector_type` - The [`ConnectorType`] to test.
723    /// * `connector_config_fields` - The [ConnectorConfigField]s to test with.
724    /// * `entity_type` - The [`EntityType`] to test with.
725    /// * `payload_type` - The id of the output schema to test with.
726    pub async fn test_connector_config(
727        &self,
728        connector_type: ConnectorType,
729        connector_config_fields: Vec<ConnectorConfigField>,
730        entity_type: EntityType,
731        payload_type: String,
732    ) -> Result<TestConnectorConfigResponse> {
733        let request = make_request_with_metadata(
734            TestConnectorConfigRequest {
735                r#type: connector_type.into(),
736                fields: connector_config_fields,
737                entity_type: Some(entity_type.into()),
738                payload_type,
739            },
740            &self.metadata_map,
741        );
742        {
743            let mut client = self.testing_client.lock().await.clone();
744
745            client
746                .test_connector_config(request)
747                .await
748                .map(|r| r.into_inner())
749                .map_err(
750                    |status| SdkError::ApiError(SdkApiError {
751                        status,
752                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestConnectorConfig".into(),
753                                                feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
754                    },
755                ))
756        }
757    }
758
759    /// Test an existing connector.
760    /// # Arguments
761    /// * `connector_id` - The id of the connector to test.
762    pub async fn test_existing_connector(
763        &self,
764        connector_id: String,
765        payload_type: String,
766    ) -> Result<TestExistingConnectorResponse> {
767        let request = make_request_with_metadata(
768            TestExistingConnectorRequest {
769                connector_id,
770                payload_type,
771            },
772            &self.metadata_map,
773        );
774        {
775            let mut client = self.testing_client.lock().await.clone();
776
777            client
778                .test_existing_connector(request)
779                .await
780                .map(|r| r.into_inner())
781                .map_err(
782                    |status| SdkError::ApiError(SdkApiError {
783                        status,
784                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestExistingConnector".into(),
785                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
786                    },
787                ))
788        }
789    }
790
791    /// Test a preset configuration.
792    /// # Arguments
793    /// * `entity_type` - The entity type.
794    /// * `entity_sub_type` - The entity sub type.
795    /// * `connector_id` - The ID for the connector to test.
796    /// * `parent_preset_id` - The ID of the preset's parent to test.
797    /// * `config_overrides` - The set of [`ConfigOverrides`] to apply.
798    pub async fn test_preset_config(
799        &self,
800        entity_type: EntityType,
801        entity_sub_type: Option<String>,
802        connector_id: String,
803        parent_preset_id: String,
804        config_overrides: Vec<ConfigOverrides>,
805    ) -> Result<TestPresetConfigResponse> {
806        let request = make_request_with_metadata(
807            TestPresetConfigRequest {
808                entity_type: entity_type.into(),
809                entity_sub_type,
810                connector_id,
811                parent_preset_id,
812                config_overrides,
813            },
814            &self.metadata_map,
815        );
816        {
817            let mut client = self.testing_client.lock().await.clone();
818
819            client
820                .test_preset_config(request)
821                .await
822                .map(|r| r.into_inner())
823                .map_err(
824                    |status| SdkError::ApiError(SdkApiError {
825                        status,
826                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestPreset".into(),
827                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
828                    },
829                ))
830        }
831    }
832
833    /// Test a preset configuration.
834    /// # Arguments
835    /// * `entity_type` - The entity type.
836    /// * `entity_sub_type` - The entity sub type.
837    /// * `connector_id` - The ID for the connector to test.
838    /// * `preset_id` - The ID of the preset to test.
839    pub async fn test_existing_preset_config(
840        &self,
841        entity_type: EntityType,
842        entity_sub_type: Option<String>,
843        connector_id: String,
844        preset_id: String,
845    ) -> Result<TestExistingPresetResponse> {
846        let request = make_request_with_metadata(
847            TestExistingPresetRequest {
848                entity_type: entity_type.into(),
849                entity_sub_type,
850                connector_id,
851                preset_id,
852            },
853            &self.metadata_map,
854        );
855        {
856            let mut client = self.testing_client.lock().await.clone();
857
858            client
859                .test_existing_preset(request)
860                .await
861                .map(|r| r.into_inner())
862                .map_err(
863                    |status| SdkError::ApiError(SdkApiError {
864                        status,
865                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestExistingPreset".into(),
866                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
867                    },
868                ))
869        }
870    }
871
872    /// Test rendering a template.
873    /// # Arguments
874    /// * `entity_type` - The entity type to test with.
875    /// * `entity_sub_type` - The entity sub type to test with.
876    /// * `template` - The template to render.
877    pub async fn test_template_render(
878        &self,
879        entity_type: EntityType,
880        entity_sub_type: Option<String>,
881        template: String,
882    ) -> Result<TestTemplateRenderResponse> {
883        let request = make_request_with_metadata(
884            TestTemplateRenderRequest {
885                entity_type: entity_type.into(),
886                entity_sub_type,
887                template,
888            },
889            &self.metadata_map,
890        );
891        {
892            let mut client = self.testing_client.lock().await.clone();
893
894            client
895                .test_template_render(request)
896                .await
897                .map(|r| r.into_inner())
898                .map_err(
899                    |status| SdkError::ApiError(SdkApiError {
900                        status,
901                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestTemplateRender".into(),
902                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
903                    },
904                ))
905        }
906    }
907
908    /// Test a destination.
909    /// # Arguments
910    /// * `entity_type` - The entity type to test with.
911    /// * `entity_sub_type` - The entity sub type.
912    /// * `connector_config_fields` - Connector configuration (templated).
913    /// * `preset_id` - Preset ID.
914    /// * `connector_id` - Connector ID.
915    /// * `message_config_fields` - Message configuration.
916    #[allow(clippy::too_many_arguments)]
917    pub async fn test_destination(
918        &self,
919        entity_type: EntityType,
920        entity_sub_type: Option<String>,
921        connector_config_fields: Vec<TemplatedConnectorConfigField>,
922        preset_id: String,
923        connector_id: String,
924        message_config_fields: Vec<MessageConfigField>,
925        payload_type: String,
926    ) -> Result<TestDestinationResponse> {
927        let request = make_request_with_metadata(
928            TestDestinationRequest {
929                entity_type: entity_type.into(),
930                entity_sub_type,
931                connector_config_fields,
932                message_config_fields,
933                preset_id,
934                connector_id,
935                payload_type,
936            },
937            &self.metadata_map,
938        );
939        {
940            let mut client = self.testing_client.lock().await.clone();
941
942            client
943                .test_destination(request)
944                .await
945                .map(|r| r.into_inner())
946                .map_err(
947                    |status| SdkError::ApiError(SdkApiError {
948                        status,
949                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestDestination".into(),
950                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
951                    },
952                ))
953        }
954    }
955
956    /// Tests whether a routing condition is valid.
957    /// # Arguments
958    /// * `entity_type` - The entity type to test with.
959    /// * `template` - The template to render.
960    pub async fn test_routing_condition_valid(
961        &self,
962        entity_type: EntityType,
963        template: String,
964    ) -> Result<TestRoutingConditionValidResponse> {
965        let request = make_request_with_metadata(
966            TestRoutingConditionValidRequest {
967                entity_type: entity_type.into(),
968                template,
969            },
970            &self.metadata_map,
971        );
972        {
973            let mut client = self.testing_client.lock().await.clone();
974
975            client
976                .test_routing_condition_valid(request)
977                .await
978                .map(|r| r.into_inner())
979                .map_err(
980                    |status| SdkError::ApiError(SdkApiError {
981                        status,
982                        endpoint: "/com.coralogixapis.notification_center.notifications.v1.TestingService/TestRoutingConditionValid".into(),
983                        feature_group: NOTIFICATIONS_FEATURE_GROUP_ID.into()
984                    },
985                ))
986        }
987    }
988}