Skip to main content

fluvio_sc_schema/
remote_file.rs

1#[cfg(feature = "json")]
2use std::ops::Deref;
3
4use anyhow::Result;
5
6#[cfg(feature = "use_serde")]
7use serde::{Deserialize, Serialize, de::DeserializeOwned};
8
9use fluvio_controlplane_metadata::{mirror::Home, topic::TopicSpec};
10use fluvio_stream_model::k8_types::{K8Obj, Spec, ObjectMeta};
11
12#[derive(Debug, Default)]
13#[cfg_attr(
14    feature = "use_serde",
15    derive(Deserialize, Serialize),
16    serde(rename_all = "camelCase")
17)]
18pub struct RemoteMetadata {
19    // TODO: remove it, we should get the topics from the upstreams/core
20    #[cfg_attr(feature = "use_serde", serde(default))]
21    pub topics: Vec<K8Obj<TopicSpec>>,
22    #[cfg_attr(feature = "use_serde", serde(default))]
23    pub home: Home,
24}
25
26/// Configuration used to inihilize a Cluster locally. This data is copied to
27/// the K8 cluster metadata
28#[derive(Debug, Default)]
29#[cfg_attr(
30    feature = "use_serde",
31    derive(Deserialize, Serialize),
32    serde(rename_all = "camelCase")
33)]
34pub struct RemoteMetadataExport {
35    // TODO: remove it, we should get the topics from the upstreams/core
36    #[cfg_attr(feature = "use_serde", serde(default))]
37    pub topics: Vec<K8ObjExport<TopicSpec>>,
38    #[cfg_attr(feature = "use_serde", serde(default))]
39    pub home: Home,
40}
41
42impl RemoteMetadataExport {
43    pub fn new(home: Home) -> Self {
44        Self {
45            topics: vec![],
46            home,
47        }
48    }
49}
50
51impl RemoteMetadata {
52    pub fn validate(&self) -> Result<()> {
53        Ok(())
54    }
55}
56
57/// Represents a ClusterConfig that is read from a file. Usually a JSON file.
58#[cfg(feature = "json")]
59#[derive(Debug, Default)]
60pub struct RemoteMetadataFile(RemoteMetadata);
61
62#[cfg(feature = "json")]
63impl RemoteMetadataFile {
64    pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
65        let path = path.as_ref();
66        let contents = std::fs::read_to_string(path)?;
67
68        Self::from_json(&contents)
69    }
70
71    fn from_json(json: &str) -> Result<Self> {
72        let config: RemoteMetadata = serde_json::from_str(json)?;
73
74        config.validate()?;
75
76        Ok(Self(config))
77    }
78}
79
80#[cfg(feature = "json")]
81impl Deref for RemoteMetadataFile {
82    type Target = RemoteMetadata;
83
84    fn deref(&self) -> &Self::Target {
85        &self.0
86    }
87}
88
89#[cfg(feature = "json")]
90impl From<RemoteMetadataFile> for RemoteMetadata {
91    fn from(file: RemoteMetadataFile) -> Self {
92        file.0
93    }
94}
95
96#[derive(Debug)]
97#[cfg_attr(
98    feature = "use_serde",
99    derive(Deserialize, Serialize),
100    serde(rename_all = "camelCase"),
101    serde(bound(serialize = "S: Serialize")),
102    serde(bound(deserialize = "S: DeserializeOwned"))
103)]
104pub struct K8ObjExport<S>
105where
106    S: Spec,
107{
108    #[cfg_attr(feature = "use_serde", serde(default = "S::api_version"))]
109    pub api_version: String,
110    #[cfg_attr(feature = "use_serde", serde(default = "S::kind"))]
111    pub kind: String,
112    #[cfg_attr(feature = "use_serde", serde(default))]
113    pub metadata: ObjectMeta,
114    #[cfg_attr(feature = "use_serde", serde(default))]
115    pub spec: S,
116}
117
118impl<S: Spec> From<K8Obj<S>> for K8ObjExport<S> {
119    fn from(obj: K8Obj<S>) -> Self {
120        Self {
121            api_version: obj.api_version,
122            kind: obj.kind,
123            metadata: obj.metadata,
124            spec: obj.spec,
125        }
126    }
127}
128
129#[cfg(test)]
130mod tests {
131    use super::RemoteMetadata;
132    #[cfg(feature = "json")]
133    use super::RemoteMetadataFile;
134
135    #[cfg(feature = "json")]
136    #[test]
137    fn validates_json_config() {
138        let config = r#"{
139            "home": {
140                "id": "home",
141                "remoteId": "remote1",
142                "publicEndpoint": "localhost:30003"
143            }
144          }
145          "#;
146
147        let config = RemoteMetadataFile::from_json(config);
148
149        assert!(config.is_ok());
150
151        let config: RemoteMetadata = config.unwrap().into();
152
153        assert_eq!(config.home.id, "home");
154        assert_eq!(config.home.remote_id, "remote1");
155        assert_eq!(config.home.public_endpoint, "localhost:30003");
156    }
157}