Skip to content

Commit 2c2bb68

Browse files
Terraform Team AutomationNagendraNigade
authored andcommitted
Added - Support for Add MR table feature into Oracle NoSQL Database Cloud
1 parent 9c90602 commit 2c2bb68

File tree

12 files changed

+827
-0
lines changed

12 files changed

+827
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
variable "tenancy_ocid" {
5+
}
6+
7+
variable "user_ocid" {
8+
}
9+
10+
variable "fingerprint" {
11+
}
12+
13+
variable "private_key_path" {
14+
}
15+
16+
variable "region" {
17+
}
18+
19+
variable "compartment_ocid" {
20+
}
21+
22+
variable "table_ddl_statement" {
23+
default = "CREATE TABLE IF NOT EXISTS test_mrtable(id INTEGER, name STRING, info JSON, PRIMARY KEY(id)) with schema frozen"
24+
}
25+
26+
provider "oci" {
27+
tenancy_ocid = var.tenancy_ocid
28+
user_ocid = var.user_ocid
29+
fingerprint = var.fingerprint
30+
private_key_path = var.private_key_path
31+
region = var.region
32+
}
33+
34+
resource "oci_nosql_table" "test_mrtable" {
35+
#Required
36+
compartment_id = var.compartment_ocid
37+
ddl_statement = var.table_ddl_statement
38+
name = "test_mrtable"
39+
40+
table_limits {
41+
#Required
42+
max_read_units = "50"
43+
max_write_units = "50"
44+
max_storage_in_gbs = "1"
45+
}
46+
}
47+
48+
resource "oci_nosql_table_replica" "replica_yul" {
49+
table_name_or_id = oci_nosql_table.test_mrtable.id
50+
region = "ca-montreal-1"
51+
52+
#Optional
53+
max_read_units = "60"
54+
max_write_units = "60"
55+
}
56+
57+
data "oci_nosql_table" "get_test_mrtable" {
58+
compartment_id = var.compartment_ocid
59+
table_name_or_id = oci_nosql_table.test_mrtable.id
60+
61+
depends_on = [oci_nosql_table_replica.replica_yul]
62+
}
63+
64+
output "test_mrtable_replicas" {
65+
value = [
66+
data.oci_nosql_table.get_test_mrtable.replicas
67+
]
68+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package integrationtest
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"strconv"
10+
"testing"
11+
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
14+
15+
"github.com/oracle/oci-go-sdk/v65/common"
16+
oci_nosql "github.com/oracle/oci-go-sdk/v65/nosql"
17+
"github.com/oracle/terraform-provider-oci/httpreplay"
18+
"github.com/oracle/terraform-provider-oci/internal/acctest"
19+
tf_client "github.com/oracle/terraform-provider-oci/internal/client"
20+
"github.com/oracle/terraform-provider-oci/internal/resourcediscovery"
21+
"github.com/oracle/terraform-provider-oci/internal/tfresource"
22+
"github.com/oracle/terraform-provider-oci/internal/utils"
23+
)
24+
25+
var (
26+
NosqlTableReplicaRequiredOnlyResource = NosqlTableReplicaResourceDependencies +
27+
acctest.GenerateResourceFromRepresentationMap("oci_nosql_table_replica", "test_table_replica", acctest.Required, acctest.Create, NosqlTableReplicaRepresentation)
28+
29+
NosqlTableReplicaRepresentation = map[string]interface{}{
30+
"region": acctest.Representation{RepType: acctest.Required, Create: `ca-montreal-1`},
31+
"table_name_or_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_nosql_table.test_mr_table.id}`},
32+
"compartment_id": acctest.Representation{RepType: acctest.Optional, Create: `${var.compartment_id}`},
33+
"max_read_units": acctest.Representation{RepType: acctest.Optional, Create: `11`},
34+
"max_write_units": acctest.Representation{RepType: acctest.Optional, Create: `11`},
35+
}
36+
37+
mrtable_ddl = "CREATE TABLE IF NOT EXISTS test_mr_table(id integer, info JSON, PRIMARY KEY(id)) WITH SCHEMA FROZEN"
38+
mrTableLimitsRepresentation = map[string]interface{}{
39+
"max_read_units": acctest.Representation{RepType: acctest.Required, Create: `10`},
40+
"max_write_units": acctest.Representation{RepType: acctest.Required, Create: `10`},
41+
"max_storage_in_gbs": acctest.Representation{RepType: acctest.Required, Create: `1`},
42+
}
43+
mrTableRepresentation = map[string]interface{}{
44+
"compartment_id": acctest.Representation{RepType: acctest.Required, Create: `${var.compartment_id}`},
45+
"ddl_statement": acctest.Representation{RepType: acctest.Required, Create: mrtable_ddl},
46+
"name": acctest.Representation{RepType: acctest.Required, Create: "test_mr_table"},
47+
"table_limits": acctest.RepresentationGroup{RepType: acctest.Required, Group: mrTableLimitsRepresentation},
48+
"lifecycle": acctest.RepresentationGroup{RepType: acctest.Required, Group: ignoreTableDefinedTags},
49+
}
50+
NosqlTableReplicaResourceDependencies = acctest.GenerateResourceFromRepresentationMap("oci_nosql_table", "test_mr_table", acctest.Required, acctest.Create, mrTableRepresentation)
51+
)
52+
53+
// issue-routing-tag: nosql/default
54+
func TestNosqlTableReplicaResource_basic(t *testing.T) {
55+
httpreplay.SetScenario("TestNosqlTableReplicaResource_basic")
56+
defer httpreplay.SaveScenario()
57+
58+
config := acctest.ProviderTestConfig()
59+
60+
compartmentId := utils.GetEnvSettingWithBlankDefault("compartment_ocid")
61+
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
62+
63+
resourceName := "oci_nosql_table_replica.test_table_replica"
64+
65+
var resId string
66+
// Save TF content to Create resource with optional properties. This has to be exactly the same as the config part in the "create with optionals" step in the test.
67+
acctest.SaveConfigContent(config+compartmentIdVariableStr+NosqlTableReplicaResourceDependencies+
68+
acctest.GenerateResourceFromRepresentationMap("oci_nosql_table_replica", "test_table_replica", acctest.Optional, acctest.Create, NosqlTableReplicaRepresentation), "nosql", "tableReplica", t)
69+
70+
acctest.ResourceTest(t, testAccCheckNosqlTableReplicaDestroy, []resource.TestStep{
71+
// verify Create
72+
{
73+
Config: config + compartmentIdVariableStr + NosqlTableReplicaResourceDependencies +
74+
acctest.GenerateResourceFromRepresentationMap("oci_nosql_table_replica", "test_table_replica", acctest.Required, acctest.Create, NosqlTableReplicaRepresentation),
75+
Check: acctest.ComposeAggregateTestCheckFuncWrapper(
76+
resource.TestCheckResourceAttr(resourceName, "region", "ca-montreal-1"),
77+
resource.TestCheckResourceAttrSet(resourceName, "table_name_or_id"),
78+
),
79+
},
80+
81+
// delete before next Create
82+
{
83+
Config: config + compartmentIdVariableStr + NosqlTableReplicaResourceDependencies,
84+
},
85+
// verify Create with optionals
86+
{
87+
Config: config + compartmentIdVariableStr + NosqlTableReplicaResourceDependencies +
88+
acctest.GenerateResourceFromRepresentationMap("oci_nosql_table_replica", "test_table_replica", acctest.Optional, acctest.Create, NosqlTableReplicaRepresentation),
89+
Check: acctest.ComposeAggregateTestCheckFuncWrapper(
90+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
91+
resource.TestCheckResourceAttr(resourceName, "max_read_units", "11"),
92+
resource.TestCheckResourceAttr(resourceName, "max_write_units", "11"),
93+
resource.TestCheckResourceAttr(resourceName, "region", "ca-montreal-1"),
94+
resource.TestCheckResourceAttrSet(resourceName, "table_name_or_id"),
95+
96+
func(s *terraform.State) (err error) {
97+
resId, err = acctest.FromInstanceState(s, resourceName, "id")
98+
if isEnableExportCompartment, _ := strconv.ParseBool(utils.GetEnvSettingWithDefault("enable_export_compartment", "true")); isEnableExportCompartment {
99+
if errExport := resourcediscovery.TestExportCompartmentWithResourceName(&resId, &compartmentId, resourceName); errExport != nil {
100+
return errExport
101+
}
102+
}
103+
return err
104+
},
105+
),
106+
},
107+
})
108+
}
109+
110+
func testAccCheckNosqlTableReplicaDestroy(s *terraform.State) error {
111+
noResourceFound := true
112+
client := acctest.TestAccProvider.Meta().(*tf_client.OracleClients).NosqlClient()
113+
for _, rs := range s.RootModule().Resources {
114+
if rs.Type == "oci_nosql_table_replica" {
115+
116+
noResourceFound = false
117+
118+
request := oci_nosql.GetTableRequest{}
119+
120+
if value, ok := rs.Primary.Attributes["compartment_id"]; ok {
121+
request.CompartmentId = &value
122+
}
123+
if value, ok := rs.Primary.Attributes["table_name_or_id"]; ok {
124+
request.TableNameOrId = &value
125+
}
126+
127+
request.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(true, "nosql")
128+
response, err := client.GetTable(context.Background(), request)
129+
130+
if err == nil {
131+
deletedLifecycleStates := map[string]bool{
132+
string(oci_nosql.TableLifecycleStateDeleted): true,
133+
}
134+
if _, ok := deletedLifecycleStates[string(response.LifecycleState)]; !ok {
135+
//resource lifecycle state is not in expected deleted lifecycle states.
136+
return fmt.Errorf("resource lifecycle state: %s is not in expected deleted lifecycle states", response.LifecycleState)
137+
}
138+
//resource lifecycle state is in expected deleted lifecycle states. continue with next one.
139+
continue
140+
}
141+
142+
//Verify that exception is for '404 not found'.
143+
if failure, isServiceError := common.IsServiceError(err); !isServiceError || failure.GetHTTPStatusCode() != 404 {
144+
return err
145+
}
146+
}
147+
}
148+
149+
if noResourceFound {
150+
return fmt.Errorf("at least one resource was expected from the state file, but could not be found")
151+
}
152+
return nil
153+
}

