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