use std::collections::BTreeMap;
use serde_json::Value;
use fakecloud_kinesisanalyticsv2::builders;
use super::{ProvisionResult, ResourceDefinition, StackResource};
impl super::ResourceProvisioner {
pub(super) fn create_ka2_application(
&self,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
let props = &resource.properties;
let name = ka2_str(props, "ApplicationName").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::Application requires ApplicationName".to_string()
})?;
let runtime = ka2_str(props, "RuntimeEnvironment").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::Application requires RuntimeEnvironment".to_string()
})?;
let role = ka2_str(props, "ServiceExecutionRole").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::Application requires ServiceExecutionRole".to_string()
})?;
let description = ka2_str(props, "ApplicationDescription");
let mode = ka2_str(props, "ApplicationMode");
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::insert_application(
st,
&self.region,
&self.account_id,
&name,
description,
&runtime,
&role,
mode,
props.get("ApplicationConfiguration"),
props.get("CloudWatchLoggingOptions"),
cfn_tags(props),
)?;
Ok(ProvisionResult::new(name))
}
pub(super) fn update_ka2_application(
&self,
existing: &StackResource,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
self.delete_ka2_application(&existing.physical_id);
self.create_ka2_application(resource)
}
pub(super) fn delete_ka2_application(&self, physical_id: &str) {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
if let Some(app) = st.applications.remove(physical_id) {
st.tags.remove(&app.arn);
}
}
pub(super) fn create_ka2_application_output(
&self,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
let props = &resource.properties;
let app_name = ka2_str(props, "ApplicationName").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationOutput requires ApplicationName".to_string()
})?;
let output = props.get("Output").cloned().ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationOutput requires Output".to_string()
})?;
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
let id = builders::insert_output(st, &app_name, &output)?;
Ok(ProvisionResult::new(id).with("ApplicationName", app_name))
}
pub(super) fn update_ka2_application_output(
&self,
existing: &StackResource,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
if let Some(app_name) = existing.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_output(st, app_name, &existing.physical_id);
}
self.create_ka2_application_output(resource)
}
pub(super) fn delete_ka2_application_output(&self, resource: &StackResource) {
if let Some(app_name) = resource.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_output(st, app_name, &resource.physical_id);
}
}
pub(super) fn create_ka2_reference_data_source(
&self,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
let props = &resource.properties;
let app_name = ka2_str(props, "ApplicationName").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationReferenceDataSource requires ApplicationName"
.to_string()
})?;
let rds = props.get("ReferenceDataSource").cloned().ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationReferenceDataSource requires ReferenceDataSource"
.to_string()
})?;
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
let id = builders::insert_reference_data_source(st, &app_name, &rds)?;
Ok(ProvisionResult::new(id).with("ApplicationName", app_name))
}
pub(super) fn update_ka2_reference_data_source(
&self,
existing: &StackResource,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
if let Some(app_name) = existing.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_reference_data_source(st, app_name, &existing.physical_id);
}
self.create_ka2_reference_data_source(resource)
}
pub(super) fn delete_ka2_reference_data_source(&self, resource: &StackResource) {
if let Some(app_name) = resource.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_reference_data_source(st, app_name, &resource.physical_id);
}
}
pub(super) fn create_ka2_cloudwatch_logging_option(
&self,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
let props = &resource.properties;
let app_name = ka2_str(props, "ApplicationName").ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption requires ApplicationName"
.to_string()
})?;
let opt = props
.get("CloudWatchLoggingOption")
.cloned()
.ok_or_else(|| {
"AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption requires \
CloudWatchLoggingOption"
.to_string()
})?;
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
let id = builders::insert_cloudwatch_logging_option(st, &app_name, &opt)?;
Ok(ProvisionResult::new(id).with("ApplicationName", app_name))
}
pub(super) fn update_ka2_cloudwatch_logging_option(
&self,
existing: &StackResource,
resource: &ResourceDefinition,
) -> Result<ProvisionResult, String> {
if let Some(app_name) = existing.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_cloudwatch_logging_option(st, app_name, &existing.physical_id);
}
self.create_ka2_cloudwatch_logging_option(resource)
}
pub(super) fn delete_ka2_cloudwatch_logging_option(&self, resource: &StackResource) {
if let Some(app_name) = resource.attributes.get("ApplicationName") {
let mut guard = self.ka2_state.write();
let st = guard.get_or_create(&self.account_id);
builders::remove_cloudwatch_logging_option(st, app_name, &resource.physical_id);
}
}
}
fn ka2_str(props: &Value, key: &str) -> Option<String> {
props
.get(key)
.and_then(Value::as_str)
.filter(|s| !s.is_empty())
.map(str::to_string)
}
fn cfn_tags(props: &Value) -> BTreeMap<String, String> {
let mut out = BTreeMap::new();
match props.get("Tags") {
Some(Value::Array(a)) => {
for t in a {
if let Some(k) = t.get("Key").and_then(Value::as_str) {
let v = t.get("Value").and_then(Value::as_str).unwrap_or("");
out.insert(k.to_string(), v.to_string());
}
}
}
Some(Value::Object(m)) => {
for (k, v) in m {
if let Some(s) = v.as_str() {
out.insert(k.clone(), s.to_string());
}
}
}
_ => {}
}
out
}