/
app_config.go
89 lines (72 loc) · 2.05 KB
/
app_config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package appconfig
import (
"context"
"errors"
"strings"
"sync/atomic"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/appconfigdata"
"github.com/aws/aws-sdk-go-v2/service/appconfigdata/types"
"github.com/ln80/event-store/control"
)
type LoaderConfig struct {
Application string
Configuration string
Environment string
MinimumPollInterval time.Duration
}
func (lc LoaderConfig) IsZero() bool {
return lc == LoaderConfig{}
}
type Loader struct {
api ClientAPI
cfg *LoaderConfig
input atomic.Value // appconfigdata.GetLatestConfigurationInput
}
var _ control.Loader = &Loader{}
func NewLoader(ctx context.Context, api ClientAPI, opts ...func(*LoaderConfig)) (*Loader, error) {
l := &Loader{
api: api,
cfg: &LoaderConfig{
MinimumPollInterval: 25 * time.Second,
},
}
for _, opt := range opts {
if opt == nil {
continue
}
opt(l.cfg)
}
if l.cfg.IsZero() {
return nil, errors.New("empty appconfig loader parameters")
}
out, err := l.api.StartConfigurationSession(ctx, &appconfigdata.StartConfigurationSessionInput{
ApplicationIdentifier: aws.String(l.cfg.Application),
EnvironmentIdentifier: aws.String(l.cfg.Environment),
ConfigurationProfileIdentifier: aws.String(l.cfg.Configuration),
RequiredMinimumPollIntervalInSeconds: aws.Int32(int32(l.cfg.MinimumPollInterval.Seconds())),
})
if err != nil {
return nil, err
}
l.input.Store(appconfigdata.GetLatestConfigurationInput{
ConfigurationToken: out.InitialConfigurationToken,
})
return l, nil
}
func (l *Loader) Load(ctx context.Context) ([]byte, error) {
input := l.input.Load().(appconfigdata.GetLatestConfigurationInput)
out, err := l.api.GetLatestConfiguration(ctx, &input)
if err != nil {
var te *types.BadRequestException
if errors.As(err, &te) && strings.Contains(te.Error(), "Request too early") {
return nil, nil
}
return nil, err
}
l.input.Store(appconfigdata.GetLatestConfigurationInput{
ConfigurationToken: out.NextPollConfigurationToken,
})
return out.Configuration, nil
}