Skip to content

Commit 7ba0abe

Browse files
authored
DGS-19519 Enhance error handling for CSFLE configure method (#1379)
* Enhance error handling for CSFLE configure method * Add test * Minor cleanup * Minor fix
1 parent 8d9a0db commit 7ba0abe

File tree

4 files changed

+134
-5
lines changed

4 files changed

+134
-5
lines changed

schemaregistry/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,8 @@ func NewConfigWithBearerAuthentication(url, token, targetSr, identityPoolID stri
8888

8989
return c
9090
}
91+
92+
// ConfigsEqual compares two configurations for approximate equality
93+
func ConfigsEqual(c1 *Config, c2 *Config) bool {
94+
return internal.ConfigsEqual(&c1.ClientConfig, &c2.ClientConfig)
95+
}

schemaregistry/internal/client_config.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,21 @@ type ClientConfig struct {
7474
// HTTP client
7575
HTTPClient *http.Client
7676
}
77+
78+
// ConfigsEqual compares two configurations for approximate equality
79+
func ConfigsEqual(c1 *ClientConfig, c2 *ClientConfig) bool {
80+
return c1.SchemaRegistryURL == c2.SchemaRegistryURL &&
81+
c1.BasicAuthUserInfo == c2.BasicAuthUserInfo &&
82+
c1.BasicAuthCredentialsSource == c2.BasicAuthCredentialsSource &&
83+
c1.SaslMechanism == c2.SaslMechanism &&
84+
c1.SaslUsername == c2.SaslUsername &&
85+
c1.SaslPassword == c2.SaslPassword &&
86+
c1.BearerAuthToken == c2.BearerAuthToken &&
87+
c1.BearerAuthCredentialsSource == c2.BearerAuthCredentialsSource &&
88+
c1.BearerAuthLogicalCluster == c2.BearerAuthLogicalCluster &&
89+
c1.BearerAuthIdentityPoolID == c2.BearerAuthIdentityPoolID &&
90+
c1.SslCertificateLocation == c2.SslCertificateLocation &&
91+
c1.SslKeyLocation == c2.SslKeyLocation &&
92+
c1.SslCaLocation == c2.SslCaLocation &&
93+
c1.SslDisableEndpointVerification == c2.SslDisableEndpointVerification
94+
}

schemaregistry/rules/encryption/encrypt_executor.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,32 @@ type FieldEncryptionExecutor struct {
110110

111111
// Configure configures the executor
112112
func (f *FieldEncryptionExecutor) Configure(clientConfig *schemaregistry.Config, config map[string]string) error {
113-
client, err := deks.NewClient(clientConfig)
114-
if err != nil {
115-
return err
113+
if f.Client != nil {
114+
if !schemaregistry.ConfigsEqual(f.Client.Config(), clientConfig) {
115+
return errors.New("executor already configured")
116+
}
117+
} else {
118+
client, err := deks.NewClient(clientConfig)
119+
if err != nil {
120+
return err
121+
}
122+
f.Client = client
123+
}
124+
125+
if f.Config != nil {
126+
for key, value := range config {
127+
v, ok := f.Config[key]
128+
if ok {
129+
if v != value {
130+
return fmt.Errorf("rule config key already set: %s", key)
131+
}
132+
} else {
133+
f.Config[key] = value
134+
}
135+
}
136+
} else {
137+
f.Config = config
116138
}
117-
f.Config = config
118-
f.Client = client
119139
return nil
120140
}
121141

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright 2024 Confluent Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package encryption
18+
19+
import (
20+
"fmt"
21+
"reflect"
22+
"runtime"
23+
"testing"
24+
25+
"github.com/confluentinc/confluent-kafka-go/v2/schemaregistry"
26+
)
27+
28+
func TestFieldEncryptionExecutor_Configure(t *testing.T) {
29+
maybeFail = initFailFunc(t)
30+
31+
executor := NewExecutor()
32+
clientConfig := schemaregistry.NewConfig("mock://")
33+
config := map[string]string{
34+
"key": "value",
35+
}
36+
err := executor.Configure(clientConfig, config)
37+
maybeFail(err)
38+
// configure with same args is fine
39+
err = executor.Configure(clientConfig, config)
40+
maybeFail(err)
41+
config2 := map[string]string{
42+
"key2": "value2",
43+
}
44+
// configure with additional config keys is fine
45+
err = executor.Configure(clientConfig, config2)
46+
maybeFail(err)
47+
48+
clientConfig2 := schemaregistry.NewConfig("mock://")
49+
clientConfig2.BasicAuthUserInfo = "foo"
50+
err = executor.Configure(clientConfig2, config)
51+
maybeFail(expect(err != nil, true))
52+
53+
config3 := map[string]string{
54+
"key": "value2",
55+
}
56+
err = executor.Configure(clientConfig, config3)
57+
maybeFail(expect(err != nil, true))
58+
}
59+
60+
type failFunc func(...error)
61+
62+
var maybeFail failFunc
63+
64+
func initFailFunc(t *testing.T) failFunc {
65+
tester := t
66+
return func(errors ...error) {
67+
for _, err := range errors {
68+
if err != nil {
69+
pc := make([]uintptr, 1)
70+
runtime.Callers(2, pc)
71+
caller := runtime.FuncForPC(pc[0])
72+
_, line := caller.FileLine(caller.Entry())
73+
74+
tester.Fatalf("%s:%d failed: %s", caller.Name(), line, err)
75+
}
76+
}
77+
}
78+
}
79+
80+
func expect(actual, expected interface{}) error {
81+
if !reflect.DeepEqual(actual, expected) {
82+
return fmt.Errorf("expected: %v, Actual: %v", expected, actual)
83+
}
84+
85+
return nil
86+
}

0 commit comments

Comments
 (0)