Skip to content

Commit 1e067f7

Browse files
authored
[Internal] Make Read after Create/Update configurable (#4190)
## Changes <!-- Summary of your changes that are easy to understand --> This PR adds the ability for a resource to specify that it may not need to call `Read` after `Create` and `Update` operations so we can avoid performing another API call(s). The resource may implement `CanSkipReadAfterCreateAndUpdate` function that can decide if the `Read` operation should be skipped. I decided to move common part from #4173 to make it easier to review ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [ ] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [x] relevant acceptance tests are passing - [ ] using Go SDK
1 parent 28b8f49 commit 1e067f7

File tree

2 files changed

+107
-11
lines changed

2 files changed

+107
-11
lines changed

common/resource.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ import (
1616

1717
// Resource aims to simplify things like error & deleted entities handling
1818
type Resource struct {
19-
Create func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
20-
Read func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
21-
Update func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
22-
Delete func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
23-
CustomizeDiff func(ctx context.Context, d *schema.ResourceDiff) error
24-
StateUpgraders []schema.StateUpgrader
25-
Schema map[string]*schema.Schema
26-
SchemaVersion int
27-
Timeouts *schema.ResourceTimeout
28-
DeprecationMessage string
29-
Importer *schema.ResourceImporter
19+
Create func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
20+
Read func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
21+
Update func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
22+
Delete func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error
23+
CustomizeDiff func(ctx context.Context, d *schema.ResourceDiff) error
24+
StateUpgraders []schema.StateUpgrader
25+
Schema map[string]*schema.Schema
26+
SchemaVersion int
27+
Timeouts *schema.ResourceTimeout
28+
DeprecationMessage string
29+
Importer *schema.ResourceImporter
30+
CanSkipReadAfterCreateAndUpdate func(d *schema.ResourceData) bool
3031
}
3132

3233
func nicerError(ctx context.Context, err error, action string) error {
@@ -94,6 +95,9 @@ func (r Resource) ToResource() *schema.Resource {
9495
err = nicerError(ctx, err, "update")
9596
return diag.FromErr(err)
9697
}
98+
if r.CanSkipReadAfterCreateAndUpdate != nil && r.CanSkipReadAfterCreateAndUpdate(d) {
99+
return nil
100+
}
97101
if err := recoverable(r.Read)(ctx, d, c); err != nil {
98102
err = nicerError(ctx, err, "read")
99103
return diag.FromErr(err)
@@ -162,6 +166,9 @@ func (r Resource) ToResource() *schema.Resource {
162166
err = nicerError(ctx, err, "create")
163167
return diag.FromErr(err)
164168
}
169+
if r.CanSkipReadAfterCreateAndUpdate != nil && r.CanSkipReadAfterCreateAndUpdate(d) {
170+
return nil
171+
}
165172
if err = recoverable(r.Read)(ctx, d, c); err != nil {
166173
err = nicerError(ctx, err, "read")
167174
return diag.FromErr(err)

common/resource_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package common
33
import (
44
"context"
55
"fmt"
6+
"log"
67
"testing"
78

89
"github.com/databricks/databricks-sdk-go/apierr"
@@ -38,6 +39,94 @@ func TestImportingCallsRead(t *testing.T) {
3839
assert.Equal(t, 1, d.Get("foo"))
3940
}
4041

42+
func createTestResourceForSkipRead(skipRead bool) Resource {
43+
res := Resource{
44+
Create: func(ctx context.Context,
45+
d *schema.ResourceData,
46+
c *DatabricksClient) error {
47+
log.Println("[DEBUG] Create called")
48+
return d.Set("foo", 1)
49+
},
50+
Read: func(ctx context.Context,
51+
d *schema.ResourceData,
52+
c *DatabricksClient) error {
53+
log.Println("[DEBUG] Read called")
54+
d.Set("foo", 2)
55+
return nil
56+
},
57+
Update: func(ctx context.Context,
58+
d *schema.ResourceData,
59+
c *DatabricksClient) error {
60+
log.Println("[DEBUG] Update called")
61+
return d.Set("foo", 3)
62+
},
63+
Schema: map[string]*schema.Schema{
64+
"foo": {
65+
Type: schema.TypeInt,
66+
Required: true,
67+
},
68+
},
69+
}
70+
if skipRead {
71+
res.CanSkipReadAfterCreateAndUpdate = func(d *schema.ResourceData) bool {
72+
return true
73+
}
74+
}
75+
return res
76+
}
77+
78+
func TestCreateSkipRead(t *testing.T) {
79+
client := &DatabricksClient{}
80+
ctx := context.Background()
81+
r := createTestResourceForSkipRead(true).ToResource()
82+
d := r.TestResourceData()
83+
diags := r.CreateContext(ctx, d, client)
84+
assert.False(t, diags.HasError())
85+
assert.Equal(t, 1, d.Get("foo"))
86+
}
87+
88+
func TestCreateDontSkipRead(t *testing.T) {
89+
client := &DatabricksClient{}
90+
ctx := context.Background()
91+
r := createTestResourceForSkipRead(false).ToResource()
92+
d := r.TestResourceData()
93+
diags := r.CreateContext(ctx, d, client)
94+
assert.False(t, diags.HasError())
95+
assert.Equal(t, 2, d.Get("foo"))
96+
}
97+
98+
func TestUpdateSkipRead(t *testing.T) {
99+
client := &DatabricksClient{}
100+
ctx := context.Background()
101+
r := createTestResourceForSkipRead(true).ToResource()
102+
d := r.TestResourceData()
103+
datas, err := r.Importer.StateContext(ctx, d, client)
104+
require.NoError(t, err)
105+
assert.Len(t, datas, 1)
106+
assert.False(t, r.Schema["foo"].ForceNew)
107+
assert.Equal(t, "", d.Id())
108+
109+
diags := r.UpdateContext(ctx, d, client)
110+
assert.False(t, diags.HasError())
111+
assert.Equal(t, 3, d.Get("foo"))
112+
}
113+
114+
func TestUpdateDontSkipRead(t *testing.T) {
115+
client := &DatabricksClient{}
116+
ctx := context.Background()
117+
r := createTestResourceForSkipRead(false).ToResource()
118+
d := r.TestResourceData()
119+
datas, err := r.Importer.StateContext(ctx, d, client)
120+
require.NoError(t, err)
121+
assert.Len(t, datas, 1)
122+
assert.False(t, r.Schema["foo"].ForceNew)
123+
assert.Equal(t, "", d.Id())
124+
125+
diags := r.UpdateContext(ctx, d, client)
126+
assert.False(t, diags.HasError())
127+
assert.Equal(t, 2, d.Get("foo"))
128+
}
129+
41130
func TestHTTP404TriggersResourceRemovalForReadAndDelete(t *testing.T) {
42131
nope := func(ctx context.Context,
43132
d *schema.ResourceData,

0 commit comments

Comments
 (0)