Skip to main content

harmos_runtime/operations/manager/
inspection.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17
18// Third Party Imports
19
20// Local Imports
21use super::*;
22
23/* === Constants === */
24
25/* === Macros === */
26
27/* === Type Aliases === */
28
29/* === Structs === */
30
31/* === Enums === */
32
33/* === Traits === */
34
35/* === Implementations === */
36
37impl OperationManager {
38    pub fn definition(&self, id: &str) -> Result<Definition> {
39        self.entry(id).map(|entry| entry.definition.clone())
40    }
41
42    pub fn definition_from(&self, owner: &str, id: &str) -> Result<Definition> {
43        let entry = self.capture_provider(id, Some(owner))?;
44        entry.available()?;
45        Ok(entry.definition.clone())
46    }
47
48    pub fn submit_from<O: OperationDeclaration>(&self, owner: &str, request: O) -> Result<OperationInstance<O>> {
49        let submitted = executor::now();
50        let entry = self.capture_provider(O::ID, Some(owner))?;
51        self.admit_entry::<O, ()>(
52            (request.into(), ()),
53            None,
54            &[],
55            &Source::Host,
56            Submission { submitted, entry, cause: None, preparation: None },
57        )
58    }
59
60    pub fn definitions(&self) -> Vec<Definition> {
61        self.registry.state.lock().expect("operation registry lock is healthy").definitions()
62    }
63
64    #[cfg(feature = "grpc")]
65    pub(crate) fn reserve_grpc_service(&self, name: &str) -> Result<()> {
66        let mut state = self.registry.state.lock().expect("operation registry lock is healthy");
67        if state.closing {
68            return Err(Error::Closing { domain: "operations" });
69        }
70        let prefix = format!("/{name}/");
71        if state.grpc_services.contains(name) || state.grpc.keys().any(|path| path.starts_with(&prefix)) {
72            return Err(Error::AlreadyRegistered { domain: "gRPC service", name: name.to_owned() });
73        }
74        state.grpc_services.insert(name.to_owned());
75        Ok(())
76    }
77
78    #[cfg(feature = "grpc")]
79    pub fn grpc_methods(&self) -> Vec<crate::operations::GrpcMethod> {
80        let state = self.registry.state.lock().expect("operation registry lock is healthy");
81        if state.closing {
82            return Vec::new();
83        }
84        state
85            .grpc
86            .values()
87            .filter_map(Weak::upgrade)
88            .filter(|entry| entry.active.load(Ordering::Acquire) && entry.available().is_ok())
89            .filter_map(|entry| {
90                Some(crate::operations::GrpcMethod {
91                    owner: entry.owner.clone(),
92                    generation: entry.generation,
93                    contract: entry.contract.clone()?,
94                })
95            })
96            .collect()
97    }
98
99    #[cfg(feature = "grpc")]
100    pub(crate) fn grpc_binding(&self, path: &str) -> Result<crate::operations::GrpcBinding> {
101        let state = self.registry.state.lock().expect("operation registry lock is healthy");
102        if state.closing {
103            return Err(Error::Closing { domain: "operations" });
104        }
105        let entry = state
106            .grpc
107            .get(path)
108            .and_then(Weak::upgrade)
109            .ok_or_else(|| Error::NotRegistered { domain: "gRPC method", name: path.to_owned() })?;
110        if !entry.active.load(Ordering::Acquire) {
111            return Err(Error::Closing { domain: "operation" });
112        }
113        entry.available()?;
114        Ok(crate::operations::GrpcBinding { operations: self.clone(), entry })
115    }
116
117    pub fn owner(&self, id: &str) -> Result<Identifier> {
118        self.entry(id).map(|entry| entry.owner.clone())
119    }
120}
121
122/* === Public Functions === */
123
124/* === Private Functions === */
125
126/* === Tests === */