Skip to content

Commit b3d597d

Browse files
authored
feat: Ensure new common configurations from the file are applied (#5230)
After upgrading EdgeX, new configurations may be introduced. Ensure new configurations from the YAML file are pushed to the core-keeper. Signed-off-by: bruce <[email protected]>
1 parent 2885035 commit b3d597d

File tree

3 files changed

+49
-112
lines changed

3 files changed

+49
-112
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ go 1.23.7
55
require (
66
github.com/blang/semver/v4 v4.0.0
77
github.com/eclipse/paho.mqtt.golang v1.5.0
8-
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.30
9-
github.com/edgexfoundry/go-mod-configuration/v4 v4.1.0-dev.12
8+
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.31
109
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.1.0-dev.12
1110
github.com/edgexfoundry/go-mod-messaging/v4 v4.1.0-dev.13
1211
github.com/edgexfoundry/go-mod-secrets/v4 v4.1.0-dev.4
@@ -32,6 +31,7 @@ require (
3231
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
3332
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
3433
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
34+
github.com/edgexfoundry/go-mod-configuration/v4 v4.1.0-dev.12 // indirect
3535
github.com/edgexfoundry/go-mod-registry/v4 v4.1.0-dev.4 // indirect
3636
github.com/emirpasic/gods v1.18.1 // indirect
3737
github.com/fsnotify/fsnotify v1.9.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
7272
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7373
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
7474
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
75-
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.30 h1:3Onz1+oxAlRlMchjfL0bO+XTP63lMqmlpjobQNP8Bn0=
76-
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.30/go.mod h1:sQKOtdQlVuRzo06mDgNbJeyT/9QV94LlaY5wO1MsycU=
75+
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.31 h1:YTGd985lXEySEt76d/yXD8BaQAFOZFlBS7VfBJVLUIY=
76+
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.1.0-dev.31/go.mod h1:sQKOtdQlVuRzo06mDgNbJeyT/9QV94LlaY5wO1MsycU=
7777
github.com/edgexfoundry/go-mod-configuration/v4 v4.1.0-dev.12 h1:sW0dy9juPYPOwgwZAq1riDhJ96ivZBV9bdn+qWeeWO0=
7878
github.com/edgexfoundry/go-mod-configuration/v4 v4.1.0-dev.12/go.mod h1:8av7ex+XGeQHXQe/qyCdZ6g9AYWAYGRkkeFK0TKbiOQ=
7979
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.1.0-dev.12 h1:y5DmnfDWSzkil3n/mOM3geNlObQw59U75901R4s0a94=

internal/core/common_config/main.go

Lines changed: 45 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*******************************************************************************
22
* Copyright 2023 Intel Corporation
3+
* Copyright 2025 IOTech Ltd
34
*
45
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
56
* in compliance with the License. You may obtain a copy of the License at
@@ -17,25 +18,25 @@ package common_config
1718
import (
1819
"context"
1920
"fmt"
21+
"gopkg.in/yaml.v3"
2022
"net/http"
2123
"os"
2224
"os/signal"
23-
"sort"
2425
"sync"
2526
"syscall"
2627

2728
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/config"
2829
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/container"
2930
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/environment"
31+
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/file"
3032
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/flags"
33+
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/interfaces"
3134
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/secret"
3235
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/startup"
3336
"github.com/edgexfoundry/go-mod-bootstrap/v4/di"
34-
"github.com/edgexfoundry/go-mod-configuration/v4/configuration"
3537
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/logger"
3638
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
3739
"github.com/edgexfoundry/go-mod-core-contracts/v4/models"
38-
"gopkg.in/yaml.v3"
3940
)
4041

4142
const (
@@ -96,37 +97,39 @@ func Main(ctx context.Context, cancel context.CancelFunc, args []string) {
9697
os.Exit(1)
9798
}
9899

99-
hasConfig := false
100-
hasConfigSuccess := false
101-
for startupTimer.HasNotElapsed() {
102-
// check to see if the configuration exists in the config provider
103-
hasConfig, err = configClient.HasConfiguration()
104-
if err == nil {
105-
hasConfigSuccess = true
106-
break
107-
}
108-
109-
lc.Warnf("Unable to determine if common configuration exists in the provider, will try again: %v", err)
110-
startupTimer.SleepForInterval()
100+
// push not done flag to configClient
101+
err = configClient.PutConfigurationValue(commonConfigDone, []byte(common.ValueFalse))
102+
if err != nil {
103+
lc.Errorf("failed to push %s on startup: %s", commonConfigDone, err.Error())
104+
os.Exit(1)
111105
}
112106

113-
if !hasConfigSuccess {
114-
lc.Errorf("failed to determine if common configuration exists in the provider: %s", err.Error())
107+
yamlFile := config.GetConfigFileLocation(lc, f)
108+
lc.Infof("Using common configuration from %s", yamlFile)
109+
110+
configMap, err := loadConfigMapFromYamlFile(yamlFile, secretProvider, lc)
111+
if err != nil {
112+
lc.Errorf("Failed to load %s : %s", yamlFile, err.Error())
113+
os.Exit(1)
114+
}
115+
configMap, err = applyEnvOverrides(configMap, lc)
116+
if err != nil {
117+
lc.Errorf("Failed to apply env overrides to common configuration: %s", err.Error())
115118
os.Exit(1)
116119
}
117120

118-
// load the yaml file and push it using the config client
119-
if !hasConfig || getOverwriteConfig(f, lc) {
120-
lc.Info("Pushing common configuration. It doesn't exists or overwrite flag is set")
121+
// PutConfigurationMap func will check each keys and put the config value if not exist or override is set
122+
err = configClient.PutConfigurationMap(configMap, getOverwriteConfig(f, lc))
123+
if err != nil {
124+
lc.Errorf("Failed to put configuration: %s", err.Error())
125+
os.Exit(1)
126+
}
121127

122-
yamlFile := config.GetConfigFileLocation(lc, f)
123-
err = pushConfiguration(lc, yamlFile, configClient)
124-
if err != nil {
125-
lc.Error(err.Error())
126-
os.Exit(1)
127-
}
128-
} else {
129-
lc.Info("Skipped pushing common configuration. It already exists and overwrite flag not set")
128+
// push done flag to config client
129+
err = configClient.PutConfigurationValue(commonConfigDone, []byte(common.ValueTrue))
130+
if err != nil {
131+
lc.Errorf("Failed to push %s on completion: %s", commonConfigDone, err.Error())
132+
os.Exit(1)
130133
}
131134

132135
lc.Info("Core Common Config exiting")
@@ -155,96 +158,30 @@ func translateInterruptToCancel(ctx context.Context, wg *sync.WaitGroup, cancel
155158
}()
156159
}
157160

158-
func pushConfiguration(lc logger.LoggingClient, yamlFile string, configClient configuration.Client) error {
159-
// push not done flag to configClient
160-
err := configClient.PutConfigurationValue(commonConfigDone, []byte("false"))
161-
if err != nil {
162-
return fmt.Errorf("failed to push %s on startup: %s", commonConfigDone, err.Error())
163-
}
164-
lc.Infof("Using common configuration from %s", yamlFile)
165-
contents, err := os.ReadFile(yamlFile)
166-
if err != nil {
167-
return fmt.Errorf("failed to read common configuration file %s: %s", yamlFile, err.Error())
168-
}
169-
170-
data := make(map[string]interface{})
171-
kv := make(map[string]interface{})
172-
173-
err = yaml.Unmarshal(contents, &data)
174-
if err != nil {
175-
return fmt.Errorf("failed to unmarshall common configuration file %s: %s", yamlFile, err.Error())
176-
}
177-
178-
kv = buildKeyValues(data, kv, "")
179-
180-
kv, err = applyEnvOverrides(kv, lc)
181-
if err != nil {
182-
return fmt.Errorf("failed to apply env overrides to common configuration: %s", err.Error())
183-
}
184-
185-
keys := make([]string, 0, len(kv))
186-
187-
for k := range kv {
188-
keys = append(keys, k)
189-
}
190-
191-
sort.Strings(keys)
192-
193-
for _, k := range keys {
194-
v := kv[k]
195-
// Push key/value into Configuration Provider if it is not empty
196-
if v != nil {
197-
err = configClient.PutConfigurationValue(k, []byte(fmt.Sprint(v)))
198-
}
199-
if err != nil {
200-
return fmt.Errorf("failed to push common configuration key %s with value %v: %s", k, v, err.Error())
201-
}
202-
}
161+
func applyEnvOverrides(keyValues map[string]any, lc logger.LoggingClient) (map[string]any, error) {
162+
env := environment.NewVariables(lc)
203163

204-
// push done flag to config client
205-
err = configClient.PutConfigurationValue(commonConfigDone, []byte("true"))
164+
overrideCount, err := env.OverrideConfigMapValues(keyValues)
206165
if err != nil {
207-
return fmt.Errorf("failed to push %s on completion: %s", commonConfigDone, err.Error())
166+
return nil, err
208167
}
209168

210-
lc.Info("Common configuration has been pushed to into Configuration Provider with overrides applied")
169+
lc.Infof("Common configuration loaded from file with %d overrides applied", overrideCount)
211170

212-
return nil
171+
return keyValues, nil
213172
}
214173

215-
// buildKeyValues is a helper function to parse the configuration yaml file contents
216-
func buildKeyValues(data map[string]interface{}, kv map[string]interface{}, origKey string) map[string]interface{} {
217-
key := origKey
218-
for k, v := range data {
219-
if len(key) == 0 {
220-
key = fmt.Sprint(k)
221-
} else {
222-
key = fmt.Sprintf("%s/%s", key, k)
223-
}
224-
225-
vdata, ok := v.(map[string]interface{})
226-
if !ok {
227-
kv[key] = v
228-
key = origKey
229-
continue
230-
}
231-
232-
kv = buildKeyValues(vdata, kv, key)
233-
key = origKey
174+
func loadConfigMapFromYamlFile(yamlFile string, secretProvider interfaces.SecretProvider, lc logger.LoggingClient) (map[string]any, error) {
175+
contents, err := file.Load(yamlFile, secretProvider, lc)
176+
if err != nil {
177+
return nil, fmt.Errorf("failed to read configuration file %s: %s", yamlFile, err.Error())
234178
}
235179

236-
return kv
237-
}
238-
239-
func applyEnvOverrides(keyValues map[string]any, lc logger.LoggingClient) (map[string]any, error) {
240-
env := environment.NewVariables(lc)
180+
data := make(map[string]any)
241181

242-
overrideCount, err := env.OverrideConfigMapValues(keyValues)
182+
err = yaml.Unmarshal(contents, &data)
243183
if err != nil {
244-
return nil, err
184+
return nil, fmt.Errorf("failed to unmarshall yaml configuration: %s", err.Error())
245185
}
246-
247-
lc.Infof("Common configuration loaded from file with %d overrides applied", overrideCount)
248-
249-
return keyValues, nil
186+
return data, nil
250187
}

0 commit comments

Comments
 (0)