mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 03:46:37 +00:00
fix
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
use crate::config::kafka::KafkaConfig;
|
||||
use crate::config::mqtt::MqttConfig;
|
||||
use crate::config::webhook::WebhookConfig;
|
||||
use crate::config::{default_queue_dir, default_queue_limit};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Add a common field for the adapter configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AdapterCommon {
|
||||
/// Adapter identifier for unique identification
|
||||
pub identifier: String,
|
||||
/// Adapter description information
|
||||
pub comment: String,
|
||||
/// Whether to enable this adapter
|
||||
#[serde(default)]
|
||||
pub enable: bool,
|
||||
#[serde(default = "default_queue_dir")]
|
||||
pub queue_dir: String,
|
||||
#[serde(default = "default_queue_limit")]
|
||||
pub queue_limit: u64,
|
||||
}
|
||||
|
||||
impl Default for AdapterCommon {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
identifier: String::new(),
|
||||
comment: String::new(),
|
||||
enable: false,
|
||||
queue_dir: default_queue_dir(),
|
||||
queue_limit: default_queue_limit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for the adapter.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum AdapterConfig {
|
||||
Webhook(WebhookConfig),
|
||||
Kafka(KafkaConfig),
|
||||
Mqtt(MqttConfig),
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use crate::config::adapter::AdapterCommon;
|
||||
use crate::config::{default_queue_dir, default_queue_limit};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Configuration for the Kafka adapter.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct KafkaConfig {
|
||||
#[serde(flatten)]
|
||||
pub common: AdapterCommon,
|
||||
pub brokers: String,
|
||||
pub topic: String,
|
||||
pub max_retries: u32,
|
||||
pub timeout: u64,
|
||||
}
|
||||
|
||||
impl Default for KafkaConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
common: AdapterCommon::default(),
|
||||
brokers: String::new(),
|
||||
topic: String::new(),
|
||||
max_retries: 3,
|
||||
timeout: 5000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KafkaConfig {
|
||||
/// Create a new Kafka configuration
|
||||
pub fn new(identifier: impl Into<String>, brokers: impl Into<String>, topic: impl Into<String>) -> Self {
|
||||
Self {
|
||||
common: AdapterCommon {
|
||||
identifier: identifier.into(),
|
||||
comment: String::new(),
|
||||
enable: true,
|
||||
queue_dir: default_queue_dir(),
|
||||
queue_limit: default_queue_limit(),
|
||||
},
|
||||
brokers: brokers.into(),
|
||||
topic: topic.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
use std::env;
|
||||
|
||||
pub mod adapter;
|
||||
pub mod kafka;
|
||||
pub mod mqtt;
|
||||
pub mod notifier;
|
||||
pub mod webhook;
|
||||
|
||||
/// The default configuration file name
|
||||
const DEFAULT_CONFIG_FILE: &str = "event";
|
||||
|
||||
/// The prefix for the configuration file
|
||||
pub const STORE_PREFIX: &str = "rustfs";
|
||||
|
||||
/// The default retry interval for the webhook adapter
|
||||
pub const DEFAULT_RETRY_INTERVAL: u64 = 3;
|
||||
|
||||
/// The default maximum retry count for the webhook adapter
|
||||
pub const DEFAULT_MAX_RETRIES: u32 = 3;
|
||||
|
||||
/// The default notification queue limit
|
||||
pub const DEFAULT_NOTIFY_QUEUE_LIMIT: u64 = 10000;
|
||||
|
||||
/// Provide temporary directories as default storage paths
|
||||
pub(crate) fn default_queue_dir() -> String {
|
||||
env::var("EVENT_QUEUE_DIR").unwrap_or_else(|e| {
|
||||
tracing::info!("Failed to get `EVENT_QUEUE_DIR` failed err: {}", e.to_string());
|
||||
env::temp_dir().join(DEFAULT_CONFIG_FILE).to_string_lossy().to_string()
|
||||
})
|
||||
}
|
||||
|
||||
/// Provides the recommended default channel capacity for high concurrency systems
|
||||
pub(crate) fn default_queue_limit() -> u64 {
|
||||
env::var("EVENT_CHANNEL_CAPACITY")
|
||||
.unwrap_or_else(|_| DEFAULT_NOTIFY_QUEUE_LIMIT.to_string())
|
||||
.parse()
|
||||
.unwrap_or(DEFAULT_NOTIFY_QUEUE_LIMIT) // Default to 10000 if parsing fails
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
use crate::config::adapter::AdapterCommon;
|
||||
use crate::config::{default_queue_dir, default_queue_limit};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Configuration for the MQTT adapter.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MqttConfig {
|
||||
#[serde(flatten)]
|
||||
pub common: AdapterCommon,
|
||||
pub broker: String,
|
||||
pub port: u16,
|
||||
pub client_id: String,
|
||||
pub topic: String,
|
||||
pub max_retries: u32,
|
||||
}
|
||||
|
||||
impl Default for MqttConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
common: AdapterCommon::default(),
|
||||
broker: String::new(),
|
||||
port: 1883,
|
||||
client_id: String::new(),
|
||||
topic: String::new(),
|
||||
max_retries: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MqttConfig {
|
||||
/// Create a new MQTT configuration
|
||||
pub fn new(identifier: impl Into<String>, broker: impl Into<String>, topic: impl Into<String>) -> Self {
|
||||
Self {
|
||||
common: AdapterCommon {
|
||||
identifier: identifier.into(),
|
||||
comment: String::new(),
|
||||
enable: true,
|
||||
queue_dir: default_queue_dir(),
|
||||
queue_limit: default_queue_limit(),
|
||||
},
|
||||
broker: broker.into(),
|
||||
topic: topic.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
use crate::config::{adapter::AdapterConfig, kafka::KafkaConfig, mqtt::MqttConfig, webhook::WebhookConfig};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Event Notifier Configuration
|
||||
/// This struct contains the configuration for the event notifier system,
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct EventNotifierConfig {
|
||||
/// A collection of webhook configurations, with the key being a unique identifier
|
||||
#[serde(default)]
|
||||
pub webhook: HashMap<String, WebhookConfig>,
|
||||
/// A collection of Kafka configurations, with the key being a unique identifier
|
||||
#[serde(default)]
|
||||
pub kafka: HashMap<String, KafkaConfig>,
|
||||
///MQTT configuration collection, with the key being a unique identifier
|
||||
#[serde(default)]
|
||||
pub mqtt: HashMap<String, MqttConfig>,
|
||||
}
|
||||
|
||||
impl EventNotifierConfig {
|
||||
/// Create a new default configuration
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Load the configuration from the file
|
||||
pub fn event_load_config(_config_dir: Option<String>) -> EventNotifierConfig {
|
||||
// The existing implementation remains the same, but returns EventNotifierConfig
|
||||
// ...
|
||||
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Deserialization configuration
|
||||
pub fn unmarshal(data: &[u8]) -> common::error::Result<EventNotifierConfig> {
|
||||
let m: EventNotifierConfig = serde_json::from_slice(data)?;
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
/// Serialization configuration
|
||||
pub fn marshal(&self) -> common::error::Result<Vec<u8>> {
|
||||
let data = serde_json::to_vec(&self)?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// Convert this configuration to a list of adapter configurations
|
||||
pub fn to_adapter_configs(&self) -> Vec<AdapterConfig> {
|
||||
let mut adapters = Vec::new();
|
||||
|
||||
// Add all enabled webhook configurations
|
||||
for webhook in self.webhook.values() {
|
||||
if webhook.common.enable {
|
||||
adapters.push(AdapterConfig::Webhook(webhook.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all enabled Kafka configurations
|
||||
for kafka in self.kafka.values() {
|
||||
if kafka.common.enable {
|
||||
adapters.push(AdapterConfig::Kafka(kafka.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all enabled MQTT configurations
|
||||
for mqtt in self.mqtt.values() {
|
||||
if mqtt.common.enable {
|
||||
adapters.push(AdapterConfig::Mqtt(mqtt.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
adapters
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
use crate::config::adapter::AdapterCommon;
|
||||
use crate::config::{default_queue_dir, default_queue_limit};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use tracing::info;
|
||||
|
||||
/// Configuration for the webhook adapter.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct WebhookConfig {
|
||||
#[serde(flatten)]
|
||||
pub common: AdapterCommon,
|
||||
pub endpoint: String,
|
||||
pub auth_token: Option<String>,
|
||||
pub custom_headers: Option<HashMap<String, String>>,
|
||||
pub max_retries: u32,
|
||||
pub retry_interval: Option<u64>,
|
||||
pub timeout: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub client_cert: Option<String>,
|
||||
#[serde(default)]
|
||||
pub client_key: Option<String>,
|
||||
}
|
||||
|
||||
impl WebhookConfig {
|
||||
/// validate the configuration for the webhook adapter
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - `Result<(), String>`: Ok if the configuration is valid, Err with a message if invalid.
|
||||
///
|
||||
/// # Errors
|
||||
/// - Returns an error if the configuration is invalid, such as empty endpoint, unreasonable timeout, or mismatched certificate and key.
|
||||
pub fn validate(&self) -> Result<(), String> {
|
||||
// If not enabled, the other fields are not validated
|
||||
if !self.common.enable {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// verify that endpoint cannot be empty
|
||||
if self.endpoint.trim().is_empty() {
|
||||
return Err("Webhook endpoint cannot be empty".to_string());
|
||||
}
|
||||
|
||||
// verification timeout must be reasonable
|
||||
if self.timeout.is_some() {
|
||||
match self.timeout {
|
||||
Some(timeout) if timeout > 0 => {
|
||||
info!("Webhook timeout is set to {}", timeout);
|
||||
}
|
||||
_ => return Err("Webhook timeout must be greater than 0".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the maximum number of retry is reasonable
|
||||
if self.max_retries > 10 {
|
||||
return Err("Maximum retry count cannot exceed 10".to_string());
|
||||
}
|
||||
|
||||
// Verify the queue directory path
|
||||
if !self.common.queue_dir.is_empty() && !Path::new(&self.common.queue_dir).is_absolute() {
|
||||
return Err("Queue directory path should be absolute".to_string());
|
||||
}
|
||||
|
||||
// The authentication certificate and key must appear in pairs
|
||||
if (self.client_cert.is_some() && self.client_key.is_none()) || (self.client_cert.is_none() && self.client_key.is_some())
|
||||
{
|
||||
return Err("Certificate and key must be specified as a pair".to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a new webhook configuration
|
||||
pub fn new(identifier: impl Into<String>, endpoint: impl Into<String>) -> Self {
|
||||
Self {
|
||||
common: AdapterCommon {
|
||||
identifier: identifier.into(),
|
||||
comment: String::new(),
|
||||
enable: true,
|
||||
queue_dir: default_queue_dir(),
|
||||
queue_limit: default_queue_limit(),
|
||||
},
|
||||
endpoint: endpoint.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user