cat_gateway/settings/
cassandra_db.rs

1//! Command line and environment variable settings for the service
2
3use cardano_blockchain_types::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(url: &str, namespace: &str) -> Self {
68        let name = namespace.to_uppercase();
69
70        let tls =
71            StringEnvVar::new_as_enum(&format!("CASSANDRA_{name}_TLS"), TlsChoice::Disabled, false);
72        let compression = StringEnvVar::new_as_enum(
73            &format!("CASSANDRA_{name}_COMPRESSION"),
74            CompressionChoice::Lz4,
75            false,
76        );
77
78        Self {
79            url: StringEnvVar::new(&format!("CASSANDRA_{name}_URL"), (url, true).into()),
80            username: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_USERNAME"), false),
81            password: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_PASSWORD"), true),
82            tls,
83            tls_cert: StringEnvVar::new_optional(&format!("CASSANDRA_{name}_TLS_CERT"), false),
84            compression,
85            max_batch_size: StringEnvVar::new_as_int(
86                &format!("CASSANDRA_{name}_BATCH_SIZE"),
87                MAX_BATCH_SIZE_DEFAULT,
88                MIN_BATCH_SIZE,
89                MAX_BATCH_SIZE,
90            ),
91            deployment: StringEnvVar::new(
92                &format!("CASSANDRA_{name}_DEPLOYMENT"),
93                "{'class': 'NetworkTopologyStrategy','replication_factor': 1}".into(),
94            ),
95        }
96    }
97
98    /// Log the configuration of this Cassandra DB
99    pub(crate) fn log(&self, persistent: bool, network: Network) {
100        let db_type = if persistent { "Persistent" } else { "Volatile" };
101
102        let auth = match (&self.username, &self.password) {
103            (Some(u), Some(_)) => format!("Username: {} Password: REDACTED", u.as_str()),
104            _ => "No Authentication".to_string(),
105        };
106
107        let tls_cert = match &self.tls_cert {
108            None => "No TLS Certificate Defined".to_string(),
109            Some(cert) => cert.as_string(),
110        };
111
112        info!(
113            url = self.url.as_str(),
114            namespace = db::index::schema::namespace(persistent, network),
115            auth = auth,
116            tls = self.tls.to_string(),
117            cert = tls_cert,
118            compression = self.compression.to_string(),
119            "Cassandra {db_type} DB Configuration"
120        );
121    }
122}