@@ -18,6 +18,7 @@ import (
1818
1919 "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
2020 "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging"
21+ "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/hash"
2122 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services"
2223 viperutil "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/config/viper"
2324 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events"
@@ -45,7 +46,6 @@ type OnMergeConfigEventHandler interface {
4546type DecodeHookFuncType func (reflect.Type , reflect.Type , interface {}) (interface {}, error )
4647
4748type Provider struct {
48- confPath string
4949 Backend * viper.Viper
5050 eventSystem events.EventSystem
5151
@@ -54,10 +54,9 @@ type Provider struct {
5454
5555func NewProvider (confPath string ) (* Provider , error ) {
5656 p := & Provider {
57- confPath : confPath ,
5857 eventSystem : simple .NewEventBus (),
5958 }
60- if err := p .load ( ); err != nil {
59+ if err := p .loadFromPath ( confPath ); err != nil {
6160 return nil , err
6261 }
6362
@@ -151,15 +150,31 @@ func (p *Provider) OnMergeConfig(handler OnMergeConfigEventHandler) {
151150 p .eventSystem .Subscribe (MergeConfigEventTopic , & eventListener {handler : handler })
152151}
153152
154- func (p * Provider ) load () error {
153+ // ProvideFromRaw returns a new Provider whose configuration is loaded from the given byte representation.
154+ // The function expects a valid `yaml` representation.
155+ // The new provider inherit the same config file used by this provider.
156+ func (p * Provider ) ProvideFromRaw (raw []byte ) (* Provider , error ) {
157+ newProvider := & Provider {
158+ eventSystem : simple .NewEventBus (),
159+ }
160+ if err := newProvider .loadFromRaw (raw ); err != nil {
161+ return nil , err
162+ }
163+ newProvider .Backend .SetConfigFile (p .ConfigFileUsed ())
164+
165+ return newProvider , nil
166+ }
167+
168+ func (p * Provider ) loadFromPath (path string ) error {
155169 p .Backend = viper .New ()
156- err := p .initViper (p .Backend , CmdRoot )
170+ err := p .initViper (p .Backend , CmdRoot , path )
157171 if err != nil {
158172 return err
159173 }
160174
161175 err = p .Backend .ReadInConfig () // Find and read the config file
162- if err != nil { // Handle errors reading the config file
176+ if err != nil {
177+ // Handle errors reading the config file
163178 // The version of Viper we use claims the config type isn't supported when in fact the file hasn't been found
164179 // Display a more helpful message to avoid confusing the user.
165180 if strings .Contains (fmt .Sprint (err ), "Unsupported Config Type" ) {
@@ -185,6 +200,22 @@ func (p *Provider) load() error {
185200 return nil
186201}
187202
203+ func (p * Provider ) loadFromRaw (raw []byte ) error {
204+ p .Backend = viper .New ()
205+ p .Backend .SetConfigType ("yaml" )
206+
207+ // read configuration
208+ if err := p .Backend .ReadConfig (bytes .NewReader (raw )); err != nil {
209+ return errors .Wrapf (err , "failed to read configuration from raw [%s]" , hash .Hashable (raw ))
210+ }
211+ // post process
212+ if err := p .substituteEnv (); err != nil {
213+ return err
214+ }
215+
216+ return nil
217+ }
218+
188219// Manually override keys if the respective environment variable is set, because viper doesn't do
189220// that for UnmarshalKey values (see https://github.com/spf13/viper/pull/1699).
190221// Example: CORE_LOGGING_FORMAT sets logging.format.
@@ -260,9 +291,9 @@ func setDeepValue(m map[string]any, keys []string, value any) error {
260291// the configuration we need. If Backend == nil, we will initialize the global
261292// Viper instance
262293// ----------------------------------------------------------------------------------
263- func (p * Provider ) initViper (v * viper.Viper , configName string ) error {
264- if len (p . confPath ) != 0 {
265- AddConfigPath (v , p . confPath )
294+ func (p * Provider ) initViper (v * viper.Viper , configName string , confPath string ) error {
295+ if len (confPath ) != 0 {
296+ AddConfigPath (v , confPath )
266297 }
267298
268299 var altPath = os .Getenv ("FSCNODE_CFG_PATH" )
0 commit comments