cx_sdk/client/
incidents.rs

1// Copyright 2025 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::incidents::v1::{
18    AcknowledgeIncidentsRequest,
19    AcknowledgeIncidentsResponse,
20    AssignIncidentsRequest,
21    AssignIncidentsResponse,
22    BatchGetIncidentRequest,
23    BatchGetIncidentResponse,
24    CloseIncidentsRequest,
25    CloseIncidentsResponse,
26    GetFilterValuesRequest,
27    GetFilterValuesResponse,
28    GetIncidentEventsRequest,
29    GetIncidentEventsResponse,
30    GetIncidentRequest,
31    GetIncidentResponse,
32    GetIncidentUsingCorrelationKeyRequest,
33    GetIncidentUsingCorrelationKeyResponse,
34    ListIncidentAggregationsRequest,
35    ListIncidentAggregationsResponse,
36    ListIncidentEventsFilterValuesRequest,
37    ListIncidentEventsFilterValuesResponse,
38    ListIncidentEventsRequest,
39    ListIncidentEventsResponse,
40    ListIncidentEventsTotalCountRequest,
41    ListIncidentEventsTotalCountResponse,
42    ListIncidentsRequest,
43    ResolveIncidentsRequest,
44    ResolveIncidentsResponse,
45    UnassignIncidentsRequest,
46    UnassignIncidentsResponse,
47    incidents_service_client::IncidentsServiceClient,
48};
49pub use cx_api::proto::com::coralogixapis::incidents::v1::{
50    ContextualLabelValues,
51    FilterOperator,
52    GroupBy,
53    IncidentEventOrderByFieldType,
54    IncidentEventQueryFilter,
55    IncidentFields,
56    IncidentQueryFilter,
57    IncidentSearchQuery,
58    IncidentSeverity,
59    IncidentStatus,
60    LabelsFilter,
61    ListIncidentEventRequestOrderBy,
62    ListIncidentsResponse,
63    MetaLabel,
64    OrderBy,
65    OrderByDirection,
66    OrderByFields,
67    PaginationRequest,
68    TimeRange,
69    UserDetails,
70    incident_search_query::Field,
71    order_by::Field as OrderByField,
72};
73use time::OffsetDateTime;
74use tokio::sync::Mutex;
75use tonic::{
76    metadata::MetadataMap,
77    transport::{
78        Channel,
79        ClientTlsConfig,
80        Endpoint,
81    },
82};
83
84use crate::{
85    CoralogixRegion,
86    auth::AuthContext,
87    error::SdkApiError,
88    metadata::CallProperties,
89    util::make_request_with_metadata,
90};
91
92const INCIDENTS_FEATURE_GROUP_ID: &str = "incidents";
93
94/// IncidentsClient is a client for the Incidents API.
95pub struct IncidentsClient {
96    service_client: Mutex<IncidentsServiceClient<Channel>>,
97    metadata_map: MetadataMap,
98}
99
100impl IncidentsClient {
101    /// Creates a new IncidentsClient.
102    /// # Arguments
103    /// * `auth_context` - The [`AuthContext`] to use for authentication.
104    /// * `region` - The [`CoralogixRegion`] to connect to.
105    pub async fn new(
106        auth_context: AuthContext,
107        region: CoralogixRegion,
108    ) -> Result<Self, Box<dyn std::error::Error>> {
109        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
110            .tls_config(ClientTlsConfig::new().with_native_roots())?
111            .connect_lazy();
112
113        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
114        Ok(Self {
115            metadata_map: request_metadata.to_metadata_map(),
116            service_client: Mutex::new(IncidentsServiceClient::new(channel)),
117        })
118    }
119
120    /// Gets an incident by its ID.
121    /// # Arguments
122    /// * `id` - The ID of the incident to get.
123    pub async fn get_incident(
124        &self,
125        id: &str,
126    ) -> Result<GetIncidentResponse, Box<dyn std::error::Error>> {
127        let request = make_request_with_metadata(
128            GetIncidentRequest {
129                id: Some(id.to_string()),
130            },
131            &self.metadata_map,
132        );
133        let response = self
134            .service_client
135            .lock()
136            .await
137            .get_incident(request)
138            .await
139            .map_err(|status| SdkApiError {
140                status,
141                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/GetIncident".into(),
142                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
143            })?;
144        Ok(response.into_inner())
145    }
146
147    /// Batch gets incidents by their IDs.
148    /// # Arguments
149    /// * `ids` - The IDs of the incidents to get.
150    pub async fn batch_get_incident(
151        &self,
152        ids: Vec<String>,
153    ) -> Result<BatchGetIncidentResponse, Box<dyn std::error::Error>> {
154        let request =
155            make_request_with_metadata(BatchGetIncidentRequest { ids }, &self.metadata_map);
156        let response = self
157            .service_client
158            .lock()
159            .await
160            .batch_get_incident(request)
161            .await
162            .map_err(|status| SdkApiError {
163                status,
164                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/BatchGetIncident"
165                    .into(),
166                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
167            })?;
168        Ok(response.into_inner())
169    }
170
171    /// Lists incidents.
172    /// # Arguments
173    /// * `filter` - The [`IncidentQueryFilter`] to filter the incidents by.
174    /// * `pagination` - The [`PaginationRequest`] to paginate the incidents.
175    /// * `order_bys` - The [`OrderBy`]s to order the incidents by.
176    pub async fn list_incidents(
177        &self,
178        filter: Option<IncidentQueryFilter>,
179        pagination: Option<PaginationRequest>,
180        order_bys: Vec<OrderBy>,
181    ) -> Result<ListIncidentsResponse, Box<dyn std::error::Error>> {
182        let request = make_request_with_metadata(
183            ListIncidentsRequest {
184                filter,
185                pagination,
186                order_bys,
187            },
188            &self.metadata_map,
189        );
190
191        let response = self
192            .service_client
193            .lock()
194            .await
195            .list_incidents(request)
196            .await
197            .map_err(|status| SdkApiError {
198                status,
199                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/ListIncidents".into(),
200                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
201            })?;
202        Ok(response.into_inner())
203    }
204
205    /// Lists incident aggregations.
206    /// # Arguments
207    /// * `request` - The [`ListIncidentAggregationsRequest`] to list the incident aggregations.
208    pub async fn list_incident_aggregations(
209        &self,
210        filter: Option<IncidentQueryFilter>,
211        group_bys: Vec<GroupBy>,
212        pagination: Option<PaginationRequest>,
213    ) -> Result<ListIncidentAggregationsResponse, Box<dyn std::error::Error>> {
214        let request = make_request_with_metadata(
215            ListIncidentAggregationsRequest {
216                filter,
217                group_bys,
218                pagination,
219            },
220            &self.metadata_map,
221        );
222        let response = self
223            .service_client
224            .lock()
225            .await
226            .list_incident_aggregations(request)
227            .await
228            .map_err(|status| SdkApiError {
229                status,
230                endpoint:
231                    "/com.coralogixapis.incidents.v1.IncidentsService/ListIncidentAggregations"
232                        .into(),
233                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
234            })?;
235        Ok(response.into_inner())
236    }
237
238    /// Gets the filter values for a given filter.
239    /// # Arguments
240    /// * `filter` - The [`IncidentQueryFilter`] to get the filter values for.
241    pub async fn get_filter_values(
242        &self,
243        filter: IncidentQueryFilter,
244    ) -> Result<GetFilterValuesResponse, Box<dyn std::error::Error>> {
245        let request = make_request_with_metadata(
246            GetFilterValuesRequest {
247                filter: Some(filter),
248            },
249            &self.metadata_map,
250        );
251        let response = self
252            .service_client
253            .lock()
254            .await
255            .get_filter_values(request)
256            .await
257            .map_err(|status| SdkApiError {
258                status,
259                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/GetFilterValues".into(),
260                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
261            })?;
262        Ok(response.into_inner())
263    }
264
265    /// Assigns incidents to a user.
266    /// # Arguments
267    /// * `incident_ids` - The IDs of the incidents to assign.
268    /// * `assigned_to` - The [`UserDetails`] to assign the incidents to.
269    pub async fn assign_incidents(
270        &self,
271        incident_ids: Vec<String>,
272        assigned_to: Option<UserDetails>,
273    ) -> Result<AssignIncidentsResponse, Box<dyn std::error::Error>> {
274        let request = make_request_with_metadata(
275            AssignIncidentsRequest {
276                incident_ids,
277                assigned_to,
278            },
279            &self.metadata_map,
280        );
281        let response = self
282            .service_client
283            .lock()
284            .await
285            .assign_incidents(request)
286            .await?;
287        Ok(response.into_inner())
288    }
289
290    /// Unassigns incidents from a user.
291    /// # Arguments
292    /// * `incident_ids` - The IDs of the incidents to unassign.
293    pub async fn unassign_incidents(
294        &self,
295        incident_ids: Vec<String>,
296    ) -> Result<UnassignIncidentsResponse, Box<dyn std::error::Error>> {
297        let request = make_request_with_metadata(
298            UnassignIncidentsRequest { incident_ids },
299            &self.metadata_map,
300        );
301        let response = self
302            .service_client
303            .lock()
304            .await
305            .unassign_incidents(request)
306            .await
307            .map_err(|status| SdkApiError {
308                status,
309                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/UnassignIncidents"
310                    .into(),
311                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
312            })?;
313        Ok(response.into_inner())
314    }
315
316    /// Acknowledges incidents.
317    /// # Arguments
318    /// * `incident_ids` - The IDs of the incidents to acknowledge.
319    pub async fn acknowledge_incidents(
320        &self,
321        incident_ids: Vec<String>,
322    ) -> Result<AcknowledgeIncidentsResponse, Box<dyn std::error::Error>> {
323        let request = make_request_with_metadata(
324            AcknowledgeIncidentsRequest { incident_ids },
325            &self.metadata_map,
326        );
327        let response = self
328            .service_client
329            .lock()
330            .await
331            .acknowledge_incidents(request)
332            .await
333            .map_err(|status| SdkApiError {
334                status,
335                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/AcknowledgeIncidents"
336                    .into(),
337                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
338            })?;
339        Ok(response.into_inner())
340    }
341
342    /// Closes incidents.
343    /// # Arguments
344    /// * `incident_ids` - The IDs of the incidents to close.
345    pub async fn close_incidents(
346        &self,
347        incident_ids: Vec<String>,
348    ) -> Result<CloseIncidentsResponse, Box<dyn std::error::Error>> {
349        let request =
350            make_request_with_metadata(CloseIncidentsRequest { incident_ids }, &self.metadata_map);
351        let response = self
352            .service_client
353            .lock()
354            .await
355            .close_incidents(request)
356            .await
357            .map_err(|status| SdkApiError {
358                status,
359                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/CloseIncidents".into(),
360                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
361            })?;
362        Ok(response.into_inner())
363    }
364
365    /// Gets the events for an incident.
366    /// # Arguments
367    /// * `incident_id` - The ID of the incident to get the events for.
368    pub async fn get_incident_events(
369        &self,
370        incident_id: Option<String>,
371    ) -> Result<GetIncidentEventsResponse, Box<dyn std::error::Error>> {
372        let request = make_request_with_metadata(
373            GetIncidentEventsRequest { incident_id },
374            &self.metadata_map,
375        );
376        let response = self
377            .service_client
378            .lock()
379            .await
380            .get_incident_events(request)
381            .await?;
382        Ok(response.into_inner())
383    }
384
385    /// Resolves incidents.
386    /// # Arguments
387    /// * `incident_ids` - The IDs of the incidents to resolve.
388    pub async fn resolve_incidents(
389        &self,
390        incident_ids: Vec<String>,
391    ) -> Result<ResolveIncidentsResponse, Box<dyn std::error::Error>> {
392        let request = make_request_with_metadata(
393            ResolveIncidentsRequest { incident_ids },
394            &self.metadata_map,
395        );
396        let response = self
397            .service_client
398            .lock()
399            .await
400            .resolve_incidents(request)
401            .await
402            .map_err(|status| SdkApiError {
403                status,
404                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/ResolveIncidents"
405                    .into(),
406                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
407            })?;
408        Ok(response.into_inner())
409    }
410
411    /// Gets an incident by its correlation key and specific point in time.
412    /// # Arguments
413    /// * `correlation_key` - The correlation key of the incident to get.
414    /// * `timestamp` - The timestamp to get the incident at.
415    pub async fn get_incident_using_correlation_key(
416        &self,
417        correlation_key: String,
418        timestamp: OffsetDateTime,
419    ) -> Result<GetIncidentUsingCorrelationKeyResponse, Box<dyn std::error::Error>> {
420        let request = make_request_with_metadata(
421            GetIncidentUsingCorrelationKeyRequest {
422                correlation_key: Some(correlation_key),
423                incident_point_in_time: Some(timestamp.to_string().parse().unwrap()),
424            },
425            &self.metadata_map,
426        );
427        let response = self
428            .service_client
429            .lock()
430            .await
431            .get_incident_using_correlation_key(request)
432            .await
433            .map_err(|status| SdkApiError {
434                status,
435                endpoint:
436                    "/com.coralogixapis.incidents.v1.IncidentsService/GetIncidentUsingCorrelationKey"
437                        .into(),
438                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
439            })?;
440        Ok(response.into_inner())
441    }
442
443    /// Lists the events for an incident.
444    /// # Arguments
445    /// * `incident_id` - The ID of the incident to get the events for.
446    pub async fn list_incident_events(
447        &self,
448        filter: Option<IncidentEventQueryFilter>,
449        pagination: Option<PaginationRequest>,
450        order_by: Option<ListIncidentEventRequestOrderBy>,
451    ) -> Result<ListIncidentEventsResponse, Box<dyn std::error::Error>> {
452        let request = make_request_with_metadata(
453            ListIncidentEventsRequest {
454                filter,
455                pagination,
456                order_by,
457            },
458            &self.metadata_map,
459        );
460        let response = self
461            .service_client
462            .lock()
463            .await
464            .list_incident_events(request)
465            .await
466            .map_err(|status| SdkApiError {
467                status,
468                endpoint: "/com.coralogixapis.incidents.v1.IncidentsService/ListIncidentEvents"
469                    .into(),
470                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
471            })?;
472        Ok(response.into_inner())
473    }
474
475    /// Lists the total count of events for an incident.
476    /// # Arguments
477    /// * `incident_id` - The ID of the incident to get the total count of events for.
478    pub async fn list_incident_events_total_count(
479        &self,
480        filter: Option<IncidentEventQueryFilter>,
481    ) -> Result<ListIncidentEventsTotalCountResponse, Box<dyn std::error::Error>> {
482        let request = make_request_with_metadata(
483            ListIncidentEventsTotalCountRequest { filter },
484            &self.metadata_map,
485        );
486        let response = self
487            .service_client
488            .lock()
489            .await
490            .list_incident_events_total_count(request)
491            .await
492            .map_err(|status| SdkApiError {
493                status,
494                endpoint:
495                    "/com.coralogixapis.incidents.v1.IncidentsService/ListIncidentEventsTotalCount"
496                        .into(),
497                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
498            })?;
499        Ok(response.into_inner())
500    }
501
502    /// Lists the filter values for an incident event.
503    /// # Arguments
504    /// * `filter` - The [`IncidentEventQueryFilter`] to get the filter values for.
505    pub async fn list_incident_events_filter_values(
506        &self,
507        filter: Option<IncidentEventQueryFilter>,
508    ) -> Result<ListIncidentEventsFilterValuesResponse, Box<dyn std::error::Error>> {
509        let request = make_request_with_metadata(
510            ListIncidentEventsFilterValuesRequest { filter },
511            &self.metadata_map,
512        );
513        let response = self
514            .service_client
515            .lock()
516            .await
517            .list_incident_events_filter_values(request)
518            .await
519            .map_err(|status| SdkApiError {
520                status,
521                endpoint:
522                    "/com.coralogixapis.incidents.v1.IncidentsService/ListIncidentEventsFilterValues"
523                        .into(),
524                feature_group: INCIDENTS_FEATURE_GROUP_ID.into(),
525            })?;
526        Ok(response.into_inner())
527    }
528}