running_process/broker/
builders.rs1use std::path::{Path, PathBuf};
32use std::time::{SystemTime, UNIX_EPOCH};
33
34use crate::broker::host_identity;
35use crate::broker::manifest::{
36 manifest_with_self_sha256, write_to_central, write_to_central_in_dir, ManifestError,
37 CACHE_MANIFEST_MEDIA_TYPE, SUPPORTED_MANIFEST_SCHEMA_VERSION,
38};
39use crate::broker::protocol::{
40 BrokerIsolation, CacheManifest, CacheRoot, CacheRootKind, ServiceDefinition,
41};
42use crate::broker::server::service_def_loader::{
43 service_definition_dir, validate_service_definition_for_service, write_service_definition,
44 ServiceDefinitionError,
45};
46
47const BROKER_ENVELOPE_VERSION: &str = "v1";
49
50#[derive(Clone, Debug)]
57pub struct ServiceDefinitionBuilder {
58 definition: ServiceDefinition,
59}
60
61impl ServiceDefinitionBuilder {
62 pub fn shared_broker(service_name: impl Into<String>, binary_path: impl Into<String>) -> Self {
67 Self {
68 definition: ServiceDefinition {
69 service_name: service_name.into(),
70 binary_path: binary_path.into(),
71 isolation: BrokerIsolation::SharedBroker as i32,
72 ..Default::default()
73 },
74 }
75 }
76
77 pub fn explicit_instance(
82 service_name: impl Into<String>,
83 binary_path: impl Into<String>,
84 instance: impl Into<String>,
85 ) -> Self {
86 Self {
87 definition: ServiceDefinition {
88 service_name: service_name.into(),
89 binary_path: binary_path.into(),
90 isolation: BrokerIsolation::ExplicitInstance as i32,
91 explicit_instance: instance.into(),
92 ..Default::default()
93 },
94 }
95 }
96
97 pub fn min_version(mut self, version: impl Into<String>) -> Self {
99 self.definition.min_version = version.into();
100 self
101 }
102
103 pub fn allow_version(mut self, version: impl Into<String>) -> Self {
105 self.definition.version_allow_list.push(version.into());
106 self
107 }
108
109 pub fn per_version_binary_dir(mut self, dir: impl Into<String>) -> Self {
111 self.definition.per_version_binary_dir = dir.into();
112 self
113 }
114
115 pub fn label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
117 self.definition.labels.insert(key.into(), value.into());
118 self
119 }
120
121 pub fn build(self) -> Result<ServiceDefinition, ServiceDefinitionError> {
123 validate_service_definition_for_service(&self.definition, &self.definition.service_name)?;
124 Ok(self.definition)
125 }
126
127 pub fn install(self) -> Result<PathBuf, ServiceDefinitionError> {
130 self.install_in(&service_definition_dir())
131 }
132
133 pub fn install_in(self, root: &Path) -> Result<PathBuf, ServiceDefinitionError> {
136 let definition = self.build()?;
137 write_service_definition(root, &definition)
138 }
139}
140
141#[derive(Clone, Debug)]
149pub struct CacheManifestBuilder {
150 manifest: CacheManifest,
151}
152
153impl CacheManifestBuilder {
154 pub fn new(service_name: impl Into<String>, service_version: impl Into<String>) -> Self {
156 let now = now_unix_ms();
157 Self {
158 manifest: CacheManifest {
159 manifest_schema_version: SUPPORTED_MANIFEST_SCHEMA_VERSION,
160 media_type: CACHE_MANIFEST_MEDIA_TYPE.to_string(),
161 host: Some(host_identity::current()),
162 service_name: service_name.into(),
163 service_version: service_version.into(),
164 broker_envelope_version: BROKER_ENVELOPE_VERSION.to_string(),
165 created_at_unix_ms: now,
166 last_active_unix_ms: now,
167 ..Default::default()
168 },
169 }
170 }
171
172 pub fn broker_instance(mut self, instance: impl Into<String>) -> Self {
175 self.manifest.broker_instance = instance.into();
176 self
177 }
178
179 pub fn bundle_id(mut self, bundle_id: impl Into<String>) -> Self {
181 self.manifest.bundle_id = bundle_id.into();
182 self
183 }
184
185 pub fn root(mut self, kind: CacheRootKind, path: impl Into<String>) -> Self {
187 self.manifest.roots.push(CacheRoot {
188 path: path.into(),
189 kind: kind as i32,
190 ..Default::default()
191 });
192 self
193 }
194
195 pub fn build(self) -> Result<CacheManifest, ManifestError> {
198 manifest_with_self_sha256(&self.manifest)
199 }
200
201 pub fn publish(self) -> Result<PathBuf, ManifestError> {
204 let manifest = self.build()?;
205 write_to_central(&manifest.service_name, &manifest.service_version, &manifest)
206 }
207
208 pub fn publish_in(self, registry_dir: &Path) -> Result<PathBuf, ManifestError> {
210 let manifest = self.build()?;
211 write_to_central_in_dir(
212 registry_dir,
213 &manifest.service_name,
214 &manifest.service_version,
215 &manifest,
216 )
217 }
218}
219
220fn now_unix_ms() -> u64 {
221 SystemTime::now()
222 .duration_since(UNIX_EPOCH)
223 .map(|d| d.as_millis() as u64)
224 .unwrap_or(0)
225}