use crate::source_error;
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use thiserror::Error as ThisError;
use utoipa::ToSchema;
#[derive(Serialize, Deserialize, Debug, ToSchema)]
pub struct RegisterTelemetryEventRequest {
pub account_id: String,
pub license_key: String,
pub event: TelemetryEvent,
}
#[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
pub enum TelemetryEvent {
PipelineProvisioned { id_hash: String },
PipelineShutdownFinished { id_hash: String },
PipelineStatistics {
id_hash: String,
statistics: serde_json::Value,
},
}
#[derive(ThisError, Clone, Debug, PartialEq)]
pub enum RegisterTelemetryEventError {
#[error("failed to serialize request to JSON due to {error}")]
SerializeRequestToJsonFailed { error: String },
#[error("failed to send request due to {error}")]
SendRequestFailed { error: String },
#[error("HTTP status code ({0}) received back with the response is unexpected")]
UnexpectedResponseStatusCode(StatusCode),
}
pub async fn register_telemetry_event(
client: &reqwest::Client,
cloud_api_endpoint: &str,
account_id: &str,
license_key: &str,
event: TelemetryEvent,
) -> Result<(), RegisterTelemetryEventError> {
let endpoint = format!("{cloud_api_endpoint}/telemetry/event");
match serde_json::to_value(RegisterTelemetryEventRequest {
account_id: account_id.to_string(),
license_key: license_key.to_string(),
event,
}) {
Ok(request) => {
let result = client.post(&endpoint).json(&request).send().await;
match result {
Ok(response) => {
let status_code = response.status();
if status_code == StatusCode::OK {
Ok(())
} else {
Err(RegisterTelemetryEventError::UnexpectedResponseStatusCode(
status_code,
))
}
}
Err(e) => {
let source_err = source_error(&e);
let error = format!("{e}, source: {source_err}");
Err(RegisterTelemetryEventError::SendRequestFailed { error })
}
}
}
Err(e) => Err(RegisterTelemetryEventError::SerializeRequestToJsonFailed {
error: e.to_string(),
}),
}
}