internal/integrationtest/nosql_table_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,11 @@ func TestNosqlTableResource_basic(t *testing.T) {
227227
resource.TestCheckResourceAttr(singularDatasourceName, "freeform_tags.%", "1"),
228228
resource.TestCheckResourceAttrSet(singularDatasourceName, "id"),
229229
resource.TestCheckResourceAttr(singularDatasourceName, "is_auto_reclaimable", "false"),
230+
resource.TestCheckResourceAttrSet(singularDatasourceName, "is_multi_region"),
230231
resource.TestCheckResourceAttr(singularDatasourceName, "name", "test_table"),
232+
resource.TestCheckResourceAttr(singularDatasourceName, "replicas.#", "0"),
231233
resource.TestCheckResourceAttr(singularDatasourceName, "schema.#", "1"),
234+
resource.TestCheckResourceAttrSet(singularDatasourceName, "schema_state"),
232235
resource.TestCheckResourceAttr(singularDatasourceName, "schema.0.identity.#", "1"),
233236
resource.TestCheckResourceAttr(singularDatasourceName, "schema.0.identity.0.column_name", "id"),
234237
resource.TestCheckResourceAttr(singularDatasourceName, "schema.0.identity.0.is_always", "true"),

internal/service/nosql/nosql_export.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ var exportNosqlIndexHints = &tf_export.TerraformResourceHints{
5858
},
5959
}
6060

