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                view_type: view.view_type,
100            },
101            &self.teams_level_metadata_map,
102        );
103        Ok(self
104            .service_client
105            .lock()
106            .await
107            .create_view(request)
108            .await
109            .map_err(|status| SdkApiError {
110                status,
111                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/CreateView".into(),
112                feature_group: FEATURE_GROUP_ID.into(),
113            })?
114            .into_inner())
115    }
116
117    /// Replaces the existing [`View`] identified by its id.
118    ///
119    /// # Arguments
120    /// * `view` - The view to replace.
121    pub async fn replace(&self, view: View) -> Result<ReplaceViewResponse> {
122        let request = make_request_with_metadata(
123            ReplaceViewRequest { view: Some(view) },
124            &self.teams_level_metadata_map,
125        );
126        Ok(self
127            .service_client
128            .lock()
129            .await
130            .replace_view(request)
131            .await
132            .map_err(|status| SdkApiError {
133                status,
134                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/ReplaceView"
135                    .to_string(),
136                feature_group: FEATURE_GROUP_ID.to_string(),
137            })?
138            .into_inner())
139    }
140
141    /// Deletes the [`View`] identified by its id.
142    ///
143    /// # Arguments
144    /// * `id` - The id of the view to delete.
145    pub async fn delete(&self, id: i32) -> Result<DeleteViewResponse> {
146        let request = make_request_with_metadata(
147            DeleteViewRequest { id: Some(id) },
148            &self.teams_level_metadata_map,
149        );
150        Ok(self
151            .service_client
152            .lock()
153            .await
154            .delete_view(request)
155            .await
156            .map_err(|status| SdkApiError {
157                status,
158                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/DeleteView"
159                    .to_string(),
160                feature_group: FEATURE_GROUP_ID.to_string(),
161            })?
162            .into_inner())
163    }
164
165    /// Retrieves the [`View`] by id.
166    ///
167    /// # Arguments
168    /// * `id` - The id of the view to retrieve.
169    pub async fn get(&self, id: i32) -> Result<Option<View>> {
170        let request = make_request_with_metadata(
171            GetViewRequest { id: Some(id) },
172            &self.teams_level_metadata_map,
173        );
174
175        Ok(self
176            .service_client
177            .lock()
178            .await
179            .get_view(request)
180            .await
181            .map_err(|status| SdkApiError {
182                status,
183                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/GetView".to_string(),
184                feature_group: FEATURE_GROUP_ID.to_string(),
185            })?
186            .into_inner()
187            .view)
188    }
189
190    /// Retrieves a list of all [`View`]s.
191    ///     
192    /// # Returns
193    /// A list of all views.
194    pub async fn list(&self) -> Result<Vec<View>> {
195        let request =
196            make_request_with_metadata(ListViewsRequest {}, &self.teams_level_metadata_map);
197
198        Ok(self
199            .service_client
200            .lock()
201            .await
202            .list_views(request)
203            .await
204            .map_err(|status| SdkApiError {
205                status,
206                endpoint: "/com.coralogixapis.views.v1.services.ViewsService/ListViews".to_string(),
207                feature_group: FEATURE_GROUP_ID.to_string(),
208            })?
209            .into_inner()
210            .views)
211    }
212}