mssf_core/runtime/
node_context.rs

1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation.  All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5
6use std::time::Duration;
7
8use crate::runtime::executor::BoxedCancelToken;
9use crate::strings::StringResult;
10use crate::{Interface, WString};
11use mssf_com::FabricRuntime::{IFabricNodeContextResult, IFabricNodeContextResult2};
12
13use crate::sync::fabric_begin_end_proxy;
14use crate::types::NodeId;
15
16pub fn get_com_node_context(
17    timeout_milliseconds: u32,
18    cancellation_token: Option<BoxedCancelToken>,
19) -> crate::sync::FabricReceiver<crate::WinResult<IFabricNodeContextResult>> {
20    fabric_begin_end_proxy(
21        move |callback| {
22            crate::API_TABLE.fabric_begin_get_node_context(timeout_milliseconds, callback)
23        },
24        move |ctx| crate::API_TABLE.fabric_end_get_node_context(ctx),
25        cancellation_token,
26    )
27}
28
29#[derive(Debug)]
30pub struct NodeContext {
31    com: IFabricNodeContextResult,
32    pub node_name: WString,
33    pub node_type: WString,
34    pub ip_address_or_fqdn: WString,
35    pub node_instance_id: u64,
36    pub node_id: NodeId,
37}
38
39impl NodeContext {
40    // Get the node context from SF runtime
41    pub async fn get(
42        timeout: Duration,
43        cancellation_token: Option<BoxedCancelToken>,
44    ) -> crate::Result<Self> {
45        let com = get_com_node_context(timeout.as_millis().try_into().unwrap(), cancellation_token)
46            .await??;
47        Ok(Self::from(&com))
48    }
49}
50
51impl NodeContext {
52    // Get the node context synchronously
53    pub fn get_sync() -> crate::Result<Self> {
54        let com = crate::API_TABLE.fabric_get_node_context()?;
55        Ok(Self::from(&com))
56    }
57
58    // Retrieves the directory path for the directory at node level.
59    pub fn get_directory(&self, logical_directory_name: &WString) -> crate::Result<WString> {
60        let com2 = self.com.cast::<IFabricNodeContextResult2>()?;
61        let dir = unsafe { com2.GetDirectory(logical_directory_name.as_pcwstr()) }?;
62        Ok(StringResult::from(&dir).into_inner())
63    }
64}
65
66impl From<&IFabricNodeContextResult> for NodeContext {
67    fn from(value: &IFabricNodeContextResult) -> Self {
68        let raw = unsafe { value.get_NodeContext() };
69        assert!(!raw.is_null());
70        let raw_ref = unsafe { raw.as_ref() }.unwrap();
71        Self {
72            com: value.clone(),
73            node_name: WString::from(raw_ref.NodeName),
74            node_type: WString::from(raw_ref.NodeType),
75            ip_address_or_fqdn: WString::from(raw_ref.IPAddressOrFQDN),
76            node_instance_id: raw_ref.NodeInstanceId,
77            node_id: raw_ref.NodeId.into(),
78        }
79    }
80}