Skip to main content

mssf_core/client/
application_client.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 mssf_com::{
9    FabricClient::{IFabricApplicationManagementClient, IFabricApplicationUpgradeProgressResult2},
10    FabricTypes::FABRIC_URI,
11};
12
13use crate::{
14    runtime::executor::BoxedCancelToken,
15    sync::{FabricReceiver, fabric_begin_end_proxy},
16    types::{ApplicationUpgradeProgress, Uri},
17};
18
19/// Provides functionality to perform application management operations, such as
20/// querying application upgrade progress.
21///
22/// See C# API [here](https://learn.microsoft.com/en-us/dotnet/api/system.fabric.fabricclient.applicationmanagementclient?view=azure-dotnet).
23///
24/// We are only adding support for application upgrade progress for now - additional functionality can be added later.
25#[derive(Debug, Clone)]
26pub struct ApplicationManagementClient {
27    com: IFabricApplicationManagementClient,
28}
29
30impl From<IFabricApplicationManagementClient> for ApplicationManagementClient {
31    fn from(value: IFabricApplicationManagementClient) -> Self {
32        Self { com: value }
33    }
34}
35
36impl From<ApplicationManagementClient> for IFabricApplicationManagementClient {
37    fn from(value: ApplicationManagementClient) -> Self {
38        value.com
39    }
40}
41
42// Internal implementation block - convert SF callbacks into async futures.
43impl ApplicationManagementClient {
44    fn get_application_upgrade_progress_internal(
45        &self,
46        application_name: FABRIC_URI,
47        timeout_milliseconds: u32,
48        cancellation_token: Option<BoxedCancelToken>,
49    ) -> FabricReceiver<crate::Result<IFabricApplicationUpgradeProgressResult2>> {
50        let com1 = &self.com;
51        let com2 = self.com.clone();
52        fabric_begin_end_proxy(
53            move |callback| unsafe {
54                com1.BeginGetApplicationUpgradeProgress(
55                    application_name,
56                    timeout_milliseconds,
57                    callback,
58                )
59            },
60            move |ctx| unsafe { com2.EndGetApplicationUpgradeProgress(ctx) },
61            cancellation_token,
62        )
63    }
64}
65
66// Public implementation block.
67impl ApplicationManagementClient {
68    /// Gets the upgrade progress for the specified application.
69    /// Equivalent of the `Get-ServiceFabricApplicationUpgrade` PowerShell cmdlet.
70    ///
71    /// The returned [`ApplicationUpgradeProgress`] includes the aggregate
72    /// upgrade state as well as the per upgrade-domain status.
73    ///
74    /// Remarks: SF returns a valid result even for applications that are not
75    /// currently upgrading; check [`ApplicationUpgradeProgress::is_active`] to
76    /// determine whether an upgrade is in flight.
77    pub async fn get_application_upgrade_progress(
78        &self,
79        application_name: &Uri,
80        timeout: Duration,
81        cancellation_token: Option<BoxedCancelToken>,
82    ) -> crate::Result<ApplicationUpgradeProgress> {
83        let com = self
84            .get_application_upgrade_progress_internal(
85                application_name.as_raw(),
86                timeout.as_millis().try_into().unwrap(),
87                cancellation_token,
88            )
89            .await??;
90        Ok(ApplicationUpgradeProgress::from(&com))
91    }
92}