From 1177b38aaae8501ab64bdcb0e0b31f0d0474bc3b Mon Sep 17 00:00:00 2001 From: Aakash Hemadri Date: Wed, 14 Apr 2021 18:10:57 +0530 Subject: [PATCH] refactor: Move create_bucket to api/bucket Signed-off-by: Aakash Hemadri --- influxdb2_client/src/api/buckets.rs | 67 +++++++++++++++++++++++++ influxdb2_client/src/api/mod.rs | 1 + influxdb2_client/src/lib.rs | 72 ++------------------------- influxdb2_client/src/models/bucket.rs | 31 ++++++++++++ influxdb2_client/src/models/mod.rs | 2 +- 5 files changed, 104 insertions(+), 69 deletions(-) create mode 100644 influxdb2_client/src/api/buckets.rs diff --git a/influxdb2_client/src/api/buckets.rs b/influxdb2_client/src/api/buckets.rs new file mode 100644 index 0000000000..cb3f156c0d --- /dev/null +++ b/influxdb2_client/src/api/buckets.rs @@ -0,0 +1,67 @@ +//! Buckets API + +use crate::models::PostBucketRequest; +use crate::{Client, Http, RequestError, ReqwestProcessing, Serializing}; +use reqwest::Method; +use snafu::ResultExt; + +impl Client { + /// Create a new bucket in the organization specified by the 16-digit + /// hexadecimal `org_id` and with the bucket name `bucket`. + pub async fn create_bucket( + &self, + post_bucket_request: Option, + ) -> Result<(), RequestError> { + let create_bucket_url = format!("{}/api/v2/buckets", self.url); + + let response = self + .request(Method::POST, &create_bucket_url) + .body( + serde_json::to_string(&post_bucket_request.unwrap_or_default()) + .context(Serializing)?, + ) + .send() + .await + .context(ReqwestProcessing)?; + + if !response.status().is_success() { + let status = response.status(); + let text = response.text().await.context(ReqwestProcessing)?; + Http { status, text }.fail()?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use mockito::mock; + + #[tokio::test] + async fn create_bucket() { + let org_id = "0000111100001111".to_string(); + let bucket = "some-bucket".to_string(); + let token = "some-token"; + + let mock_server = mock("POST", "/api/v2/buckets") + .match_header("Authorization", format!("Token {}", token).as_str()) + .match_body( + format!( + r#"{{"orgID":"{}","name":"{}","retentionRules":[]}}"#, + org_id, bucket + ) + .as_str(), + ) + .create(); + + let client = Client::new(&mockito::server_url(), token); + + let _result = client + .create_bucket(Some(PostBucketRequest::new(org_id, bucket))) + .await; + + mock_server.assert(); + } +} diff --git a/influxdb2_client/src/api/mod.rs b/influxdb2_client/src/api/mod.rs index cfb09178c9..83eeda120e 100644 --- a/influxdb2_client/src/api/mod.rs +++ b/influxdb2_client/src/api/mod.rs @@ -1,4 +1,5 @@ //! InfluxDB v2.0 Client API +pub mod buckets; pub mod query; pub mod ready; pub mod setup; diff --git a/influxdb2_client/src/lib.rs b/influxdb2_client/src/lib.rs index e5a0f9d9ee..b94b8701f2 100644 --- a/influxdb2_client/src/lib.rs +++ b/influxdb2_client/src/lib.rs @@ -32,7 +32,7 @@ //! ``` //! async fn example() -> Result<(), Box> { //! use influxdb2_client::Client; -//! use influxdb2_client::models::DataPoint; +//! use influxdb2_client::models::{DataPoint, PostBucketRequest}; //! use futures::stream; //! //! let org = "myorg"; @@ -41,7 +41,7 @@ //! //! let client = Client::new("http://localhost:8888", "some-token"); //! -//! client.create_bucket(org_id, bucket).await?; +//! client.create_bucket(Some(PostBucketRequest::new(org_id.to_string(), bucket.to_string()))).await?; //! //! let points = vec![ //! DataPoint::builder("cpu") @@ -60,13 +60,12 @@ //! } //! ``` +use crate::models::WriteDataPoint; use bytes::BufMut; use futures::{Stream, StreamExt}; use reqwest::{Body, Method}; -use serde::Serialize; use snafu::{ResultExt, Snafu}; use std::io::{self, Write}; -use crate::models::WriteDataPoint; /// Errors that occur while making requests to the Influx server. #[derive(Debug, Snafu)] @@ -190,53 +189,14 @@ impl Client { Ok(self.write_line_protocol(org, bucket, body).await?) } - - /// Create a new bucket in the organization specified by the 16-digit - /// hexadecimal `org_id` and with the bucket name `bucket`. - pub async fn create_bucket(&self, org_id: &str, bucket: &str) -> Result<(), RequestError> { - let create_bucket_url = format!("{}/api/v2/buckets", self.url); - - #[derive(Serialize, Debug, Default)] - struct CreateBucketInfo { - #[serde(rename = "orgID")] - org_id: String, - name: String, - #[serde(rename = "retentionRules")] - // The type of `retentionRules` isn't `String`; this is included and always set to - // an empty vector to be compatible with the Influx 2.0 API where `retentionRules` is - // a required parameter. InfluxDB IOx ignores this parameter. - retention_rules: Vec, - } - - let body = CreateBucketInfo { - org_id: org_id.into(), - name: bucket.into(), - ..Default::default() - }; - - let response = self - .request(Method::POST, &create_bucket_url) - .body(serde_json::to_string(&body).context(Serializing)?) - .send() - .await - .context(ReqwestProcessing)?; - - if !response.status().is_success() { - let status = response.status(); - let text = response.text().await.context(ReqwestProcessing)?; - Http { status, text }.fail()?; - } - - Ok(()) - } } #[cfg(test)] mod tests { use super::*; + use crate::models::DataPoint; use futures::stream; use mockito::mock; - use crate::models::DataPoint; #[tokio::test] async fn writing_points() { @@ -282,30 +242,6 @@ cpu,host=server01,region=us-west usage=0.87 mock_server.assert(); } - - #[tokio::test] - async fn create_bucket() { - let org_id = "0000111100001111"; - let bucket = "some-bucket"; - let token = "some-token"; - - let mock_server = mock("POST", "/api/v2/buckets") - .match_header("Authorization", format!("Token {}", token).as_str()) - .match_body( - format!( - r#"{{"orgID":"{}","name":"{}","retentionRules":[]}}"#, - org_id, bucket - ) - .as_str(), - ) - .create(); - - let client = Client::new(&mockito::server_url(), token); - - let _result = client.create_bucket(org_id, bucket).await; - - mock_server.assert(); - } } pub mod common; diff --git a/influxdb2_client/src/models/bucket.rs b/influxdb2_client/src/models/bucket.rs index 9b24c987f6..06b1561195 100644 --- a/influxdb2_client/src/models/bucket.rs +++ b/influxdb2_client/src/models/bucket.rs @@ -109,3 +109,34 @@ impl Buckets { Self::default() } } + +/// PostBucketRequest +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct PostBucketRequest { + /// Organization ID + #[serde(rename = "orgID")] + pub org_id: String, + /// Bucket name + pub name: String, + /// Bucket Description + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + /// RP + #[serde(skip_serializing_if = "Option::is_none")] + pub rp: Option, + /// Rules to expire or retain data. No rules means data never expires. + #[serde(default)] + pub retention_rules: Vec, +} + +impl PostBucketRequest { + /// Returns instance of PostBucketRequest + pub fn new(org_id: String, name: String) -> Self { + Self { + org_id, + name, + ..Default::default() + } + } +} diff --git a/influxdb2_client/src/models/mod.rs b/influxdb2_client/src/models/mod.rs index f1715cb600..b6012191e3 100644 --- a/influxdb2_client/src/models/mod.rs +++ b/influxdb2_client/src/models/mod.rs @@ -9,7 +9,7 @@ pub use self::user::{User, UserLinks, Users, UsersLinks}; pub mod organization; pub use self::organization::{Organization, OrganizationLinks, Organizations}; pub mod bucket; -pub use self::bucket::{Bucket, BucketLinks, Buckets}; +pub use self::bucket::{Bucket, BucketLinks, Buckets, PostBucketRequest}; pub mod onboarding; pub use self::onboarding::{IsOnboarding, OnboardingRequest, OnboardingResponse}; pub mod links;