pdk_core/policy_context/
api.rs

1// Copyright (c) 2025, Salesforce, Inc.,
2// All rights reserved.
3// For full license text, see the LICENSE.txt file
4
5//! Data types that exposes metadata for the policy.
6
7use crate::policy_context::metadata::{Api, EnvironmentContext};
8use crate::policy_context::static_policy_context_cache::StaticPolicyContextCache;
9use classy::extract::context::ConfigureContext;
10use classy::extract::FromContext;
11use std::convert::Infallible;
12
13#[derive(Clone, Debug)]
14/// Metadata about the API and the policy.
15pub struct Metadata {
16    /// Metadata regarding the flex instance where the policy is running.
17    pub flex_metadata: FlexMetadata,
18    /// Metadata regarding the policy.
19    pub policy_metadata: PolicyMetadata,
20    /// Metadata regarding the api where the policy is applied.
21    pub api_metadata: ApiMetadata,
22    /// Metadata regarding the management plane.
23    pub platform_metadata: PlatformMetadata,
24}
25
26#[derive(Clone, Debug)]
27/// Information about the Flex Gateway where the policy is running.
28pub struct FlexMetadata {
29    /// Name of the flex instance
30    pub flex_name: String,
31    /// Version of the flex instance
32    pub flex_version: String,
33}
34
35#[derive(Clone, Debug)]
36/// Metadata regarding the policy.
37pub struct PolicyMetadata {
38    /// Name of the policy.
39    pub policy_name: String,
40    /// Namespace of the policy.
41    pub policy_namespace: String,
42    #[cfg(feature = "experimental_filter_name")]
43    /// The name of the filter.
44    pub filter_name: String,
45}
46
47#[derive(Clone, Debug)]
48/// Metadata regarding the api where the policy is applied.
49pub struct ApiMetadata {
50    /// The ID of the API.
51    pub id: Option<String>,
52    /// The name of the API.
53    pub name: Option<String>,
54    /// The version of the API.
55    pub version: Option<String>,
56    /// The base_path of the API.
57    pub base_path: Option<String>,
58    /// The slas associated to the API.
59    pub slas: Option<Vec<ApiSla>>,
60}
61
62#[derive(Clone, Debug, Default)]
63/// Metadata regarding the management plane.
64pub struct PlatformMetadata {
65    /// Organization ID
66    pub organization_id: String,
67    /// Environment ID
68    pub environment_id: String,
69    /// The root organization ID
70    pub root_organization_id: String,
71}
72
73#[derive(Clone, Debug)]
74/// The SLA associated to the API.
75pub struct ApiSla {
76    /// The id of the SLA.
77    pub id: String,
78    /// The tiers associated to the SLA.
79    pub tiers: Vec<Tier>,
80}
81
82#[derive(Clone, Debug)]
83/// The limits associated to a [`ApiSla`]
84pub struct Tier {
85    /// Number of requests allowed on a given time.
86    pub requests: u64,
87    /// Time in which the requests are tracked.
88    pub period_in_millis: u64,
89}
90
91impl From<&crate::policy_context::metadata::PolicyMetadata> for Metadata {
92    fn from(value: &crate::policy_context::metadata::PolicyMetadata) -> Self {
93        Metadata {
94            flex_metadata: value.into(),
95            policy_metadata: value.into(),
96            api_metadata: value.into(),
97            platform_metadata: value.into(),
98        }
99    }
100}
101
102impl From<&crate::policy_context::metadata::PolicyMetadata> for FlexMetadata {
103    fn from(value: &crate::policy_context::metadata::PolicyMetadata) -> Self {
104        FlexMetadata {
105            flex_name: value.flex_name().to_string(),
106            flex_version: value
107                .anypoint_environment()
108                .and_then(EnvironmentContext::flex_version)
109                .map(str::to_string)
110                // Will always be set since min flex version is 1.6.1
111                .unwrap_or_default(),
112        }
113    }
114}
115
116impl From<&crate::policy_context::metadata::PolicyMetadata> for PolicyMetadata {
117    fn from(value: &crate::policy_context::metadata::PolicyMetadata) -> Self {
118        PolicyMetadata {
119            policy_name: value.policy_id().to_string(),
120            policy_namespace: value.policy_namespace().to_string(),
121            #[cfg(feature = "experimental_filter_name")]
122            filter_name: value.filter_name().to_string(),
123        }
124    }
125}
126
127impl From<&crate::policy_context::metadata::PolicyMetadata> for ApiMetadata {
128    fn from(value: &crate::policy_context::metadata::PolicyMetadata) -> Self {
129        ApiMetadata {
130            id: value.api_info().map(Api::id).map(str::to_string),
131            name: value.api_info().map(Api::name).map(str::to_string),
132            version: value.api_info().map(Api::version).map(str::to_string),
133            base_path: value
134                .api_info()
135                .and_then(Api::base_path)
136                .map(str::to_string),
137            slas: value
138                .api_tiers()
139                .map(|slas| slas.iter().map(|sla| sla.into()).collect()),
140        }
141    }
142}
143
144impl From<&crate::policy_context::metadata::ApiSla> for ApiSla {
145    fn from(value: &crate::policy_context::metadata::ApiSla) -> Self {
146        ApiSla {
147            id: value.id().to_string(),
148            tiers: value.tiers().iter().map(|s| s.into()).collect(),
149        }
150    }
151}
152
153impl From<&crate::policy_context::metadata::Tier> for Tier {
154    fn from(value: &crate::policy_context::metadata::Tier) -> Self {
155        Tier {
156            requests: value.requests(),
157            period_in_millis: value.period_in_millis(),
158        }
159    }
160}
161
162impl From<&crate::policy_context::metadata::PolicyMetadata> for PlatformMetadata {
163    fn from(value: &crate::policy_context::metadata::PolicyMetadata) -> Self {
164        // PlatformMetadata should always be set since it is read from the registration yaml.
165        value
166            .anypoint_environment()
167            .map(|env| PlatformMetadata {
168                organization_id: env.organization_id().to_string(),
169                environment_id: env.environment_id().to_string(),
170                root_organization_id: env.master_organization_id().to_string(),
171            })
172            .unwrap_or_default()
173    }
174}
175
176impl FromContext<ConfigureContext> for Metadata {
177    type Error = Infallible;
178
179    fn from_context(_context: &ConfigureContext) -> Result<Self, Self::Error> {
180        Ok(Metadata::new())
181    }
182}
183
184impl Metadata {
185    pub fn new() -> Metadata {
186        let context = StaticPolicyContextCache::read_metadata();
187        Metadata::from(context.as_ref())
188    }
189}
190
191impl Default for Metadata {
192    fn default() -> Self {
193        Metadata::new()
194    }
195}