mssf_core/client/
connection.rs1use mssf_com::{
7 FabricClient::{
8 IFabricClientConnectionEventHandler, IFabricClientConnectionEventHandler_Impl,
9 IFabricClientConnectionEventHandler2, IFabricClientConnectionEventHandler2_Impl,
10 IFabricGatewayInformationResult,
11 },
12 FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA,
13};
14
15use crate::{WString, types::NodeId};
16
17pub trait ClientConnectionEventHandler: Send + Sync + 'static {
20 fn on_connected(&self, info: &GatewayInformationResult) -> crate::Result<()>;
21 fn on_disconnected(&self, info: &GatewayInformationResult) -> crate::Result<()>;
22 fn on_claims_retrieval(&self, metadata: ClaimsRetrievalMetadata) -> crate::Result<WString>;
23}
24
25#[derive(Debug, Clone)]
28pub struct GatewayInformationResult {
29 pub node_address: crate::WString,
30 pub node_id: NodeId,
31 pub node_instance_id: u64,
32 pub node_name: crate::WString,
33}
34
35impl From<&IFabricGatewayInformationResult> for GatewayInformationResult {
36 fn from(com: &IFabricGatewayInformationResult) -> Self {
37 let info = unsafe { com.get_GatewayInformation().as_ref().unwrap() };
38 Self {
39 node_address: WString::from(info.NodeAddress),
40 node_id: info.NodeId.into(),
41 node_instance_id: info.NodeInstanceId,
42 node_name: WString::from(info.NodeName),
43 }
44 }
45}
46
47#[windows_core::implement(IFabricClientConnectionEventHandler2)]
50pub struct ClientConnectionEventHandlerBridge<T>
51where
52 T: ClientConnectionEventHandler,
53{
54 inner: T,
55}
56
57impl<T> ClientConnectionEventHandlerBridge<T>
58where
59 T: ClientConnectionEventHandler,
60{
61 pub fn new(inner: T) -> Self {
62 Self { inner }
63 }
64 pub fn new_com(inner: T) -> IFabricClientConnectionEventHandler {
65 let h1: IFabricClientConnectionEventHandler2 = Self::new(inner).into();
66 use windows_core::Interface;
67 h1.cast().unwrap()
68 }
69}
70
71impl<T> IFabricClientConnectionEventHandler_Impl for ClientConnectionEventHandlerBridge_Impl<T>
72where
73 T: ClientConnectionEventHandler,
74{
75 fn OnConnected(
76 &self,
77 gw_info: windows_core::Ref<IFabricGatewayInformationResult>,
78 ) -> crate::WinResult<()> {
79 let info = GatewayInformationResult::from(gw_info.unwrap());
80 self.inner
81 .on_connected(&info)
82 .map_err(crate::WinError::from)
83 }
84
85 fn OnDisconnected(
86 &self,
87 gw_info: windows_core::Ref<IFabricGatewayInformationResult>,
88 ) -> crate::WinResult<()> {
89 let info = GatewayInformationResult::from(gw_info.unwrap());
90 self.inner
91 .on_disconnected(&info)
92 .map_err(crate::WinError::from)
93 }
94}
95
96impl<T> IFabricClientConnectionEventHandler2_Impl for ClientConnectionEventHandlerBridge_Impl<T>
97where
98 T: ClientConnectionEventHandler,
99{
100 fn OnClaimsRetrieval(
101 &self,
102 metadata: *const mssf_com::Microsoft::ServiceFabric::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA,
103 ) -> crate::WinResult<mssf_com::Microsoft::ServiceFabric::FabricCommon::IFabricStringResult>
104 {
105 let meta = unsafe { metadata.as_ref().unwrap() };
106 let claims_meta = ClaimsRetrievalMetadata::from(meta);
107 let result = self
108 .inner
109 .on_claims_retrieval(claims_meta)
110 .map_err(crate::WinError::from)?;
111
112 let string_result = crate::strings::StringResult::new(result);
113 Ok(string_result.into())
114 }
115}
116
117pub trait ConnectionNotificationFn:
120 Fn(&GatewayInformationResult) -> crate::Result<()> + Send + Sync + 'static
121{
122}
123impl<T> ConnectionNotificationFn for T where
124 T: Fn(&GatewayInformationResult) -> crate::Result<()> + Send + Sync + 'static
125{
126}
127
128pub trait ClaimsRetrievalFn:
129 Fn(ClaimsRetrievalMetadata) -> crate::Result<WString> + Send + Sync + 'static
130{
131}
132impl<T> ClaimsRetrievalFn for T where
133 T: Fn(ClaimsRetrievalMetadata) -> crate::Result<WString> + Send + Sync + 'static
134{
135}
136
137pub struct LambdaClientConnectionNotificationHandler {
140 f_conn: Option<Box<dyn ConnectionNotificationFn>>,
141 f_disconn: Option<Box<dyn ConnectionNotificationFn>>,
142 f_claims: Option<Box<dyn ClaimsRetrievalFn>>,
143}
144
145impl LambdaClientConnectionNotificationHandler {
146 pub fn new() -> Self {
147 Self {
148 f_conn: None,
149 f_disconn: None,
150 f_claims: None,
151 }
152 }
153
154 pub fn set_f_conn(&mut self, f: impl ConnectionNotificationFn) {
156 self.f_conn = Some(Box::new(f));
157 }
158
159 pub fn set_f_disconn(&mut self, f: impl ConnectionNotificationFn) {
161 self.f_disconn = Some(Box::new(f));
162 }
163
164 pub fn set_f_claims(&mut self, f: impl ClaimsRetrievalFn) {
166 self.f_claims = Some(Box::new(f));
167 }
168}
169
170impl ClientConnectionEventHandler for LambdaClientConnectionNotificationHandler {
171 fn on_connected(&self, info: &GatewayInformationResult) -> crate::Result<()> {
172 if let Some(f) = &self.f_conn {
173 f(info)
174 } else {
175 Ok(())
176 }
177 }
178
179 fn on_disconnected(&self, info: &GatewayInformationResult) -> crate::Result<()> {
180 if let Some(f) = &self.f_disconn {
181 f(info)
182 } else {
183 Ok(())
184 }
185 }
186
187 fn on_claims_retrieval(&self, metadata: ClaimsRetrievalMetadata) -> crate::Result<WString> {
188 if let Some(f) = &self.f_claims {
189 f(metadata)
190 } else {
191 Err(crate::ErrorCode::E_NOTIMPL.into())
193 }
194 }
195}
196
197#[derive(Debug, Clone, PartialEq)]
199pub struct AadClaimsRetrievalMetadata {
200 pub authority: WString,
201 pub tenant_id: WString,
202 pub cluster_application: WString,
203 pub client_application: WString,
204 pub client_redirect: WString,
205 pub login_endpoint: WString,
207}
208
209#[derive(Debug, Clone, PartialEq)]
211pub enum ClaimsRetrievalMetadata {
212 AAD(AadClaimsRetrievalMetadata),
213 None,
214}
215
216impl From<&FABRIC_CLAIMS_RETRIEVAL_METADATA> for ClaimsRetrievalMetadata {
217 fn from(value: &FABRIC_CLAIMS_RETRIEVAL_METADATA) -> Self {
218 match value.Kind {
219 mssf_com::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA_KIND_AAD => {
220 let aad_meta = unsafe {
221 (value.Value
222 as *const mssf_com::FabricTypes::FABRIC_AAD_CLAIMS_RETRIEVAL_METADATA)
223 .as_ref()
224 .unwrap()
225 };
226 let ex1 = unsafe {
227 (aad_meta.Reserved
228 as *const mssf_com::FabricTypes::FABRIC_AAD_CLAIMS_RETRIEVAL_METADATA_EX1)
229 .as_ref()
230 };
231
232 ClaimsRetrievalMetadata::AAD(AadClaimsRetrievalMetadata {
233 authority: WString::from(aad_meta.Authority),
234 tenant_id: WString::from(aad_meta.TenantId),
235 cluster_application: WString::from(aad_meta.ClusterApplication),
236 client_application: WString::from(aad_meta.ClientApplication),
237 client_redirect: WString::from(aad_meta.ClientRedirect),
238 login_endpoint: ex1.map_or(WString::new(), |v| WString::from(v.LoginEndpoint)),
239 })
240 }
241 mssf_com::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA_KIND_NONE => {
242 ClaimsRetrievalMetadata::None
243 }
244 _ => ClaimsRetrievalMetadata::None,
245 }
246 }
247}