Skip to main content

rusty_cdk_core/appsync/
builder.rs

1use serde_json::Value;
2use crate::appsync::{AppSyncApi, AppSyncApiProperties, AppSyncApiRef, AppSyncApiType, AppSyncAuthMode, AuthProvider, ChannelNamespace, ChannelNamespaceProperties, ChannelNamespaceRef, ChannelNamespaceType, CognitoConfig, EventConfig, EventLogConfig, LambdaAuthorizerConfig, OpenIDConnectConfig};
3use crate::shared::Id;
4use crate::stack::{Resource, StackBuilder};
5use crate::wrappers::{AppSyncApiName, ChannelNamespaceName};
6
7// TODO add api key builder + DTO
8
9pub struct AppSyncApiBuilder {
10    id: Id,
11    name: String,
12    event_config: Option<EventConfig>,
13}
14
15impl AppSyncApiBuilder {
16    pub fn new(id: &str, app_sync_api_name: AppSyncApiName) -> Self {
17        Self { id: Id(id.to_string()), name: app_sync_api_name.0, event_config: None }
18    }
19
20    pub fn event_config(self, event_config: EventConfig) -> Self {
21        Self {
22            event_config: Some(event_config),
23            ..self
24        }
25    }
26
27    pub fn build(self, stack_builder: &mut StackBuilder) -> AppSyncApiRef {
28        let resource_id = Resource::generate_id("AppSyncApi");
29        let api = AppSyncApi {
30            id: self.id,
31            resource_id: resource_id.clone(),
32            r#type: AppSyncApiType::AppSyncApiType,
33            properties: AppSyncApiProperties {
34                name: self.name,
35                event_config: self.event_config,
36            },
37        };
38        stack_builder.add_resource(api);
39
40        AppSyncApiRef::internal_new(resource_id)
41    }
42}
43
44pub struct EventConfigBuilder {
45    auth_providers: Vec<AuthProvider>,
46    connection_auth_modes: Vec<AppSyncAuthMode>,
47    default_auth_modes: Vec<AppSyncAuthMode>,
48    default_subscribe_auth_modes: Vec<AppSyncAuthMode>,
49    log_config: Option<EventLogConfig>,
50}
51
52impl EventConfigBuilder {
53    pub fn new(auth_providers: Vec<AuthProvider>, connection_auth_modes: Vec<AuthMode>, default_auth_modes: Vec<AuthMode>, default_subscribe_auth_modes: Vec<AuthMode>) -> Self {
54        Self {
55            auth_providers,
56            connection_auth_modes: connection_auth_modes.into_iter().map(Into::into).collect(),
57            default_auth_modes: default_auth_modes.into_iter().map(Into::into).collect(),
58            default_subscribe_auth_modes: default_subscribe_auth_modes.into_iter().map(Into::into).collect(),
59            log_config: None,
60        }
61    }
62
63    pub fn log_config(self, config: EventLogConfig) -> Self {
64        Self {
65            log_config: Some(config),
66            ..self
67        }
68    }
69
70    pub fn build(self) -> EventConfig {
71        EventConfig {
72            auth_providers: self.auth_providers,
73            connection_auth_modes: self.connection_auth_modes,
74            default_auth_modes: self.default_auth_modes,
75            default_subscribe_auth_modes: self.default_subscribe_auth_modes,
76            log_config: self.log_config,
77        }
78    }
79}
80
81pub enum AuthType {
82    AmazonCognitoUserPools(CognitoConfig),
83    AwsIam,
84    ApiKey,
85    OpenidConnect(OpenIDConnectConfig),
86    AwsLambda(LambdaAuthorizerConfig),
87}
88
89#[derive(Debug, Clone)]
90pub enum AuthMode {
91    AmazonCognitoUserPools,
92    AwsIam,
93    ApiKey,
94    OpenidConnect,
95    AwsLambda,
96}
97
98impl From<AuthMode> for AppSyncAuthMode {
99    fn from(mode: AuthMode) -> AppSyncAuthMode {
100        match mode {
101            AuthMode::AmazonCognitoUserPools => {
102                AppSyncAuthMode {
103                    auth_type: Some("AMAZON_COGNITO_USER_POOLS".to_string())
104                }
105            },
106            AuthMode::AwsIam => {
107                AppSyncAuthMode {
108                    auth_type: Some("AWS_IAM".to_string())
109                }
110            },
111            AuthMode::ApiKey => {
112                AppSyncAuthMode {
113                    auth_type: Some("API_KEY".to_string())
114                }
115            },
116            AuthMode::OpenidConnect => {
117                AppSyncAuthMode {
118                    auth_type: Some("OPENID_CONNECT".to_string())
119                }
120            },
121            AuthMode::AwsLambda => {
122                AppSyncAuthMode {
123                    auth_type: Some("AWS_LAMBDA".to_string())
124                }
125            },
126        }
127    }
128}
129
130pub struct AuthProviderBuilder {
131    auth_type: String,
132    cognito_config: Option<CognitoConfig>,
133    lambda_auth_config: Option<LambdaAuthorizerConfig>,
134    open_id_connect_config: Option<OpenIDConnectConfig>,
135}
136
137impl AuthProviderBuilder {
138    pub fn new(auth_type: AuthType) -> Self {
139        match auth_type {
140            AuthType::AmazonCognitoUserPools(c) => {
141                Self {
142                    auth_type: "AMAZON_COGNITO_USER_POOLS".to_string(),
143                    cognito_config: Some(c),
144                    lambda_auth_config: None,
145                    open_id_connect_config: None,
146                }
147            }
148            AuthType::AwsIam => {
149                Self {
150                    auth_type: "AWS_IAM".to_string(),
151                    cognito_config: None,
152                    lambda_auth_config: None,
153                    open_id_connect_config: None,
154                }
155            }
156            AuthType::ApiKey => {
157                Self {
158                    auth_type: "API_KEY".to_string(),
159                    cognito_config: None,
160                    lambda_auth_config: None,
161                    open_id_connect_config: None,
162                }
163            }
164            AuthType::OpenidConnect(c) => {
165                Self {
166                    auth_type: "OPENID_CONNECT".to_string(),
167                    open_id_connect_config: Some(c),
168                    cognito_config: None,
169                    lambda_auth_config: None,
170                }
171            }
172            AuthType::AwsLambda(c) => {
173                Self {
174                    auth_type: "AWS_LAMBDA".to_string(),
175                    lambda_auth_config: Some(c),
176                    cognito_config: None,
177                    open_id_connect_config: None,
178                }
179            }
180        }
181    }
182
183    pub fn build(self) -> AuthProvider {
184        AuthProvider {
185            auth_type: self.auth_type,
186            cognito_config: self.cognito_config,
187            lambda_auth_config: self.lambda_auth_config,
188            open_id_connect_config: self.open_id_connect_config,
189        }
190    }
191}
192
193#[derive(Debug, Clone)]
194pub enum AppSyncApiLogLevel {
195    None,
196    Error,
197    All,
198    Info,
199    Debug
200}
201
202impl From<AppSyncApiLogLevel> for String {
203    fn from(api: AppSyncApiLogLevel) -> String {
204        match api {
205            AppSyncApiLogLevel::None => "NONE".to_string(),
206            AppSyncApiLogLevel::Error => "ERROR".to_string(),
207            AppSyncApiLogLevel::All => "ALL".to_string(),
208            AppSyncApiLogLevel::Info => "INFO".to_string(),
209            AppSyncApiLogLevel::Debug => "DEBUG".to_string(),
210        }
211    }
212}
213
214pub struct EventLogConfigBuilder {
215    cloudwatch_logs_role_arn: String,
216    log_level: String
217}
218
219impl EventLogConfigBuilder {
220    pub fn new(cloudwatch_logs_role_arn: String, log_level: AppSyncApiLogLevel) -> Self {
221        Self { cloudwatch_logs_role_arn, log_level: log_level.into() }
222    }
223
224    pub fn build(self) -> EventLogConfig {
225        EventLogConfig {
226            cloudwatch_logs_role_arn: self.cloudwatch_logs_role_arn,
227            log_level: self.log_level,
228        }
229    }
230}
231
232pub struct ChannelNamespaceBuilder {
233    id: Id,
234    api_id: Value,
235    name: String, // TODO should actually also be unique within the api
236    publish_auth_modes: Option<Vec<AppSyncAuthMode>>,
237    subscribe_auth_modes: Option<Vec<AppSyncAuthMode>>,
238}
239
240impl ChannelNamespaceBuilder {
241    pub fn new(id: &str, api_id: &AppSyncApiRef, name: ChannelNamespaceName) -> Self {
242        Self {
243            id: Id(id.to_string()),
244            api_id: api_id.get_att("ApiId"),
245            name: name.0,
246            publish_auth_modes: None,
247            subscribe_auth_modes: None,
248        }
249    }
250    
251    pub fn publish_auth_modes(self, publish_auth_modes: Vec<AuthMode>) -> Self {
252        Self {
253            publish_auth_modes: Some(publish_auth_modes.into_iter().map(Into::into).collect()),
254            ..self
255        }
256    }
257
258    
259    pub fn subscribe_auth_modes(self, subscribe_auth_modes: Vec<AuthMode>) -> Self {
260        Self {
261            subscribe_auth_modes: Some(subscribe_auth_modes.into_iter().map(Into::into).collect()),
262            ..self
263        }
264    }
265
266    pub fn build(self, stack_builder: &mut StackBuilder) -> ChannelNamespaceRef {
267        let resource_id = Resource::generate_id("ChannelNamespace");
268        let channel = ChannelNamespace {
269            id: self.id,
270            resource_id: resource_id.clone(),
271            r#type: ChannelNamespaceType::ChannelNamespaceType,
272            properties: ChannelNamespaceProperties {
273                api_id: self.api_id,
274                name: self.name,
275                publish_auth_modes: self.publish_auth_modes,
276                subscribe_auth_modes: self.subscribe_auth_modes,
277            },
278        };
279        stack_builder.add_resource(channel);
280
281        ChannelNamespaceRef::internal_new(resource_id)
282    }
283}