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