Skip to content

Commit c4cef51

Browse files
committed
Implement cache
1 parent dd21a1c commit c4cef51

24 files changed

+1019
-54
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ go.work
2525

2626
# goreleaser
2727
dist/
28+
29+
# temporary files
30+
tmp/

alias.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import (
2424
// Engine initializes external store client and template.
2525
type Engine = engine.Engine
2626

27-
var (
28-
// NewConfigFromFile returns a new Config from file.
29-
NewConfigFromFile = config.NewFromFile
27+
// Config is the configuration for this library.
28+
type Config = config.Config
3029

30+
var (
3131
// NewEngine returns a new Engine.
3232
NewEngine = engine.New
3333
)

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.29.1
1010
github.com/aws/aws-sdk-go-v2/service/ssm v1.50.4
1111
github.com/spf13/cobra v1.8.0
12+
golang.org/x/crypto v0.3.0
1213
sigs.k8s.io/yaml v1.4.0
1314
)
1415

@@ -36,6 +37,5 @@ require (
3637
github.com/shopspring/decimal v1.2.0 // indirect
3738
github.com/spf13/cast v1.3.1 // indirect
3839
github.com/spf13/pflag v1.0.5 // indirect
39-
golang.org/x/crypto v0.3.0 // indirect
4040
gopkg.in/yaml.v2 v2.4.0 // indirect
4141
)

internal/client/aws.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
kmsTypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
2626
"github.com/aws/aws-sdk-go-v2/service/ssm"
2727
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
28+
"github.com/dwango/yashiro/internal/values"
2829
"github.com/dwango/yashiro/pkg/config"
2930
)
3031

@@ -56,8 +57,8 @@ func newAwsClient(cfg *config.AwsConfig) (Client, error) {
5657
}, nil
5758
}
5859

59-
func (c awsClient) GetValues(ctx context.Context, ignoreNotFound bool) (Values, error) {
60-
values := make(Values, len(c.parameterStoreValue)+len(c.secretsManagerValue))
60+
func (c awsClient) GetValues(ctx context.Context, ignoreNotFound bool) (values.Values, error) {
61+
values := make(values.Values, len(c.parameterStoreValue)+len(c.secretsManagerValue))
6162

6263
for _, v := range c.parameterStoreValue {
6364
output, err := c.ssmClient.GetParameter(ctx, &ssm.GetParameterInput{

internal/client/aws_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
kmsTypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
2626
"github.com/aws/aws-sdk-go-v2/service/ssm"
2727
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
28+
"github.com/dwango/yashiro/internal/values"
2829
"github.com/dwango/yashiro/pkg/config"
2930
)
3031

@@ -109,7 +110,7 @@ func Test_awsClient_GetValues(t *testing.T) {
109110
name string
110111
fields fields
111112
args args
112-
want Values
113+
want values.Values
113114
wantErr bool
114115
}{
115116
{
@@ -128,7 +129,7 @@ func Test_awsClient_GetValues(t *testing.T) {
128129
ctx: context.Background(),
129130
ignoreNotFound: false,
130131
},
131-
want: Values{"ssmKey": "test", "kmsKey": "test"},
132+
want: values.Values{"ssmKey": "test", "kmsKey": "test"},
132133
},
133134
{
134135
name: "ok: json",
@@ -156,7 +157,7 @@ func Test_awsClient_GetValues(t *testing.T) {
156157
ctx: context.Background(),
157158
ignoreNotFound: false,
158159
},
159-
want: Values{"ssmKey": map[string]any{"key": "value"}, "kmsKey": map[string]any{"key": "value"}},
160+
want: values.Values{"ssmKey": map[string]any{"key": "value"}, "kmsKey": map[string]any{"key": "value"}},
160161
},
161162
{
162163
name: "ok: ignore not found error",
@@ -174,7 +175,7 @@ func Test_awsClient_GetValues(t *testing.T) {
174175
ctx: context.Background(),
175176
ignoreNotFound: true,
176177
},
177-
want: Values{},
178+
want: values.Values{},
178179
},
179180
{
180181
name: "error: return not found from ssm",

internal/client/cache.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Copyright 2024 DWANGO Co., Ltd.
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+
* https://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+
package client
17+
18+
import (
19+
"context"
20+
21+
"github.com/dwango/yashiro/internal/client/cache"
22+
"github.com/dwango/yashiro/internal/values"
23+
)
24+
25+
type clientWithCache struct {
26+
client Client
27+
cache cache.Cache
28+
}
29+
30+
func newClientWithCache(client Client, cache cache.Cache) Client {
31+
return &clientWithCache{
32+
client: client,
33+
cache: cache,
34+
}
35+
}
36+
37+
// GetValues implements Client.
38+
func (c *clientWithCache) GetValues(ctx context.Context, ignoreNotFound bool) (values.Values, error) {
39+
val, expired, err := c.cache.Load(ctx)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
// if cache is empty, get values from external store.
45+
if len(val) == 0 || expired {
46+
val, err = c.client.GetValues(ctx, ignoreNotFound)
47+
if err != nil {
48+
return nil, err
49+
}
50+
}
51+
52+
// save values to cache
53+
if expired {
54+
if err := c.cache.Save(ctx, val); err != nil {
55+
return nil, err
56+
}
57+
}
58+
59+
return val, nil
60+
}

internal/client/cache/cache.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright 2024 DWANGO Co., Ltd.
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+
* https://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+
package cache
17+
18+
import (
19+
"context"
20+
"errors"
21+
"fmt"
22+
23+
"github.com/dwango/yashiro/internal/values"
24+
"github.com/dwango/yashiro/pkg/config"
25+
)
26+
27+
var (
28+
ErrInvalidCacheType = errors.New("invalid cache type")
29+
)
30+
31+
type Cache interface {
32+
// Load returns values from cache and whether or not cache is expired. If cache is empty,
33+
// returned values is empty and expired=true.
34+
Load(ctx context.Context) (values.Values, bool, error)
35+
36+
// Save saves values to cache.
37+
Save(ctx context.Context, val values.Values) error
38+
}
39+
40+
func New(cfg config.CacheConfig) (Cache, error) {
41+
switch cfg.Type {
42+
case config.CacheTypeUnspecified, config.CacheTypeMemory:
43+
return newMemoryCache()
44+
case config.CacheTypeFile:
45+
return newFileCache(cfg.File)
46+
default:
47+
return nil, fmt.Errorf("%w: %s", ErrInvalidCacheType, cfg.Type)
48+
}
49+
}

0 commit comments

Comments
 (0)