cx_sdk/client/
views.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 crate::{
18    auth::AuthContext,
19    com::coralogixapis::views::v1::services::{
20        CreateViewRequest,
21        CreateViewResponse,
22        DeleteViewRequest,
23        DeleteViewResponse,
24        GetViewRequest,
25        ListViewsRequest,
26        ReplaceViewRequest,
27        ReplaceViewResponse,
28        views_service_client::ViewsServiceClient,
29    },
30    error::{
31        Result,
32        SdkApiError,
33    },
34    metadata::CallProperties,
35    util::make_request_with_metadata,
36};
37
38pub use crate::com::coralogixapis::views::v1::{
39    CustomTimeSelection,
40    Filter,
41    QuickTimeSelection,
42    SearchQuery,
43    SelectedFilters,
44    TimeSelection,
45    services::View,
46    time_selection::SelectionType,
47};
48
49use tokio::sync::Mutex;
50use tonic::{
51    metadata::MetadataMap,
52    transport::{
53        Channel,
54        ClientTlsConfig,
55        Endpoint,
56    },
57};
58
59use crate::CoralogixRegion;
60
61const FEATURE_GROUP_ID: &str = "data-exploration";
62
63/// The Views API client.
64/// Read more at <https://coralogix.com/docs/user-guides/monitoring-and-insights/explore-screen/custom-views//>
65pub struct ViewsClient {
66    teams_level_metadata_map: MetadataMap,
67    service_client: Mutex<ViewsServiceClient<Channel>>,
68}
69
70impl ViewsClient {
71    /// Creates a new client for the Views API.
72    ///
73    /// # Arguments
74    /// * `auth_context` - The [`AuthContext`] to use for authentication.
75    /// * `region` - The [`CoralogixRegion`] to connect to.
76    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
77        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
78            .tls_config(ClientTlsConfig::new().with_native_roots())?
79            .connect_lazy();
80        let request_metadata: CallProperties = (&auth_context.user_level_api_key).into();
81        Ok(Self {
82            teams_level_metadata_map: request_metadata.to_metadata_map(),
83            service_client: Mutex::new(ViewsServiceClient::new(channel)),
84        })
85    }
86
87    /// Creates a new View
88    ///
89    /// # Arguments
90    /// * `view` - The [`View`] to create.
91    pub async fn create(&self, view: View) -> Result<CreateViewResponse> {
92        let request = make_request_with_metadata(
93            CreateViewRequest {
94                name: view.name,
95                search_query: view.search_query,
96                time_selection: view.time_selection,
97                filters: view.filters,
98                folder_id: view.folder_id,
99            },
100            &self.teams_level_metadata_map,
101        );
102        Ok(self
103            .service_client
104            .lock()
105            .await
106            .create_view(request)
107            .await
108            .map_err(|status| SdkApiError {
109                status,
110                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/CreateView".into(),
111                feature_group: FEATURE_GROUP_ID.into(),
112            })?
113            .into_inner())
114    }
115
116    /// Replaces the existing [`View`] identified by its id.
117    ///
118    /// # Arguments
119    /// * `view` - The view to replace.
120    pub async fn replace(&self, view: View) -> Result<ReplaceViewResponse> {
121        let request = make_request_with_metadata(
122            ReplaceViewRequest { view: Some(view) },
123            &self.teams_level_metadata_map,
124        );
125        Ok(self
126            .service_client
127            .lock()
128            .await
129            .replace_view(request)
130            .await
131            .map_err(|status| SdkApiError {
132                status,
133                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/ReplaceView"
134                    .to_string(),
135                feature_group: FEATURE_GROUP_ID.to_string(),
136            })?
137            .into_inner())
138    }
139
140    /// Deletes the [`View`] identified by its id.
141    ///
142    /// # Arguments
143    /// * `id` - The id of the view to delete.
144    pub async fn delete(&self, id: i32) -> Result<DeleteViewResponse> {
145        let request = make_request_with_metadata(
146            DeleteViewRequest { id: Some(id) },
147            &self.teams_level_metadata_map,
148        );
149        Ok(self
150            .service_client
151            .lock()
152            .await
153            .delete_view(request)
154            .await
155            .map_err(|status| SdkApiError {
156                status,
157                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/DeleteView"
158                    .to_string(),
159                feature_group: FEATURE_GROUP_ID.to_string(),
160            })?
161            .into_inner())
162    }
163
164    /// Retrieves the [`View`] by id.
165    ///
166    /// # Arguments
167    /// * `id` - The id of the view to retrieve.
168    pub async fn get(&self, id: i32) -> Result<Option<View>> {
169        let request = make_request_with_metadata(
170            GetViewRequest { id: Some(id) },
171            &self.teams_level_metadata_map,
172        );
173
174        Ok(self
175            .service_client
176            .lock()
177            .await
178            .get_view(request)
179            .await
180            .map_err(|status| SdkApiError {
181                status,
182                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/GetView".to_string(),
183                feature_group: FEATURE_GROUP_ID.to_string(),
184            })?
185            .into_inner()
186            .view)
187    }
188
189    /// Retrieves a list of all [`View`]s.
190    ///     
191    /// # Returns
192    /// A list of all views.
193    pub async fn list(&self) -> Result<Vec<View>> {
194        let request =
195            make_request_with_metadata(ListViewsRequest {}, &self.teams_level_metadata_map);
196
197        Ok(self
198            .service_client
199            .lock()
200            .await
201            .list_views(request)
202            .await
203            .map_err(|status| SdkApiError {
204                status,
205                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/ListViews".to_string(),
206                feature_group: FEATURE_GROUP_ID.to_string(),
207            })?
208            .into_inner()
209            .views)
210    }
211}