Created
April 20, 2024 02:23
-
-
Save wolfeidau/0a10079b4fc7764529e92dc39292ec4e to your computer and use it in GitHub Desktop.
Small SSM Cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cache | |
import ( | |
"context" | |
"fmt" | |
"time" | |
"github.com/aws/aws-sdk-go-v2/aws" | |
"github.com/aws/aws-sdk-go-v2/service/ssm" | |
"github.com/patrickmn/go-cache" | |
"github.com/rs/zerolog/log" | |
) | |
type SSM interface { | |
GetParameter(ctx context.Context, params *ssm.GetParameterInput, optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) | |
} | |
type CallCacheSSMClient struct { | |
ssm SSM | |
call *CallCache | |
} | |
func NewCallCacheSSMClient(ssmClient SSM, expiration time.Duration, cleanupInterval time.Duration) SSM { | |
return &CallCacheSSMClient{ssm: ssmClient, call: &CallCache{cache: cache.New(expiration, cleanupInterval)}} | |
} | |
func (ssmc *CallCacheSSMClient) GetParameter(ctx context.Context, params *ssm.GetParameterInput, optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) { | |
key := fmt.Sprintf("ssm:GetParameter:%s", aws.ToString(params.Name)) | |
if val, exists := ssmc.call.cache.Get(key); exists { | |
log.Ctx(ctx).Info().Str("key", key).Msg("cached value returned") | |
return val.(*ssm.GetParameterOutput), nil | |
} | |
log.Ctx(ctx).Info().Str("key", key).Msg("loading value") | |
out, err := ssmc.ssm.GetParameter(ctx, params, optFns...) | |
if err != nil { | |
return nil, err | |
} | |
ssmc.call.cache.Set(key, out, cache.DefaultExpiration) | |
return out, nil | |
} | |
type CallCache struct { | |
cache *cache.Cache | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cache | |
import ( | |
"context" | |
"testing" | |
"time" | |
"github.com/aws/aws-sdk-go-v2/aws" | |
"github.com/aws/aws-sdk-go-v2/service/ssm" | |
"github.com/aws/aws-sdk-go-v2/service/ssm/types" | |
"github.com/stretchr/testify/require" | |
) | |
func TestCallCacheSSMClient_GetParameter(t *testing.T) { | |
assert := require.New(t) | |
ssmMock := &ssmClientMock{} | |
ssmMock.GetParameterFunc = func(ctx context.Context, params *ssm.GetParameterInput, optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) { | |
return &ssm.GetParameterOutput{ | |
Parameter: &types.Parameter{ | |
Value: aws.String("some value"), | |
}, | |
}, nil | |
} | |
ssmClient := NewCallCacheSSMClient(ssmMock, 1*time.Minute, 10*time.Minute) | |
// First call not cached | |
out, err := ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{ | |
Name: aws.String("some.parameter"), | |
}) | |
assert.NoError(err) | |
assert.Equal("some value", aws.ToString(out.Parameter.Value)) | |
// Second call cached | |
out, err = ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{ | |
Name: aws.String("some.parameter"), | |
}) | |
assert.NoError(err) | |
assert.Equal("some value", aws.ToString(out.Parameter.Value)) | |
// Assert ssmMock.GetParameter was only called once | |
assert.Equal(1, ssmMock.GetParameterCallCount) | |
} | |
type ssmClientMock struct { | |
GetParameterFunc func(ctx context.Context, params *ssm.GetParameterInput, optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) | |
GetParameterCallCount int | |
} | |
func (mock *ssmClientMock) GetParameter(ctx context.Context, params *ssm.GetParameterInput, optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) { | |
mock.GetParameterCallCount++ | |
return mock.GetParameterFunc(ctx, params, optFns...) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment