Refactor configapi to use new cache

pull/115/head
Aloïs Micard 4 years ago
parent 477092316b
commit d826fe73b6
No known key found for this signature in database
GPG Key ID: 1A0EB82F071F5EFE

@ -1,6 +1,16 @@
package cache
import "time"
import (
"errors"
"time"
)
var (
// NoTTL define an entry that lives forever
NoTTL = time.Duration(-1)
// ErrNIL is returned when there's no value for given key
ErrNIL = errors.New("value is nil")
)
//go:generate mockgen -destination=../cache_mock/cache_mock.go -package=cache_mock . Cache

@ -2,10 +2,9 @@ package configapi
import (
"fmt"
"github.com/creekorful/trandoshan/internal/configapi/database"
"github.com/creekorful/trandoshan/internal/cache"
"github.com/creekorful/trandoshan/internal/event"
"github.com/creekorful/trandoshan/internal/process"
"github.com/go-redis/redis/v8"
"github.com/gorilla/mux"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
@ -16,8 +15,8 @@ import (
// State represent the application state
type State struct {
db database.Database
pub event.Publisher
configCache cache.Cache
pub event.Publisher
}
// Name return the process name
@ -47,11 +46,7 @@ func (state *State) CustomFlags() []cli.Flag {
// Initialize the process
func (state *State) Initialize(provider process.Provider) error {
db, err := database.NewRedisDatabase(provider.GetValue("db-uri"))
if err != nil {
return err
}
state.db = db
// TODO init cache
pub, err := provider.Publisher()
if err != nil {
@ -68,7 +63,7 @@ func (state *State) Initialize(provider process.Provider) error {
}
}
if len(defaultValues) > 0 {
if err := setDefaultValues(db, defaultValues); err != nil {
if err := setDefaultValues(nil, defaultValues); err != nil {
return err
}
}
@ -96,7 +91,7 @@ func (state *State) getConfiguration(w http.ResponseWriter, r *http.Request) {
log.Debug().Str("key", key).Msg("Getting key")
b, err := state.db.Get(key)
b, err := state.configCache.GetBytes(key)
if err != nil {
log.Err(err).Msg("error while retrieving configuration")
w.WriteHeader(http.StatusInternalServerError)
@ -120,7 +115,7 @@ func (state *State) setConfiguration(w http.ResponseWriter, r *http.Request) {
log.Debug().Str("key", key).Bytes("value", b).Msg("Setting key")
if err := state.db.Set(key, b); err != nil {
if err := state.configCache.SetBytes(key, b, cache.NoTTL); err != nil {
log.Err(err).Msg("error while setting configuration")
w.WriteHeader(http.StatusInternalServerError)
return
@ -139,10 +134,10 @@ func (state *State) setConfiguration(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(b)
}
func setDefaultValues(service database.Database, values map[string]string) error {
func setDefaultValues(configCache cache.Cache, values map[string]string) error {
for key, value := range values {
if _, err := service.Get(key); err == redis.Nil {
if err := service.Set(key, []byte(value)); err != nil {
if _, err := configCache.GetBytes(key); err == cache.ErrNIL {
if err := configCache.SetBytes(key, []byte(value), cache.NoTTL); err != nil {
return fmt.Errorf("error while setting default value of %s: %s", key, err)
}
}

@ -1,7 +1,8 @@
package configapi
import (
"github.com/creekorful/trandoshan/internal/configapi/database_mock"
"github.com/creekorful/trandoshan/internal/cache"
"github.com/creekorful/trandoshan/internal/cache_mock"
"github.com/creekorful/trandoshan/internal/event"
"github.com/creekorful/trandoshan/internal/event_mock"
"github.com/golang/mock/gomock"
@ -17,15 +18,15 @@ func TestGetConfiguration(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
dbMock := database_mock.NewMockDatabase(mockCtrl)
dbMock.EXPECT().Get("hello").Return([]byte("{\"ttl\": \"10s\"}"), nil)
configCacheMock := cache_mock.NewMockCache(mockCtrl)
configCacheMock.EXPECT().GetBytes("hello").Return([]byte("{\"ttl\": \"10s\"}"), nil)
req := httptest.NewRequest(http.MethodGet, "/config/hello", nil)
req = mux.SetURLVars(req, map[string]string{"key": "hello"})
rec := httptest.NewRecorder()
s := State{db: dbMock}
s := State{configCache: configCacheMock}
s.getConfiguration(rec, req)
if rec.Code != http.StatusOK {
@ -49,10 +50,10 @@ func TestSetConfiguration(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
dbMock := database_mock.NewMockDatabase(mockCtrl)
configCacheMock := cache_mock.NewMockCache(mockCtrl)
pubMock := event_mock.NewMockPublisher(mockCtrl)
dbMock.EXPECT().Set("hello", []byte("{\"ttl\": \"10s\"}")).Return(nil)
configCacheMock.EXPECT().SetBytes("hello", []byte("{\"ttl\": \"10s\"}"), cache.NoTTL).Return(nil)
pubMock.EXPECT().PublishJSON("config", event.RawMessage{
Body: []byte("{\"ttl\": \"10s\"}"),
Headers: map[string]interface{}{"Config-Key": "hello"},
@ -63,7 +64,7 @@ func TestSetConfiguration(t *testing.T) {
rec := httptest.NewRecorder()
s := State{db: dbMock, pub: pubMock}
s := State{configCache: configCacheMock, pub: pubMock}
s.setConfiguration(rec, req)
if rec.Code != http.StatusOK {

@ -1,9 +0,0 @@
package database
//go:generate mockgen -destination=../database_mock/database_mock.go -package=database_mock . Database
// Database is the underlying storage for the ConfigAPI
type Database interface {
Get(key string) ([]byte, error)
Set(key string, value []byte) error
}

@ -1,29 +0,0 @@
package database
import (
"context"
"github.com/go-redis/redis/v8"
)
type redisDatabase struct {
rc *redis.Client
}
// NewRedisDatabase returns a new database that use Redis as backend
func NewRedisDatabase(uri string) (Database, error) {
return &redisDatabase{
rc: redis.NewClient(&redis.Options{
Addr: uri,
Password: "", // no password set
DB: 0, // use default DB
}),
}, nil
}
func (rd *redisDatabase) Get(key string) ([]byte, error) {
return rd.rc.Get(context.Background(), key).Bytes()
}
func (rd *redisDatabase) Set(key string, value []byte) error {
return rd.rc.Set(context.Background(), key, value, 0).Err()
}
Loading…
Cancel
Save