61+
var exportNosqlTableReplicaHints = &tf_export.TerraformResourceHints{
62+
ResourceClass: "oci_nosql_table_replica",
63+
ResourceAbbreviation: "table_replica",
64+
}
65+
6166
var nosqlResourceGraph = tf_export.TerraformResourceGraph{
6267
"oci_identity_compartment": {
6368
{TerraformResourceHints: exportNosqlTableHints},

internal/service/nosql/nosql_table_data_source.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,36 @@ func (s *NosqlTableDataSourceCrud) SetData() error {
9393
s.D.Set("is_auto_reclaimable", *s.Res.IsAutoReclaimable)
9494
}
9595

96+
if s.Res.IsMultiRegion != nil {
97+
s.D.Set("is_multi_region", *s.Res.IsMultiRegion)
98+
}
99+
96100
if s.Res.LifecycleDetails != nil {
97101
s.D.Set("lifecycle_details", *s.Res.LifecycleDetails)
98102
}
99103

104+
if s.Res.LocalReplicaInitializationInPercent != nil {
105+
s.D.Set("local_replica_initialization_in_percent", *s.Res.LocalReplicaInitializationInPercent)
106+
}
107+
100108
if s.Res.Name != nil {
101109
s.D.Set("name", *s.Res.Name)
102110
}
103111

112+
replicas := []interface{}{}
113+
for _, item := range s.Res.Replicas {
114+
replicas = append(replicas, ReplicaToMap(item))
115+
}
116+
s.D.Set("replicas", replicas)
117+
104118
if s.Res.Schema != nil {
105119
s.D.Set("schema", []interface{}{SchemaToMap(s.Res.Schema)})
106120
} else {
107121
s.D.Set("schema", nil)
108122
}
109123

124+
s.D.Set("schema_state", s.Res.SchemaState)
125+
110126
s.D.Set("state", s.Res.LifecycleState)
111127

112128
if s.Res.SystemTags != nil {

0 commit comments

Comments
 (0)