cat_gateway/settings/
cassandra_db.rs

1//! Command line and environment variable settings for the service
2
3use cardano_chain_follower::Network;
4use tracing::info;
5
6use super::str_env_var::StringEnvVar;
7use crate::db::{
8    self,
9    index::session::{CompressionChoice, TlsChoice},
10};
11
12/// Default Cassandra DB URL for the Persistent DB.
13pub(super) const PERSISTENT_URL_DEFAULT: &str = "127.0.0.1:9042";
14
15/// Default Cassandra DB URL for the Persistent DB.
16pub(super) const PERSISTENT_NAMESPACE_DEFAULT: &str = "persistent";
17
18/// Default Cassandra DB URL for the Persistent DB.
19pub(super) const VOLATILE_URL_DEFAULT: &str = "127.0.0.1:9042";
20
21/// Default Cassandra DB URL for the Persistent DB.
22pub(super) const VOLATILE_NAMESPACE_DEFAULT: &str = "volatile";
23
24/// Default maximum batch size.
25/// This comes from:
26/// <https://docs.aws.amazon.com/keyspaces/latest/devguide/functional-differences.html#functional-differences.batch>
27/// Scylla may support larger batches for better performance.
28/// Larger batches will incur more memory overhead to store the prepared batches.
29const MAX_BATCH_SIZE_DEFAULT: i64 = 30;
30
31/// Minimum possible batch size.
32pub(crate) const MIN_BATCH_SIZE: i64 = 1;
33
34/// Maximum possible batch size.
35const MAX_BATCH_SIZE: i64 = 256;
36
37/// Configuration for an individual cassandra cluster.
38#[derive(Clone)]
39pub(crate) struct EnvVars {
40    /// The Address/s of the DB.
41    pub(crate) url: StringEnvVar,
42
43    /// The `UserName` to use for the Cassandra DB.
44    pub(crate) username: Option<StringEnvVar>,
45
46    /// The Password to use for the Cassandra DB..
47    pub(crate) password: Option<StringEnvVar>,
48
49    /// Use TLS for the connection?
50    pub(crate) tls: TlsChoice,
51
52    /// Use TLS for the connection?
53    pub(crate) tls_cert: Option<StringEnvVar>,
54
55    /// Compression to use.
56    pub(crate) compression: CompressionChoice,
57
58    /// Maximum Configured Batch size.
59    pub(crate) max_batch_size: i64,
60
61    /// Config options for deployment i.e replication strategy
62    pub(crate) deployment: StringEnvVar,
63}
64
65impl EnvVars {
66    /// Create a config for a cassandra cluster, identified by a default namespace.
67    pub(super) fn new(
68        url: &str,
69        namespace: &str,
70    ) -> Self {
71        let name = namespace.to_uppercase();
72
73        let tls =
74            StringEnvVar::new_as_enum(&format!("CASSANDRA_{name}_TLS"), TlsChoice::Disabled, false);
75        let compression = StringEnvVar::new_as_enum(
76            &format!("CASSANDRA_{name}_COMPRESSION"),
77            CompressionChoice::Lz4,
78            false,
79        );
80
81        Self {
82            url: StringEnvVar::new(&format!("CASSANDRA_{name}_URL"), (url, true).into()),
83            username: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_USERNAME"), false),
84            password: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_PASSWORD"), true),
85            tls,
86            tls_cert: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_TLS_CERT"), false),
87            compression,
88            max_batch_size: StringEnvVar::new_as_int(
89                &format!("CASSANDRA_{name}_BATCH_SIZE"),
90                MAX_BATCH_SIZE_DEFAULT,
91                MIN_BATCH_SIZE,
92                MAX_BATCH_SIZE,
93            ),
94            deployment: StringEnvVar::new(
95                &format!("CASSANDRA_{name}_DEPLOYMENT"),
96                "{'class': 'NetworkTopologyStrategy','replication_factor': 1}".into(),
97            ),
98        }
99    }
100
101    /// Log the configuration of this Cassandra DB
102    pub(crate) fn log(
103        &self,
104        persistent: bool,
105        network: Network,
106    ) {
107        let db_type = if persistent { "Persistent" } else { "Volatile" };
108
109        let auth = match (&self.username, &self.password) {
110            (Some(u), Some(_)) => format!("Username: {} Password: REDACTED", u.as_str()),
111            _ => "No Authentication".to_string(),
112        };
113
114        let tls_cert = match &self.tls_cert {
115            None => "No TLS Certificate Defined".to_string(),
116            Some(cert) => cert.as_string(),
117        };
118
119        info!(
120            url = self.url.as_str(),
121            namespace = db::index::schema::namespace(persistent, network),
122            auth = auth,
123            tls = self.tls.to_string(),
124            cert = tls_cert,
125            compression = self.compression.to_string(),
126            "Cassandra {db_type} DB Configuration"
127        );
128    }
129}