Skip to content

Commit

Permalink
Simplify Loading of Service Client Configuration from External Sources
Browse files Browse the repository at this point in the history
  • Loading branch information
skmcgrail committed Jan 27, 2020
1 parent 9503cfa commit 3142e27
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 21 deletions.
5 changes: 3 additions & 2 deletions aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ type Config struct {
// for testing that do not support the modeled host prefix pattern.
DisableEndpointHostPrefix bool

// ConfigResolver defines how additional configuration can be loaded by clients.
AdditionalConfig ConfigResolver
// ConfigSources are the sources that were used to the aws.Config.
// Allows for additional configuration can be loaded by clients.
ConfigSources []interface{}
}

// ConfigResolver is an interface that encapsulates the behavior of loading
Expand Down
6 changes: 6 additions & 0 deletions aws/external/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ func (cs Configs) ResolveAWSConfig(resolvers []AWSConfigResolver) (aws.Config, e
}
}

var sources []interface{}
for _, s := range cs {
sources = append(sources, s)
}
cfg.ConfigSources = sources

return cfg, nil
}

Expand Down
15 changes: 13 additions & 2 deletions aws/external/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ func TestConfigs_AppendFromLoaders(t *testing.T) {
}

func TestConfigs_ResolveAWSConfig(t *testing.T) {
cfg, err := Configs{
configSources := Configs{
WithRegion("mock-region"),
WithCredentialsValue(aws.Credentials{
AccessKeyID: "AKID", SecretAccessKey: "SECRET",
Source: "provider",
}),
}.ResolveAWSConfig([]AWSConfigResolver{
}

cfg, err := configSources.ResolveAWSConfig([]AWSConfigResolver{
ResolveRegion,
ResolveCredentialsValue,
})
Expand All @@ -101,4 +103,13 @@ func TestConfigs_ResolveAWSConfig(t *testing.T) {
if e, a := "provider", creds.Source; e != a {
t.Errorf("expect %v provider, got %v", e, a)
}

var expectedSources []interface{}
for _, s := range cfg.ConfigSources {
expectedSources = append(expectedSources, s)
}

if e, a := expectedSources, cfg.ConfigSources; !reflect.DeepEqual(e, a) {
t.Errorf("expected %v, got %v", e, a)
}
}
34 changes: 17 additions & 17 deletions private/model/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,10 +694,8 @@ func New(config aws.Config) *{{ .StructName }} {
}
{{ if .HasExternalClientConfigFields }}
if config.AdditionalConfig != nil {
if err := config.AdditionalConfig.ResolveConfig(resolveClientConfig(svc)); err != nil {
panic(fmt.Errorf("failed to resolve service configuration: %v", err))
}
if err := resolveClientConfig(svc, config.ConfigSources); err != nil {
panic(fmt.Errorf("failed to resolve service configuration: %v", err))
}
{{- end }}
Expand Down Expand Up @@ -1125,18 +1123,20 @@ func (a *API) hasNonIOShapes() bool {
var tplClientConfig = template.Must(template.New("tplClientConfig").Funcs(map[string]interface{}{
"ExternalConfigFields": externalConfigFields,
}).Parse(`
func resolveClientConfig(svc *{{ .StructName }}) func(configs []interface{}) error {
return func(configs []interface{}) error {
{{- $fields := ExternalConfigFields . -}}
{{- range $idx, $field := $fields }}
if value, ok, err := {{ $.InternalConfigResolverPackageName }}.{{ $field.ExternalConfigResolverName }}(configs); err != nil {
return err
} else if ok {
svc.{{ $field.Name }} = value
}
{{ end }}
func resolveClientConfig(svc *{{ .StructName }}, configs []interface{}) error {
if len(configs) == 0 {
return nil
}
{{ $fields := ExternalConfigFields . -}}
{{- range $idx, $field := $fields }}
if value, ok, err := {{ $.InternalConfigResolverPackageName }}.{{ $field.ExternalConfigResolverName }}(configs); err != nil {
return err
} else if ok {
svc.{{ $field.Name }} = value
}
{{ end }}
return nil
}
`))

Expand Down Expand Up @@ -1183,7 +1183,7 @@ func TestExternalConfigResolver(t *testing.T) {
t.Run("{{ $field.Name }}", func(t *testing.T) {
t.Run("value not found", func(t *testing.T) {
svc := &{{ $.StructName }}{}
err := resolveClientConfig(svc)([]interface{}{
err := resolveClientConfig(svc, []interface{}{
mock{{ $field.Name }}(func() (value {{ $field.Type }}, ok bool, err error) {
return value, ok, err
}),
Expand All @@ -1197,7 +1197,7 @@ func TestExternalConfigResolver(t *testing.T) {
})
t.Run("resolve error", func(t *testing.T) {
svc := &{{ $.StructName }}{}
err := resolveClientConfig(svc)([]interface{}{
err := resolveClientConfig(svc, []interface{}{
mock{{ $field.Name }}(func() (value {{ $field.Type }}, ok bool, err error) {
err = fmt.Errorf("resolve error")
return value, ok, err
Expand All @@ -1213,7 +1213,7 @@ func TestExternalConfigResolver(t *testing.T) {
t.Run("value found", func(t *testing.T) {
{{- $mockValue := MockConfigFieldValue $field -}}
svc := &{{ $.StructName }}{}
err := resolveClientConfig(svc)([]interface{}{
err := resolveClientConfig(svc, []interface{}{
mock{{ $field.Name }}(func() (value {{ $field.Type }}, ok bool, err error) {
value = {{ $mockValue }}
return value, true, err
Expand Down

0 comments on commit 3142e27

Please sign in to comment.