From 8f527f3ae5e72b9a406f42ae9e6cf0929efc624e Mon Sep 17 00:00:00 2001 From: jinyangyang222 Date: Wed, 13 Nov 2024 16:49:42 +0800 Subject: [PATCH] feat(iotda/data_flow_control_policy): support data flow control policy resource --- .../iotda_data_flow_control_policy.md | 87 +++++ huaweicloud/provider.go | 27 +- ...oud_iotda_data_flow_control_policy_test.go | 351 ++++++++++++++++++ ...weicloud_iotda_data_flow_control_policy.go | 202 ++++++++++ 4 files changed, 654 insertions(+), 13 deletions(-) create mode 100644 docs/resources/iotda_data_flow_control_policy.md create mode 100644 huaweicloud/services/acceptance/iotda/resource_huaweicloud_iotda_data_flow_control_policy_test.go create mode 100644 huaweicloud/services/iotda/resource_huaweicloud_iotda_data_flow_control_policy.go diff --git a/docs/resources/iotda_data_flow_control_policy.md b/docs/resources/iotda_data_flow_control_policy.md new file mode 100644 index 0000000000..8c174a0c2c --- /dev/null +++ b/docs/resources/iotda_data_flow_control_policy.md @@ -0,0 +1,87 @@ +--- +subcategory: "IoT Device Access (IoTDA)" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_iotda_data_flow_control_policy" +description: |- + Manages an IoTDA data flow control policy resource within HuaweiCloud. +--- + +# huaweicloud_iotda_data_flow_control_policy + +Manages an IoTDA data flow control policy resource within HuaweiCloud. + +-> Currently, data flow control policy resources are only supported on IoTDA **standard** or **enterprise** edition + instance. When accessing an IoTDA **standard** or **enterprise** edition instance, you need to specify + the IoTDA service endpoint in `provider` block. + You can login to the IoTDA console, choose the instance **Overview** and click **Access Details** + to view the HTTPS application access address. An example of the access address might be + *9bc34xxxxx.st1.iotda-app.ap-southeast-1.myhuaweicloud.com*, then you need to configure the + `provider` block as follows: + + ```hcl + provider "huaweicloud" { + endpoints = { + iotda = "https://9bc34xxxxx.st1.iotda-app.ap-southeast-1.myhuaweicloud.com" + } + } + ``` + +## Example Usage + +```hcl +variable "name" {} +variable "scope" {} + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = var.name + scope = var.scope +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource. + If omitted, the provider-level region will be used. Changing this parameter will create a new resource. + +* `name` - (Optional, String) Specifies the name of the data flow control policy. The length must not exceed `256`, and + only Chinese characters, letters, numbers, and the following characters are allowed: `_?'#().,&%@!-**`. + +* `description` - (Optional, String) Specifies the description of the data flow control policy. The length must not + exceed `256`, and only Chinese characters, letters, numbers, and the following characters are allowed: `_?'#().,&%@!-**`. + +* `scope` - (Optional, String, ForceNew) Specifies the scope of the data flow control policy. Changing this parameter + will create a new resource. + The valid values are as follows: + + **USER**: Tenant level flow control strategy. + + **CHANNEL**: Forwarding channel level flow control strategy. + + **RULE**: Forwarding rule level flow control strategy. + + **ACTION**: Forwarding action level flow control strategy. + + If omitted, defaults to **USER**. + +* `scope_value` - (Optional, String, ForceNew) Specifies the scope add value of the data flow control policy. Changing + this parameter will create a new resource. + + If the `scope` is set to **USER**, this field does not need to be set. + + If the `scope` is set to **CHANNEL**, the valid values are **HTTP_FORWARDING**, **DIS_FORWARDING**, + **OBS_FORWARDING**, **AMQP_FORWARDING**, and **DMS_KAFKA_FORWARDING**. + + If the `scope` is set to **RULE**, the value of this field is the corresponding data forwarding rule ID. + + If the `scope` is set to **ACTION**, the value of this field is the corresponding data forwarding rule action ID. + +* `limit` - (Optional, Int) Specifies the size of the data forwarding flow control, in tps. Integers with valid values + ranging from `1` to `1,000`. Defaults to `1,000`. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +The data flow control policy can be imported using the `id`, e.g. + +```bash +$ terraform import huaweicloud_iotda_data_flow_control_policy.test +``` diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 031670a882..23e40d0532 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -1720,19 +1720,20 @@ func Provider() *schema.Provider { "huaweicloud_images_image_share": ims.ResourceImsImageShare(), "huaweicloud_images_image_share_accepter": ims.ResourceImsImageShareAccepter(), - "huaweicloud_iotda_access_credential": iotda.ResourceAccessCredential(), - "huaweicloud_iotda_amqp": iotda.ResourceAmqp(), - "huaweicloud_iotda_batchtask": iotda.ResourceBatchTask(), - "huaweicloud_iotda_dataforwarding_rule": iotda.ResourceDataForwardingRule(), - "huaweicloud_iotda_device": iotda.ResourceDevice(), - "huaweicloud_iotda_device_async_command": iotda.ResourceDeviceAsyncCommand(), - "huaweicloud_iotda_device_certificate": iotda.ResourceDeviceCertificate(), - "huaweicloud_iotda_device_group": iotda.ResourceDeviceGroup(), - "huaweicloud_iotda_device_linkage_rule": iotda.ResourceDeviceLinkageRule(), - "huaweicloud_iotda_device_proxy": iotda.ResourceDeviceProxy(), - "huaweicloud_iotda_product": iotda.ResourceProduct(), - "huaweicloud_iotda_space": iotda.ResourceSpace(), - "huaweicloud_iotda_upgrade_package": iotda.ResourceUpgradePackage(), + "huaweicloud_iotda_access_credential": iotda.ResourceAccessCredential(), + "huaweicloud_iotda_amqp": iotda.ResourceAmqp(), + "huaweicloud_iotda_batchtask": iotda.ResourceBatchTask(), + "huaweicloud_iotda_dataforwarding_rule": iotda.ResourceDataForwardingRule(), + "huaweicloud_iotda_data_flow_control_policy": iotda.ResourceDataFlowControlPolicy(), + "huaweicloud_iotda_device": iotda.ResourceDevice(), + "huaweicloud_iotda_device_async_command": iotda.ResourceDeviceAsyncCommand(), + "huaweicloud_iotda_device_certificate": iotda.ResourceDeviceCertificate(), + "huaweicloud_iotda_device_group": iotda.ResourceDeviceGroup(), + "huaweicloud_iotda_device_linkage_rule": iotda.ResourceDeviceLinkageRule(), + "huaweicloud_iotda_device_proxy": iotda.ResourceDeviceProxy(), + "huaweicloud_iotda_product": iotda.ResourceProduct(), + "huaweicloud_iotda_space": iotda.ResourceSpace(), + "huaweicloud_iotda_upgrade_package": iotda.ResourceUpgradePackage(), "huaweicloud_kms_data_encrypt_decrypt": dew.ResourceKmsDataEncryptDecrypt(), "huaweicloud_kms_key": dew.ResourceKmsKey(), diff --git a/huaweicloud/services/acceptance/iotda/resource_huaweicloud_iotda_data_flow_control_policy_test.go b/huaweicloud/services/acceptance/iotda/resource_huaweicloud_iotda_data_flow_control_policy_test.go new file mode 100644 index 0000000000..9b2fe24632 --- /dev/null +++ b/huaweicloud/services/acceptance/iotda/resource_huaweicloud_iotda_data_flow_control_policy_test.go @@ -0,0 +1,351 @@ +package iotda + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iotda/v5/model" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func getDataFlowControlPolicyResourceFunc(conf *config.Config, state *terraform.ResourceState) (interface{}, error) { + client, err := conf.HcIoTdaV5Client(acceptance.HW_REGION_NAME, WithDerivedAuth()) + if err != nil { + return nil, fmt.Errorf("error creating IoTDA v5 client: %s", err) + } + + return client.ShowRoutingFlowControlPolicy(&model.ShowRoutingFlowControlPolicyRequest{PolicyId: state.Primary.ID}) +} + +func TestAccDataFlowControlPolicy_basic(t *testing.T) { + var ( + obj model.ShowDeviceProxyResponse + name = acceptance.RandomAccResourceName() + rName = "huaweicloud_iotda_data_flow_control_policy.test" + ) + + rc := acceptance.InitResourceCheck( + rName, + &obj, + getDataFlowControlPolicyResourceFunc, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + // This resource only supports standard and enterprise version IoTDA instances. + acceptance.TestAccPreCheckHWIOTDAAccessAddress(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testDataFlowControlPolicy_userScope(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "description", "description_test"), + resource.TestCheckResourceAttr(rName, "scope", "USER"), + resource.TestCheckResourceAttr(rName, "limit", "1000"), + ), + }, + { + Config: testDataFlowControlPolicy_userScope_update(name + "_update"), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name+"_update"), + resource.TestCheckResourceAttr(rName, "description", "description_update"), + resource.TestCheckResourceAttr(rName, "scope", "USER"), + resource.TestCheckResourceAttr(rName, "limit", "200"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDataFlowControlPolicy_channelScope(t *testing.T) { + var ( + obj model.ShowDeviceProxyResponse + name = acceptance.RandomAccResourceName() + rName = "huaweicloud_iotda_data_flow_control_policy.test" + ) + + rc := acceptance.InitResourceCheck( + rName, + &obj, + getDataFlowControlPolicyResourceFunc, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + // This resource only supports standard and enterprise version IoTDA instances. + acceptance.TestAccPreCheckHWIOTDAAccessAddress(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testDataFlowControlPolicy_channelScope(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "description", "description_test"), + resource.TestCheckResourceAttr(rName, "scope", "CHANNEL"), + resource.TestCheckResourceAttr(rName, "scope_value", "DMS_KAFKA_FORWARDING"), + resource.TestCheckResourceAttr(rName, "limit", "1000"), + ), + }, + { + Config: testDataFlowControlPolicy_channelScope_update(name + "_update"), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name+"_update"), + resource.TestCheckResourceAttr(rName, "description", "description_update"), + resource.TestCheckResourceAttr(rName, "scope", "CHANNEL"), + resource.TestCheckResourceAttr(rName, "scope_value", "DMS_KAFKA_FORWARDING"), + resource.TestCheckResourceAttr(rName, "limit", "200"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDataFlowControlPolicy_ruleScope(t *testing.T) { + var ( + obj model.ShowDeviceProxyResponse + name = acceptance.RandomAccResourceName() + rName = "huaweicloud_iotda_data_flow_control_policy.test" + ) + + rc := acceptance.InitResourceCheck( + rName, + &obj, + getDataFlowControlPolicyResourceFunc, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + // This resource only supports standard and enterprise version IoTDA instances. + acceptance.TestAccPreCheckHWIOTDAAccessAddress(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testDataFlowControlPolicy_ruleScope(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "description", "description_test"), + resource.TestCheckResourceAttr(rName, "scope", "RULE"), + resource.TestCheckResourceAttr(rName, "limit", "1000"), + resource.TestCheckResourceAttrPair(rName, "scope_value", + "huaweicloud_iotda_dataforwarding_rule.test", "id"), + ), + }, + { + Config: testDataFlowControlPolicy_ruleScope_update(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name+"_update"), + resource.TestCheckResourceAttr(rName, "description", "description_update"), + resource.TestCheckResourceAttr(rName, "scope", "RULE"), + resource.TestCheckResourceAttr(rName, "limit", "200"), + resource.TestCheckResourceAttrPair(rName, "scope_value", + "huaweicloud_iotda_dataforwarding_rule.test", "id"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDataFlowControlPolicy_actionScope(t *testing.T) { + var ( + obj model.ShowDeviceProxyResponse + name = acceptance.RandomAccResourceName() + rName = "huaweicloud_iotda_data_flow_control_policy.test" + ) + + rc := acceptance.InitResourceCheck( + rName, + &obj, + getDataFlowControlPolicyResourceFunc, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + // This resource only supports standard and enterprise version IoTDA instances. + acceptance.TestAccPreCheckHWIOTDAAccessAddress(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testDataFlowControlPolicy_actionScope(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "description", "description_test"), + resource.TestCheckResourceAttr(rName, "scope", "ACTION"), + resource.TestCheckResourceAttr(rName, "limit", "1000"), + resource.TestCheckResourceAttrPair(rName, "scope_value", + "huaweicloud_iotda_dataforwarding_rule.test", "targets.0.id"), + ), + }, + { + Config: testDataFlowControlPolicy_actionScope_update(name + "_update"), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name+"_update"), + resource.TestCheckResourceAttr(rName, "description", "description_update"), + resource.TestCheckResourceAttr(rName, "scope", "ACTION"), + resource.TestCheckResourceAttr(rName, "limit", "200"), + resource.TestCheckResourceAttrPair(rName, "scope_value", + "huaweicloud_iotda_dataforwarding_rule.test", "targets.0.id"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testDataFlowControlPolicy_userScope(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s" + description = "description_test" + scope = "USER" +} +`, buildIoTDAEndpoint(), name) +} + +func testDataFlowControlPolicy_userScope_update(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s" + description = "description_update" + scope = "USER" + limit = 200 +} +`, buildIoTDAEndpoint(), name) +} + +func testDataFlowControlPolicy_channelScope(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s" + description = "description_test" + scope = "CHANNEL" + scope_value = "DMS_KAFKA_FORWARDING" +} +`, buildIoTDAEndpoint(), name) +} + +func testDataFlowControlPolicy_channelScope_update(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s" + description = "description_update" + scope = "CHANNEL" + scope_value = "DMS_KAFKA_FORWARDING" + limit = 200 +} +`, buildIoTDAEndpoint(), name) +} + +func testDataFlowControlPolicy_ruleScope(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s" + description = "description_test" + scope = "RULE" + scope_value = huaweicloud_iotda_dataforwarding_rule.test.id +} +`, testDataForwardingRule_basic(name), name) +} + +func testDataFlowControlPolicy_ruleScope_update(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + name = "%[2]s_update" + description = "description_update" + scope = "RULE" + scope_value = huaweicloud_iotda_dataforwarding_rule.test.id + limit = 200 +} +`, testDataForwardingRule_basic(name), name) +} + +func testDataFlowControlPolicy_actionScope(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + depends_on = [ + huaweicloud_iotda_dataforwarding_rule.test + ] + + name = "%[2]s" + description = "description_test" + scope = "ACTION" + scope_value = [for target in huaweicloud_iotda_dataforwarding_rule.test.targets : target.id][0] +} +`, testDataForwardingRule_basic(name), name) +} + +func testDataFlowControlPolicy_actionScope_update(name string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_iotda_data_flow_control_policy" "test" { + depends_on = [ + huaweicloud_iotda_dataforwarding_rule.test + ] + + name = "%[2]s" + description = "description_update" + scope = "ACTION" + scope_value = [for target in huaweicloud_iotda_dataforwarding_rule.test.targets : target.id][0] + limit = 200 +} +`, testDataForwardingRule_basic(name), name) +} diff --git a/huaweicloud/services/iotda/resource_huaweicloud_iotda_data_flow_control_policy.go b/huaweicloud/services/iotda/resource_huaweicloud_iotda_data_flow_control_policy.go new file mode 100644 index 0000000000..483c926710 --- /dev/null +++ b/huaweicloud/services/iotda/resource_huaweicloud_iotda_data_flow_control_policy.go @@ -0,0 +1,202 @@ +package iotda + +import ( + "context" + + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iotda/v5/model" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/common" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// @API IoTDA POST /v5/iot/{project_id}/routing-rule/flowcontrol-policy +// @API IoTDA GET /v5/iot/{project_id}/routing-rule/flowcontrol-policy/{policy_id} +// @API IoTDA PUT /v5/iot/{project_id}/routing-rule/flowcontrol-policy/{policy_id} +// @API IoTDA DELETE /v5/iot/{project_id}/routing-rule/flowcontrol-policy/{policy_id} +func ResourceDataFlowControlPolicy() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceDataFlowControlPolicyCreate, + ReadContext: resourceDataFlowControlPolicyRead, + UpdateContext: resourceDataFlowControlPolicyUpdate, + DeleteContext: resourceDataFlowControlPolicyDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "scope": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + "scope_value": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + "limit": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + } +} + +func buildDataFlowControlPolicyCreateParams(d *schema.ResourceData) *model.CreateRoutingFlowControlPolicyRequest { + createOptsBody := model.AddFlowControlPolicy{ + PolicyName: utils.StringIgnoreEmpty(d.Get("name").(string)), + Description: utils.StringIgnoreEmpty(d.Get("description").(string)), + Scope: utils.StringIgnoreEmpty(d.Get("scope").(string)), + ScopeValue: utils.StringIgnoreEmpty(d.Get("scope_value").(string)), + //nolint:gosec + Limit: utils.Int32IgnoreEmpty(int32(d.Get("limit").(int))), + } + + return &model.CreateRoutingFlowControlPolicyRequest{ + Body: &createOptsBody, + } +} + +func resourceDataFlowControlPolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + isDerived = WithDerivedAuth(cfg, region) + ) + client, err := cfg.HcIoTdaV5Client(region, isDerived) + if err != nil { + return diag.Errorf("error creating IoTDA v5 client: %s", err) + } + + resp, err := client.CreateRoutingFlowControlPolicy(buildDataFlowControlPolicyCreateParams(d)) + if err != nil { + return diag.Errorf("error creating IoTDA data flow control policy: %s", err) + } + + if resp == nil || resp.PolicyId == nil { + return diag.Errorf("error creating IoTDA data flow control policy: ID is not found in API response") + } + + d.SetId(*resp.PolicyId) + + return resourceDataFlowControlPolicyRead(ctx, d, meta) +} + +func buildDataFlowControlPolicyQueryParams(d *schema.ResourceData) *model.ShowRoutingFlowControlPolicyRequest { + return &model.ShowRoutingFlowControlPolicyRequest{ + PolicyId: d.Id(), + } +} + +func resourceDataFlowControlPolicyRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + isDerived = WithDerivedAuth(cfg, region) + ) + client, err := cfg.HcIoTdaV5Client(region, isDerived) + if err != nil { + return diag.Errorf("error creating IoTDA v5 client: %s", err) + } + + resp, err := client.ShowRoutingFlowControlPolicy(buildDataFlowControlPolicyQueryParams(d)) + // When the resource does not exist, query API will return `404` error code. + if err != nil { + return common.CheckDeletedDiag(d, err, "error retrieving IoTDA data flow control policy") + } + + mErr := multierror.Append( + d.Set("region", region), + d.Set("name", resp.PolicyName), + d.Set("description", resp.Description), + d.Set("scope", resp.Scope), + d.Set("scope_value", resp.ScopeValue), + d.Set("limit", resp.Limit), + ) + + return diag.FromErr(mErr.ErrorOrNil()) +} + +func buildDataFlowControlPolicyUpdateParams(d *schema.ResourceData) *model.UpdateRoutingFlowControlPolicyRequest { + updateOptsBody := model.UpdateFlowControlPolicy{ + PolicyName: utils.StringIgnoreEmpty(d.Get("name").(string)), + Description: utils.StringIgnoreEmpty(d.Get("description").(string)), + //nolint:gosec + Limit: utils.Int32IgnoreEmpty(int32(d.Get("limit").(int))), + } + + return &model.UpdateRoutingFlowControlPolicyRequest{ + PolicyId: d.Id(), + Body: &updateOptsBody, + } +} + +func resourceDataFlowControlPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + isDerived = WithDerivedAuth(cfg, region) + ) + client, err := cfg.HcIoTdaV5Client(region, isDerived) + if err != nil { + return diag.Errorf("error creating IoTDA v5 client: %s", err) + } + + _, err = client.UpdateRoutingFlowControlPolicy(buildDataFlowControlPolicyUpdateParams(d)) + if err != nil { + return diag.Errorf("error updating IoTDA data flow control policy: %s", err) + } + + return resourceDataFlowControlPolicyRead(ctx, d, meta) +} + +func buildDataFlowControlPolicyDeleteParams(d *schema.ResourceData) *model.DeleteRoutingFlowControlPolicyRequest { + return &model.DeleteRoutingFlowControlPolicyRequest{ + PolicyId: d.Id(), + } +} + +func resourceDataFlowControlPolicyDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + isDerived = WithDerivedAuth(cfg, region) + ) + client, err := cfg.HcIoTdaV5Client(region, isDerived) + if err != nil { + return diag.Errorf("error creating IoTDA v5 client: %s", err) + } + + _, err = client.DeleteRoutingFlowControlPolicy(buildDataFlowControlPolicyDeleteParams(d)) + // When the resource does not exist, delete API will return `404` error code. + if err != nil { + return common.CheckDeletedDiag(d, err, "error deleting IoTDA data flow control policy") + } + + return nil +}