Skip to content

Commit

Permalink
Adds throughput support for Cosmos DB Mongo Collection (#4467)
Browse files Browse the repository at this point in the history
fixes #3586
  • Loading branch information
katbyte authored Oct 5, 2019
2 parents 7d06127 + 601d387 commit 0caed50
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
16 changes: 16 additions & 0 deletions azurerm/helpers/validate/cosmos.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ func CosmosEntityName(v interface{}, k string) (warnings []string, errors []erro

return warnings, errors
}

func CosmosThroughput(v interface{}, k string) (warnings []string, errors []error) {
value := v.(int)

if value < 400 {
errors = append(errors, fmt.Errorf(
"%s must be a minimum of 400", k))
}

if value%100 != 0 {
errors = append(errors, fmt.Errorf(
"%q must be set in increments of 100", k))
}

return warnings, errors
}
100 changes: 100 additions & 0 deletions azurerm/helpers/validate/cosmos_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package validate

import "testing"

func TestCosmosAccountName(t *testing.T) {
cases := []struct {
Value string
Errors int
}{
{
Value: "foo-bar",
Errors: 0,
},
{
Value: "foo",
Errors: 0,
},
{
Value: "fu",
Errors: 1,
},
{
Value: "foo_bar",
Errors: 1,
},
{
Value: "fooB@r",
Errors: 1,
},
{
Value: "foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar",
Errors: 1,
},
}

for _, tc := range cases {
_, errors := CosmosAccountName(tc.Value, "throughput")
if len(errors) != tc.Errors {
t.Fatalf("Expected CosmosAccountName to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors))
}
}
}

func TestCosmosEntityName(t *testing.T) {
cases := []struct {
Value string
Errors int
}{
{
Value: "",
Errors: 1,
},
{
Value: "someEntityName",
Errors: 0,
},
{
Value: "someEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityNamesomeEntityName",
Errors: 1,
},
}

for _, tc := range cases {
_, errors := CosmosEntityName(tc.Value, "throughput")
if len(errors) != tc.Errors {
t.Fatalf("Expected CosmosEntityName to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors))
}
}
}

func TestCosmosThroughput(t *testing.T) {
cases := []struct {
Value int
Errors int
}{
{
Value: 400,
Errors: 0,
},
{
Value: 300,
Errors: 1,
},
{
Value: 450,
Errors: 1,
},
{
Value: 10000,
Errors: 0,
},
}

for _, tc := range cases {
_, errors := CosmosThroughput(tc.Value, "throughput")
if len(errors) != tc.Errors {
t.Fatalf("Expected CosmosThroughput to trigger '%d' errors for '%d' - got '%d'", tc.Errors, tc.Value, len(errors))
}
}
}
34 changes: 34 additions & 0 deletions azurerm/resource_arm_cosmosdb_mongo_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource {
ValidateFunc: validation.IntAtLeast(-1),
},

"throughput": {
Type: schema.TypeInt,
Optional: true,
Default: 400,
ValidateFunc: validate.CosmosThroughput,
},

"indexes": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -100,6 +107,7 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta
resourceGroup := d.Get("resource_group_name").(string)
account := d.Get("account_name").(string)
database := d.Get("database_name").(string)
throughput := d.Get("throughput").(int)

if features.ShouldResourcesBeImported() && d.IsNewResource() {
existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name)
Expand Down Expand Up @@ -147,6 +155,23 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta
return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err)
}

throughputParameters := documentdb.ThroughputUpdateParameters{
ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{
Resource: &documentdb.ThroughputResource{
Throughput: utils.Int32(int32(throughput)),
},
},
}

throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, resourceGroup, account, database, name, throughputParameters)
if err != nil {
return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v", name, account, database, err)
}

if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err)
}

resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name)
if err != nil {
return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err)
Expand Down Expand Up @@ -205,6 +230,15 @@ func resourceArmCosmosDbMongoCollectionRead(d *schema.ResourceData, meta interfa
}
}

throughputResp, err := client.GetMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection)
if err != nil {
return fmt.Errorf("Error reading Throughput on Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err)
}

if throughput := throughputResp.Throughput; throughput != nil {
d.Set("throughput", int(*throughput))
}

return nil
}

Expand Down
5 changes: 5 additions & 0 deletions azurerm/resource_arm_cosmosdb_mongo_collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestAccAzureRMCosmosDbMongoCollection_complete(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "shard_key", "day"),
resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"),
resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"),
resource.TestCheckResourceAttr(resourceName, "throughput", "600"),
),
},
{
Expand Down Expand Up @@ -84,6 +85,7 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "shard_key", "day"),
resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"),
resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"),
resource.TestCheckResourceAttr(resourceName, "throughput", "600"),
),
},
{
Expand All @@ -97,6 +99,7 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) {
testCheckAzureRMCosmosDbMongoCollectionExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "70707"),
resource.TestCheckResourceAttr(resourceName, "indexes.#", "3"),
resource.TestCheckResourceAttr(resourceName, "throughput", "400"),
),
},
{
Expand Down Expand Up @@ -191,6 +194,7 @@ resource "azurerm_cosmosdb_mongo_collection" "test" {
default_ttl_seconds = 707
shard_key = "day"
throughput = 600
indexes {
key = "seven"
Expand All @@ -216,6 +220,7 @@ resource "azurerm_cosmosdb_mongo_collection" "test" {
database_name = "${azurerm_cosmosdb_mongo_database.test.name}"
default_ttl_seconds = 70707
throughput = 400
indexes {
key = "seven"
Expand Down
4 changes: 3 additions & 1 deletion website/docs/r/cosmosdb_mongo_collection.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ resource "azurerm_cosmosdb_mongo_collection" "example" {
default_ttl_seconds = "777"
shard_key = "uniqueKey"
throughput = 400
indexes {
key = "aKey"
Expand All @@ -53,7 +54,8 @@ The following arguments are supported:
* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created.
* `database_name` - (Required) The name of the Cosmos DB Mongo Database in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created.
* `default_ttl_seconds` - (Required) The default Time To Live in seconds. If the value is `-1` items are not automatically expired.
* `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys.
* `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys.
* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The default and minimum value is `400`.
* `indexes` - (Optional) One or more `indexes` blocks as defined below.

---
Expand Down

0 comments on commit 0caed50

Please sign in to comment.