use ave_bridge::{
AveExternalDBConfig, AveInternalDBConfig, HttpConfig, ProxyConfig,
SelfSignedCertConfig,
auth::{
ApiKeyConfig, AuthConfig, EndpointRateLimit, LockoutConfig,
RateLimitConfig, SessionConfig,
},
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use utoipa::ToSchema;
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct ConfigHttp {
pub node: AveConfigHttp,
pub keys_path: String,
pub logging: LoggingHttp,
pub sink: SinkConfigHttp,
pub auth: AuthConfigHttp,
pub http: HttpConfigHttp,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub enum MachineSpecHttp {
Profile(String),
Custom {
ram_mb: u64,
cpu_cores: usize,
},
}
impl From<ave_bridge::MachineSpec> for MachineSpecHttp {
fn from(value: ave_bridge::MachineSpec) -> Self {
match value {
ave_bridge::MachineSpec::Profile(machine_profile) => {
Self::Profile(machine_profile.to_string())
}
ave_bridge::MachineSpec::Custom { ram_mb, cpu_cores } => {
Self::Custom { ram_mb, cpu_cores }
}
}
}
}
impl From<ave_bridge::config::Config> for ConfigHttp {
fn from(value: ave_bridge::config::Config) -> Self {
Self {
node: AveConfigHttp::from(value.node),
keys_path: value.keys_path.to_string_lossy().to_string(),
logging: LoggingHttp::from(value.logging),
sink: SinkConfigHttp::from(value.sink),
auth: AuthConfigHttp::from(value.auth),
http: HttpConfigHttp::from(value.http),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct AuthConfigHttp {
pub enable: bool,
pub durability: bool,
pub database_path: String,
pub superadmin: String,
pub api_key: ApiKeyConfigHttp,
pub lockout: LockoutConfigHttp,
pub rate_limit: RateLimitConfigHttp,
pub session: SessionConfigHttp,
}
impl From<AuthConfig> for AuthConfigHttp {
fn from(value: AuthConfig) -> Self {
Self {
enable: value.enable,
database_path: value.database_path.to_string_lossy().to_string(),
superadmin: value.superadmin,
durability: value.durability,
api_key: ApiKeyConfigHttp::from(value.api_key),
lockout: LockoutConfigHttp::from(value.lockout),
rate_limit: RateLimitConfigHttp::from(value.rate_limit),
session: SessionConfigHttp::from(value.session),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct ApiKeyConfigHttp {
pub default_ttl_seconds: i64,
pub max_keys_per_user: u32,
pub prefix: String,
}
impl From<ApiKeyConfig> for ApiKeyConfigHttp {
fn from(value: ApiKeyConfig) -> Self {
Self {
default_ttl_seconds: value.default_ttl_seconds,
max_keys_per_user: value.max_keys_per_user,
prefix: value.prefix,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct LockoutConfigHttp {
pub max_attempts: u32,
pub duration_seconds: i64,
}
impl From<LockoutConfig> for LockoutConfigHttp {
fn from(value: LockoutConfig) -> Self {
Self {
max_attempts: value.max_attempts,
duration_seconds: value.duration_seconds,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct RateLimitConfigHttp {
pub enable: bool,
pub window_seconds: i64,
pub max_requests: u32,
pub limit_by_key: bool,
pub limit_by_ip: bool,
pub cleanup_interval_seconds: i64,
pub sensitive_endpoints: Vec<EndpointRateLimitHttp>,
}
impl From<RateLimitConfig> for RateLimitConfigHttp {
fn from(value: RateLimitConfig) -> Self {
Self {
enable: value.enable,
window_seconds: value.window_seconds,
max_requests: value.max_requests,
limit_by_key: value.limit_by_key,
limit_by_ip: value.limit_by_ip,
cleanup_interval_seconds: value.cleanup_interval_seconds,
sensitive_endpoints: value
.sensitive_endpoints
.into_iter()
.map(EndpointRateLimitHttp::from)
.collect(),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct EndpointRateLimitHttp {
pub endpoint: String,
pub max_requests: u32,
pub window_seconds: Option<i64>,
}
impl From<EndpointRateLimit> for EndpointRateLimitHttp {
fn from(value: EndpointRateLimit) -> Self {
Self {
endpoint: value.endpoint,
max_requests: value.max_requests,
window_seconds: value.window_seconds,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct SessionConfigHttp {
pub audit_enable: bool,
pub audit_retention_days: u32,
pub audit_max_entries: u32,
}
impl From<SessionConfig> for SessionConfigHttp {
fn from(value: SessionConfig) -> Self {
Self {
audit_enable: value.audit_enable,
audit_retention_days: value.audit_retention_days,
audit_max_entries: value.audit_max_entries,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct HttpConfigHttp {
pub http_address: String,
pub https_address: Option<String>,
pub https_cert_path: Option<String>,
pub https_private_key_path: Option<String>,
pub enable_doc: bool,
pub proxy: ProxyConfigHttp,
pub cors: CorsConfigHttp,
pub self_signed_cert: SelfSignedCertConfigHttp,
}
impl From<HttpConfig> for HttpConfigHttp {
fn from(value: HttpConfig) -> Self {
Self {
http_address: value.http_address,
https_address: value.https_address,
https_cert_path: value
.https_cert_path
.map(|x| x.to_string_lossy().to_string()),
https_private_key_path: value
.https_private_key_path
.map(|x| x.to_string_lossy().to_string()),
enable_doc: value.enable_doc,
proxy: ProxyConfigHttp::from(value.proxy),
cors: CorsConfigHttp::from(value.cors),
self_signed_cert: SelfSignedCertConfigHttp::from(
value.self_signed_cert,
),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct ProxyConfigHttp {
pub trusted_proxies: Vec<String>,
pub trust_x_forwarded_for: bool,
pub trust_x_real_ip: bool,
}
impl From<ProxyConfig> for ProxyConfigHttp {
fn from(value: ProxyConfig) -> Self {
Self {
trusted_proxies: value.trusted_proxies,
trust_x_forwarded_for: value.trust_x_forwarded_for,
trust_x_real_ip: value.trust_x_real_ip,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct SelfSignedCertConfigHttp {
pub enabled: bool,
pub common_name: String,
pub san: Vec<String>,
pub validity_days: u32,
pub renew_before_days: u32,
pub check_interval_secs: u64,
}
impl From<SelfSignedCertConfig> for SelfSignedCertConfigHttp {
fn from(value: SelfSignedCertConfig) -> Self {
Self {
enabled: value.enabled,
common_name: value.common_name,
san: value.san,
validity_days: value.validity_days,
renew_before_days: value.renew_before_days,
check_interval_secs: value.check_interval_secs,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct CorsConfigHttp {
pub enabled: bool,
pub allow_any_origin: bool,
pub allowed_origins: Vec<String>,
pub allow_credentials: bool,
}
impl From<ave_bridge::CorsConfig> for CorsConfigHttp {
fn from(value: ave_bridge::CorsConfig) -> Self {
Self {
enabled: value.enabled,
allow_any_origin: value.allow_any_origin,
allowed_origins: value.allowed_origins,
allow_credentials: value.allow_credentials,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct AveConfigHttp {
pub keypair_algorithm: String,
pub hash_algorithm: String,
pub internal_db: AveStoreConfigHttp,
pub external_db: AveStoreConfigHttp,
pub network: NetworkConfigHttp,
pub contracts_path: String,
pub always_accept: bool,
pub safe_mode: bool,
pub tracking_size: usize,
pub is_service: bool,
pub only_clear_events: bool,
pub sync: SyncConfigHttp,
pub spec: Option<MachineSpecHttp>,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct SyncConfigHttp {
pub ledger_batch_size: usize,
pub governance: GovernanceSyncConfigHttp,
pub tracker: TrackerSyncConfigHttp,
pub update: UpdateSyncConfigHttp,
pub reboot: RebootSyncConfigHttp,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct GovernanceSyncConfigHttp {
pub interval_secs: u64,
pub sample_size: usize,
pub response_timeout_secs: u64,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct TrackerSyncConfigHttp {
pub interval_secs: u64,
pub page_size: usize,
pub response_timeout_secs: u64,
pub update_batch_size: usize,
pub update_timeout_secs: u64,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct UpdateSyncConfigHttp {
pub round_retry_interval_secs: u64,
pub max_round_retries: usize,
pub witness_retry_count: usize,
pub witness_retry_interval_secs: u64,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct RebootSyncConfigHttp {
pub stability_check_interval_secs: u64,
pub stability_check_max_retries: u64,
pub diff_retry_schedule_secs: Vec<u64>,
pub timeout_retry_schedule_secs: Vec<u64>,
}
impl From<ave_bridge::AveConfig> for AveConfigHttp {
fn from(value: ave_bridge::AveConfig) -> Self {
Self {
keypair_algorithm: format!("{:?}", value.keypair_algorithm),
hash_algorithm: format!("{:?}", value.hash_algorithm),
internal_db: AveStoreConfigHttp::from(value.internal_db),
external_db: AveStoreConfigHttp::from(value.external_db),
network: NetworkConfigHttp::from(value.network),
contracts_path: value.contracts_path.to_string_lossy().to_string(),
always_accept: value.always_accept,
safe_mode: value.safe_mode,
tracking_size: value.tracking_size,
is_service: value.is_service,
only_clear_events: value.only_clear_events,
sync: SyncConfigHttp {
ledger_batch_size: value.sync.ledger_batch_size,
governance: GovernanceSyncConfigHttp {
interval_secs: value.sync.governance.interval_secs,
sample_size: value.sync.governance.sample_size,
response_timeout_secs: value
.sync
.governance
.response_timeout_secs,
},
tracker: TrackerSyncConfigHttp {
interval_secs: value.sync.tracker.interval_secs,
page_size: value.sync.tracker.page_size,
response_timeout_secs: value
.sync
.tracker
.response_timeout_secs,
update_batch_size: value.sync.tracker.update_batch_size,
update_timeout_secs: value.sync.tracker.update_timeout_secs,
},
update: UpdateSyncConfigHttp {
round_retry_interval_secs: value
.sync
.update
.round_retry_interval_secs,
max_round_retries: value.sync.update.max_round_retries,
witness_retry_count: value.sync.update.witness_retry_count,
witness_retry_interval_secs: value
.sync
.update
.witness_retry_interval_secs,
},
reboot: RebootSyncConfigHttp {
stability_check_interval_secs: value
.sync
.reboot
.stability_check_interval_secs,
stability_check_max_retries: value
.sync
.reboot
.stability_check_max_retries,
diff_retry_schedule_secs: value
.sync
.reboot
.diff_retry_schedule_secs,
timeout_retry_schedule_secs: value
.sync
.reboot
.timeout_retry_schedule_secs,
},
},
spec: value.spec.map(MachineSpecHttp::from),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct AveStoreConfigHttp {
pub db: String,
pub durability: bool,
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct AveActorsStoreConfigHttp {
pub ram_mb: Option<u64>,
pub cpu_cores: Option<usize>,
pub profile: Option<String>,
pub durability: bool,
}
impl From<AveInternalDBConfig> for AveStoreConfigHttp {
fn from(value: AveInternalDBConfig) -> Self {
Self {
db: value.db.to_string(),
durability: value.durability,
}
}
}
impl From<AveExternalDBConfig> for AveStoreConfigHttp {
fn from(value: AveExternalDBConfig) -> Self {
Self {
db: value.db.to_string(),
durability: value.durability,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct NetworkConfigHttp {
pub node_type: String,
pub listen_addresses: Vec<String>,
pub external_addresses: Vec<String>,
pub boot_nodes: Vec<RoutingNodeHttp>,
pub routing: RoutingConfigHttp,
pub control_list: ControlListConfigHttp,
pub memory_limits: String,
pub max_app_message_bytes: usize,
pub max_pending_inbound_bytes_per_peer: usize,
pub max_pending_outbound_bytes_per_peer: usize,
pub max_pending_inbound_bytes_total: usize,
pub max_pending_outbound_bytes_total: usize,
}
impl From<ave_bridge::NetworkConfig> for NetworkConfigHttp {
fn from(value: ave_bridge::NetworkConfig) -> Self {
Self {
node_type: format!("{:?}", value.node_type),
listen_addresses: value.listen_addresses,
external_addresses: value.external_addresses,
boot_nodes: value
.boot_nodes
.into_iter()
.map(RoutingNodeHttp::from)
.collect(),
routing: RoutingConfigHttp::from(value.routing),
control_list: ControlListConfigHttp::from(value.control_list),
memory_limits: value.memory_limits.to_string(),
max_app_message_bytes: value.max_app_message_bytes,
max_pending_outbound_bytes_per_peer: value
.max_pending_outbound_bytes_per_peer,
max_pending_inbound_bytes_per_peer: value
.max_pending_inbound_bytes_per_peer,
max_pending_outbound_bytes_total: value
.max_pending_outbound_bytes_total,
max_pending_inbound_bytes_total: value
.max_pending_inbound_bytes_total,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct RoutingConfigHttp {
pub dht_random_walk: bool,
pub discovery_only_if_under_num: u64,
pub allow_private_address_in_dht: bool,
pub allow_dns_address_in_dht: bool,
pub allow_loop_back_address_in_dht: bool,
pub kademlia_disjoint_query_paths: bool,
}
impl From<ave_bridge::RoutingConfig> for RoutingConfigHttp {
fn from(value: ave_bridge::RoutingConfig) -> Self {
Self {
dht_random_walk: value.get_dht_random_walk(),
discovery_only_if_under_num: value.get_discovery_limit(),
allow_private_address_in_dht: value
.get_allow_private_address_in_dht(),
allow_dns_address_in_dht: value.get_allow_dns_address_in_dht(),
allow_loop_back_address_in_dht: value
.get_allow_loop_back_address_in_dht(),
kademlia_disjoint_query_paths: value
.get_kademlia_disjoint_query_paths(),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct ControlListConfigHttp {
pub enable: bool,
pub allow_list: Vec<String>,
pub block_list: Vec<String>,
pub service_allow_list: Vec<String>,
pub service_block_list: Vec<String>,
pub interval_request_secs: u64,
pub request_timeout_secs: u64,
pub max_concurrent_requests: usize,
}
impl From<ave_bridge::ControlListConfig> for ControlListConfigHttp {
fn from(value: ave_bridge::ControlListConfig) -> Self {
Self {
enable: value.get_enable(),
allow_list: value.get_allow_list(),
block_list: value.get_block_list(),
service_allow_list: value.get_service_allow_list(),
service_block_list: value.get_service_block_list(),
interval_request_secs: value.get_interval_request().as_secs(),
request_timeout_secs: value.get_request_timeout().as_secs(),
max_concurrent_requests: value.get_max_concurrent_requests(),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct RoutingNodeHttp {
pub peer_id: String,
pub address: Vec<String>,
}
impl From<ave_bridge::RoutingNode> for RoutingNodeHttp {
fn from(value: ave_bridge::RoutingNode) -> Self {
Self {
peer_id: value.peer_id.to_string(),
address: value.address.iter().map(|a| a.to_string()).collect(),
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct LoggingHttp {
pub output: LoggingOutputHttp,
pub api_url: Option<String>,
pub file_path: String,
pub rotation: String,
pub max_size: usize,
pub max_files: usize,
pub level: String,
}
impl From<ave_bridge::LoggingConfig> for LoggingHttp {
fn from(value: ave_bridge::LoggingConfig) -> Self {
Self {
output: LoggingOutputHttp::from(value.output),
api_url: value.api_url,
file_path: value.file_path.to_string_lossy().to_string(),
rotation: format!("{:?}", value.rotation),
max_size: value.max_size,
max_files: value.max_files,
level: value.level,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct LoggingOutputHttp {
pub stdout: bool,
pub file: bool,
pub api: bool,
}
impl From<ave_bridge::LoggingOutput> for LoggingOutputHttp {
fn from(value: ave_bridge::LoggingOutput) -> Self {
Self {
stdout: value.stdout,
file: value.file,
api: value.api,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct SinkConfigHttp {
pub sinks: BTreeMap<String, Vec<SinkServerHttp>>,
pub auth: String,
pub username: String,
}
impl From<ave_bridge::SinkConfig> for SinkConfigHttp {
fn from(value: ave_bridge::SinkConfig) -> Self {
Self {
sinks: value
.sinks
.into_iter()
.map(|(k, v)| {
(k, v.into_iter().map(SinkServerHttp::from).collect())
})
.collect(),
auth: value.auth,
username: value.username,
}
}
}
#[derive(Debug, Serialize, Clone, ToSchema, Deserialize)]
pub struct SinkServerHttp {
pub server: String,
pub events: Vec<String>,
pub url: String,
pub auth: bool,
pub concurrency: usize,
pub queue_capacity: usize,
pub queue_policy: String,
pub routing_strategy: String,
pub connect_timeout_ms: u64,
pub request_timeout_ms: u64,
pub max_retries: usize,
}
impl From<ave_bridge::SinkServer> for SinkServerHttp {
fn from(value: ave_bridge::SinkServer) -> Self {
Self {
server: value.server,
events: value.events.into_iter().map(|e| e.to_string()).collect(),
url: value.url,
auth: value.auth,
concurrency: value.concurrency,
queue_capacity: value.queue_capacity,
queue_policy: match value.queue_policy {
ave_bridge::SinkQueuePolicy::DropOldest => {
"drop_oldest".to_owned()
}
ave_bridge::SinkQueuePolicy::DropNewest => {
"drop_newest".to_owned()
}
},
routing_strategy: match value.routing_strategy {
ave_bridge::SinkRoutingStrategy::OrderedBySubject => {
"ordered_by_subject".to_owned()
}
ave_bridge::SinkRoutingStrategy::UnorderedRoundRobin => {
"unordered_round_robin".to_owned()
}
},
connect_timeout_ms: value.connect_timeout_ms,
request_timeout_ms: value.request_timeout_ms,
max_retries: value.max_retries,
}
}
}