mssf_core/runtime/
activation_context.rs1use mssf_com::{
7 FabricRuntime::{
8 IFabricCodePackage, IFabricCodePackageActivationContext6,
9 IFabricConfigurationPackageChangeHandler,
10 },
11 FabricTypes::{FABRIC_HEALTH_INFORMATION, FABRIC_HEALTH_REPORT_SEND_OPTIONS},
12};
13
14use crate::{
15 Error, PCWSTR, WString,
16 strings::WStringWrap,
17 types::{EndpointResourceDescription, HealthInformation, HealthReportSendOption},
18};
19
20use super::{
21 config::ConfigurationPackage,
22 package_change::{
23 ConfigurationPackageChangeEvent,
24 config::{
25 ConfigurationPackageChangeCallbackHandle, ConfigurationPackageChangeEventHandlerBridge,
26 LambdaConfigurationPackageEventHandler,
27 },
28 },
29};
30
31#[derive(Debug, Clone)]
32pub struct CodePackageActivationContext {
33 com_impl: IFabricCodePackageActivationContext6,
34}
35
36#[derive(Debug, Clone)]
41pub struct CodePackageInfo {
42 pub context_id: WString,
43 pub code_package_name: WString,
44 pub code_package_version: WString,
45 pub work_directory: WString,
46 pub log_directory: WString,
47 pub temp_directory: WString,
48 pub application_name: WString,
49 pub application_type_name: WString,
50 pub service_listen_address: WString,
51 pub service_publish_address: WString,
52}
53
54impl CodePackageActivationContext {
55 pub fn create() -> Result<CodePackageActivationContext, Error> {
56 let com = super::get_com_activation_context::<IFabricCodePackageActivationContext6>()?;
57 Ok(Self::from(com))
58 }
59
60 pub fn get_endpoint_resource(
61 &self,
62 serviceendpointresourcename: &WString,
63 ) -> crate::Result<EndpointResourceDescription> {
64 let rs = unsafe {
65 self.com_impl.GetServiceEndpointResource(PCWSTR::from_raw(
66 serviceendpointresourcename.as_ptr(),
67 ))?
68 };
69 let res_ref = unsafe { rs.as_ref().unwrap() };
70 let desc = EndpointResourceDescription::from(res_ref);
71 Ok(desc)
72 }
73
74 pub fn get_configuration_package(
75 &self,
76 configpackagename: &WString,
77 ) -> crate::Result<ConfigurationPackage> {
78 let c = unsafe {
79 self.com_impl
80 .GetConfigurationPackage(configpackagename.as_pcwstr())
81 }?;
82 Ok(ConfigurationPackage::from(c))
83 }
84
85 pub fn get_code_package_info(&self) -> CodePackageInfo {
86 CodePackageInfo {
87 context_id: WStringWrap::from(unsafe { self.com_impl.get_ContextId() }).into(),
88 code_package_name: WStringWrap::from(unsafe { self.com_impl.get_CodePackageName() })
89 .into(),
90 code_package_version: WStringWrap::from(unsafe {
91 self.com_impl.get_CodePackageVersion()
92 })
93 .into(),
94 work_directory: WStringWrap::from(unsafe { self.com_impl.get_WorkDirectory() }).into(),
95 log_directory: WStringWrap::from(unsafe { self.com_impl.get_LogDirectory() }).into(),
96 temp_directory: WStringWrap::from(unsafe { self.com_impl.get_TempDirectory() }).into(),
97 application_name: WStringWrap::from(PCWSTR(unsafe {
98 self.com_impl.get_ApplicationName().0
99 }))
100 .into(),
101 application_type_name: WStringWrap::from(unsafe {
102 self.com_impl.get_ApplicationTypeName()
103 })
104 .into(),
105 service_listen_address: WStringWrap::from(unsafe {
106 self.com_impl.get_ServiceListenAddress()
107 })
108 .into(),
109 service_publish_address: WStringWrap::from(unsafe {
110 self.com_impl.get_ServicePublishAddress()
111 })
112 .into(),
113 }
114 }
115
116 pub fn get_code_package_names(&self) -> Vec<WString> {
117 let com = unsafe {
119 self.com_impl
120 .GetCodePackageNames()
121 .expect("cannot get code package names")
122 };
123 crate::strings::WStringList::from(&com).into_vec()
124 }
125
126 pub fn get_code_package(&self, name: &WString) -> crate::Result<CodePackage> {
127 let com = unsafe { self.com_impl.GetCodePackage(name.as_pcwstr())? };
128 Ok(CodePackage::from(&com))
129 }
130
131 pub fn report_application_health(
146 &self,
147 healthinfo: &HealthInformation,
148 send_options: Option<&HealthReportSendOption>,
149 ) -> crate::Result<()> {
150 let raw: FABRIC_HEALTH_INFORMATION = healthinfo.into();
151 let send_options = send_options.map(FABRIC_HEALTH_REPORT_SEND_OPTIONS::from);
152 let raw_options = match send_options.as_ref() {
153 Some(opt) => opt as *const FABRIC_HEALTH_REPORT_SEND_OPTIONS,
154 None => std::ptr::null(),
155 };
156 unsafe { self.com_impl.ReportApplicationHealth2(&raw, raw_options) }
157 .map_err(crate::Error::from)
158 }
159
160 pub fn get_com(&self) -> IFabricCodePackageActivationContext6 {
161 self.com_impl.clone()
162 }
163
164 pub fn register_configuration_package_change_handler<T>(
167 &self,
168 handler: T,
169 ) -> crate::Result<ConfigurationPackageChangeCallbackHandle>
170 where
171 T: Fn(&ConfigurationPackageChangeEvent) + 'static,
172 {
173 let lambda_handler = LambdaConfigurationPackageEventHandler::new(handler);
174 let bridge = ConfigurationPackageChangeEventHandlerBridge::new(lambda_handler);
175 let callback: IFabricConfigurationPackageChangeHandler = bridge.into();
176 let raw_handle = unsafe {
178 self.com_impl
179 .RegisterConfigurationPackageChangeHandler(&callback)
180 }?;
181 Ok(unsafe { ConfigurationPackageChangeCallbackHandle::from(raw_handle) })
183 }
184
185 pub fn unregister_configuration_package_change_handler(
186 &self,
187 handle: ConfigurationPackageChangeCallbackHandle,
188 ) -> crate::Result<()> {
189 unsafe {
191 self.com_impl
192 .UnregisterConfigurationPackageChangeHandler(handle.0)
193 }
194 .unwrap();
195 Ok(())
196 }
197}
198
199impl From<IFabricCodePackageActivationContext6> for CodePackageActivationContext {
200 fn from(value: IFabricCodePackageActivationContext6) -> Self {
201 CodePackageActivationContext { com_impl: value }
202 }
203}
204
205#[derive(Debug, Clone)]
206pub struct CodePackage {
207 pub name: WString,
209 pub version: WString,
210 pub service_manifest_name: WString,
211 pub service_manifest_version: WString,
212 pub is_shared: bool,
213 pub setup_entrypoint: Option<WString>, pub entrypoint: Option<WString>, pub path: WString,
218 }
220
221impl From<&IFabricCodePackage> for CodePackage {
222 fn from(value: &IFabricCodePackage) -> Self {
223 let desc = unsafe { value.get_Description().as_ref().unwrap() };
224 let path = unsafe { value.get_Path() };
225 Self {
226 name: desc.Name.into(),
227 version: desc.Version.into(),
228 service_manifest_name: desc.ServiceManifestName.into(),
229 service_manifest_version: desc.ServiceManifestVersion.into(),
230 is_shared: desc.IsShared,
231 setup_entrypoint: None,
232 entrypoint: None,
233 path: WString::from(path),
234 }
235 }
236}