scylla/client/
self_identity.rs

1use std::borrow::Cow;
2
3/// Driver and application self-identifying information,
4/// to be sent in STARTUP message.
5#[derive(Debug, Clone, Default)]
6pub struct SelfIdentity<'id> {
7    // Custom driver identity can be set if a custom driver build is running,
8    // or an entirely different driver is operating on top of Rust driver
9    // (e.g. cpp-rust-driver).
10    custom_driver_name: Option<Cow<'id, str>>,
11    custom_driver_version: Option<Cow<'id, str>>,
12
13    // ### Q: Where do APPLICATION_NAME, APPLICATION_VERSION and CLIENT_ID come from?
14    // - there are no columns in system.clients dedicated to those attributes,
15    // - APPLICATION_NAME / APPLICATION_VERSION are not present in Scylla's source code at all,
16    // - only 2 results in Cassandra source is some example in docs:
17    //   https://github.com/apache/cassandra/blob/d3cbf9c1f72057d2a5da9df8ed567d20cd272931/doc/modules/cassandra/pages/managing/operating/virtualtables.adoc?plain=1#L218.
18    //   APPLICATION_NAME and APPLICATION_VERSION appears in client_options which
19    //   is an arbitrary dict where client can send any keys.
20    // - driver variables are mentioned in protocol v5
21    //   (https://github.com/apache/cassandra/blob/d3cbf9c1f72057d2a5da9df8ed567d20cd272931/doc/native_protocol_v5.spec#L480),
22    //   application variables are not.
23    //
24    // ### A:
25    // The following options are not exposed anywhere in Scylla tables.
26    // They come directly from CPP driver, and they are supported in Cassandra
27    //
28    // See https://github.com/scylladb/cpp-driver/blob/fa0f27069a625057984d1fa58f434ea99b86c83f/include/cassandra.h#L2916.
29    // As we want to support as big subset of its API as possible in cpp-rust-driver, I decided to expose API for setting
30    // those particular key-value pairs, similarly to what cpp-driver does, and not an API to set arbitrary key-value pairs.
31    //
32    // Allowing users to set arbitrary options could break the driver by overwriting options that bear special meaning,
33    // e.g. the shard-aware port. Therefore, I'm against such liberal API. OTOH, we need to expose APPLICATION_NAME,
34    // APPLICATION_VERSION and CLIENT_ID for cpp-rust-driver.
35
36    // Application identity can be set to distinguish different applications
37    // connected to the same cluster.
38    application_name: Option<Cow<'id, str>>,
39    application_version: Option<Cow<'id, str>>,
40
41    // A (unique) client ID can be set to distinguish different instances
42    // of the same application connected to the same cluster.
43    client_id: Option<Cow<'id, str>>,
44}
45
46impl<'id> SelfIdentity<'id> {
47    pub fn new() -> Self {
48        Self::default()
49    }
50
51    /// Advertises a custom driver name, which can be used if a custom driver build is running,
52    /// or an entirely different driver is operating on top of Rust driver
53    /// (e.g. cpp-rust-driver).
54    pub fn set_custom_driver_name(&mut self, custom_driver_name: impl Into<Cow<'id, str>>) {
55        self.custom_driver_name = Some(custom_driver_name.into());
56    }
57
58    /// Advertises a custom driver name. See [Self::set_custom_driver_name] for use cases.
59    pub fn with_custom_driver_name(mut self, custom_driver_name: impl Into<Cow<'id, str>>) -> Self {
60        self.custom_driver_name = Some(custom_driver_name.into());
61        self
62    }
63
64    /// Custom driver name to be advertised. See [Self::set_custom_driver_name] for use cases.
65    pub fn get_custom_driver_name(&self) -> Option<&str> {
66        self.custom_driver_name.as_deref()
67    }
68
69    /// Advertises a custom driver version. See [Self::set_custom_driver_name] for use cases.
70    pub fn set_custom_driver_version(&mut self, custom_driver_version: impl Into<Cow<'id, str>>) {
71        self.custom_driver_version = Some(custom_driver_version.into());
72    }
73
74    /// Advertises a custom driver version. See [Self::set_custom_driver_name] for use cases.
75    pub fn with_custom_driver_version(
76        mut self,
77        custom_driver_version: impl Into<Cow<'id, str>>,
78    ) -> Self {
79        self.custom_driver_version = Some(custom_driver_version.into());
80        self
81    }
82
83    /// Custom driver version to be advertised. See [Self::set_custom_driver_version] for use cases.
84    pub fn get_custom_driver_version(&self) -> Option<&str> {
85        self.custom_driver_version.as_deref()
86    }
87
88    /// Advertises an application name, which can be used to distinguish different applications
89    /// connected to the same cluster.
90    pub fn set_application_name(&mut self, application_name: impl Into<Cow<'id, str>>) {
91        self.application_name = Some(application_name.into());
92    }
93
94    /// Advertises an application name. See [Self::set_application_name] for use cases.
95    pub fn with_application_name(mut self, application_name: impl Into<Cow<'id, str>>) -> Self {
96        self.application_name = Some(application_name.into());
97        self
98    }
99
100    /// Application name to be advertised. See [Self::set_application_name] for use cases.
101    pub fn get_application_name(&self) -> Option<&str> {
102        self.application_name.as_deref()
103    }
104
105    /// Advertises an application version. See [Self::set_application_name] for use cases.
106    pub fn set_application_version(&mut self, application_version: impl Into<Cow<'id, str>>) {
107        self.application_version = Some(application_version.into());
108    }
109
110    /// Advertises an application version. See [Self::set_application_name] for use cases.
111    pub fn with_application_version(
112        mut self,
113        application_version: impl Into<Cow<'id, str>>,
114    ) -> Self {
115        self.application_version = Some(application_version.into());
116        self
117    }
118
119    /// Application version to be advertised. See [Self::set_application_version] for use cases.
120    pub fn get_application_version(&self) -> Option<&str> {
121        self.application_version.as_deref()
122    }
123
124    /// Advertises a client ID, which can be set to distinguish different instances
125    /// of the same application connected to the same cluster.
126    pub fn set_client_id(&mut self, client_id: impl Into<Cow<'id, str>>) {
127        self.client_id = Some(client_id.into());
128    }
129
130    /// Advertises a client ID. See [Self::set_client_id] for use cases.
131    pub fn with_client_id(mut self, client_id: impl Into<Cow<'id, str>>) -> Self {
132        self.client_id = Some(client_id.into());
133        self
134    }
135
136    /// Client ID to be advertised. See [Self::set_client_id] for use cases.
137    pub fn get_client_id(&self) -> Option<&str> {
138        self.client_id.as_deref()
139    }
140}