diff --git a/certs/manager.go b/certs/manager.go index e8585c36a1c..f86dc53a8ec 100644 --- a/certs/manager.go +++ b/certs/manager.go @@ -101,9 +101,7 @@ func NewSlaveCertManager(localStorage, rpcStorage storage.Handler, secret string return err } - mdcbStorage := storage.NewMdcbStorage(localStorage, rpcStorage, log) - mdcbStorage.CallbackonPullfromRPC = &callbackOnPullCertFromRPC - + mdcbStorage := storage.NewMdcbStorage(localStorage, rpcStorage, log, callbackOnPullCertFromRPC) cm.storage = mdcbStorage return cm } diff --git a/gateway/server.go b/gateway/server.go index 0e51b4c3716..745b9dabafb 100644 --- a/gateway/server.go +++ b/gateway/server.go @@ -1587,6 +1587,7 @@ func (gw *Gateway) getGlobalMDCBStorageHandler(keyPrefix string, hashKeys bool) Gw: gw, }, logger, + nil, ) } return localStorage diff --git a/storage/mdcb_storage.go b/storage/mdcb_storage.go index ad615a6efca..a4e78b597d2 100644 --- a/storage/mdcb_storage.go +++ b/storage/mdcb_storage.go @@ -8,60 +8,50 @@ import ( ) type MdcbStorage struct { - local Handler - rpc Handler - logger *logrus.Entry - CallbackonPullfromRPC *func(key string, val string) error + local Handler + rpc Handler + logger *logrus.Entry + OnRPCCertPull func(key string, val string) error } -func NewMdcbStorage(local, rpc Handler, log *logrus.Entry) *MdcbStorage { +const ( + resourceOauthClient = "OauthClient" + resourceCertificate = "Certificate" + resourceApiKey = "ApiKey" + resourceKey = "Key" +) + +func NewMdcbStorage(local, rpc Handler, log *logrus.Entry, OnRPCCertPull func(key string, val string) error) *MdcbStorage { return &MdcbStorage{ - local: local, - rpc: rpc, - logger: log, + local: local, + rpc: rpc, + logger: log, + OnRPCCertPull: OnRPCCertPull, } } func (m MdcbStorage) GetKey(key string) (string, error) { - var val string - var err error - - if m.local == nil { - return m.rpc.GetKey(key) - } - - val, err = m.local.GetKey(key) - if err != nil { - m.logger.Infof("Retrieving key from rpc.") - val, err = m.rpc.GetKey(key) - - if err != nil { - resourceType := getResourceType(key) - m.logger.Errorf("cannot retrieve %v from rpc: %v", resourceType, err.Error()) - return val, err - } - - if m.CallbackonPullfromRPC != nil { - err := (*m.CallbackonPullfromRPC)(key, val) - if err != nil { - m.logger.Error(err) - } + if m.local != nil { + val, err := m.getFromLocal(key) + if err == nil { + return val, nil } + m.logger.Debugf("Key not present locally, pulling from rpc layer: %v", err) } - return val, err + return m.getFromRPCAndCache(key) } func getResourceType(key string) string { switch { case strings.Contains(key, "oauth-clientid."): - return "Oauth Client" + return resourceOauthClient case strings.HasPrefix(key, "cert"): - return "certificate" + return resourceCertificate case strings.HasPrefix(key, "apikey"): - return "api key" + return resourceApiKey default: - return "key" + return resourceKey } } @@ -256,3 +246,46 @@ func (m MdcbStorage) Exists(key string) (bool, error) { return foundLocal && foundRpc, nil } + +// cacheCertificate saves locally resourceCertificate after pull from rpc +func (m MdcbStorage) cacheCertificate(key, val string) error { + if m.OnRPCCertPull == nil { + return nil + } + return m.OnRPCCertPull(key, val) +} + +// cacheOAuthClient saved oauth data in local storage after pull from rpc +func (m MdcbStorage) cacheOAuthClient(key, val string) error { + return m.local.SetKey(key, val, 0) +} + +// processResourceByType based on the type of key it will trigger the proper +// caching mechanism +func (m MdcbStorage) processResourceByType(key, val string) error { + + resourceType := getResourceType(key) + switch resourceType { + case resourceOauthClient: + return m.cacheOAuthClient(key, val) + case resourceCertificate: + return m.cacheCertificate(key, val) + } + return nil +} + +// getFromRPCAndCache pulls a resource from rpc and stores it in local redis for caching +func (m MdcbStorage) getFromRPCAndCache(key string) (string, error) { + val, err := m.rpc.GetKey(key) + if err != nil { + return "", err + } + + err = m.processResourceByType(key, val) + return val, err +} + +// getFromLocal get a key from local storage +func (m MdcbStorage) getFromLocal(key string) (string, error) { + return m.local.GetKey(key) +} diff --git a/storage/mdcb_storage_test.go b/storage/mdcb_storage_test.go index 0d12bc29940..91a9505c1d9 100644 --- a/storage/mdcb_storage_test.go +++ b/storage/mdcb_storage_test.go @@ -2,22 +2,71 @@ package storage import ( "context" + "errors" "io" + "strings" "testing" + "go.uber.org/mock/gomock" + + "github.com/TykTechnologies/tyk/storage/mock" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) +type testSetup struct { + Logger *logrus.Entry + Local *mock.MockHandler + Remote *mock.MockHandler + MdcbStorage *MdcbStorage + CleanUp func() +} + +var notFoundKeyErr = errors.New("key not found") + +func getTestLogger() *logrus.Entry { + logger := logrus.New() + logger.Out = io.Discard + log := logger.WithContext(context.Background()) + return log +} + +func setupTest(t *testing.T) *testSetup { + t.Helper() // Marks this function as a test helper + log := getTestLogger() + + ctrlLocal := gomock.NewController(t) + local := mock.NewMockHandler(ctrlLocal) + + ctrlRemote := gomock.NewController(t) + remote := mock.NewMockHandler(ctrlRemote) + + mdcbStorage := NewMdcbStorage(local, remote, log, nil) + + cleanup := func() { + ctrlLocal.Finish() + ctrlRemote.Finish() + } + + return &testSetup{ + Logger: log, + Local: local, + Remote: remote, + MdcbStorage: mdcbStorage, + CleanUp: cleanup, + } +} + func TestGetResourceType(t *testing.T) { tests := []struct { key string expected string }{ - {"oauth-clientid.client-id", "Oauth Client"}, - {"cert.something", "certificate"}, - {"apikey.something", "api key"}, - {"unmatched-key", "key"}, + {"oauth-clientid.client-id", resourceOauthClient}, + {"cert.something", resourceCertificate}, + {"apikey.something", resourceApiKey}, + {"unmatched-key", resourceKey}, } for _, tt := range tests { @@ -51,7 +100,7 @@ func TestMdcbStorage_GetMultiKey(t *testing.T) { logger.Out = io.Discard log := logger.WithContext(context.Background()) - mdcb := NewMdcbStorage(localHandler, rpcHandler, log) + mdcb := NewMdcbStorage(localHandler, rpcHandler, log, nil) testsCases := []struct { name string @@ -89,3 +138,272 @@ func TestMdcbStorage_GetMultiKey(t *testing.T) { }) } } + +func TestGetFromLocalStorage(t *testing.T) { + setup := setupTest(t) + defer setup.CleanUp() + + mdcb := setup.MdcbStorage + setup.Local.EXPECT().GetKey("any").Return("exists", nil) + setup.Local.EXPECT().GetKey("nonExistingKey").Return("", notFoundKeyErr) + + localVal, err := mdcb.getFromLocal("any") + assert.Nil(t, err, "expected no error") + assert.Equal(t, "exists", localVal) + + notFoundVal, err := mdcb.getFromLocal("nonExistingKey") + assert.ErrorIs(t, err, notFoundKeyErr) + assert.Equal(t, "", notFoundVal) +} + +func TestGetFromRPCAndCache(t *testing.T) { + setup := setupTest(t) + defer setup.CleanUp() + + m := setup.MdcbStorage + rpcHandler := setup.Remote + + // attempt with keys that do not follow pattern for oauth, certs, apikeys + rpcHandler.EXPECT().GetKey("john").Return("doe", nil) + rpcHandler.EXPECT().GetKey("jane").Return("", notFoundKeyErr) + setup.Local.EXPECT().SetKey("john", gomock.Any(), gomock.Any()).Times(0) + setup.Local.EXPECT().SetKey("jane", gomock.Any(), gomock.Any()).Times(0) + + rpcVal, err := m.getFromRPCAndCache("john") + assert.Nil(t, err, "expected no error") + assert.Equal(t, "doe", rpcVal) + + rpcVal, err = m.getFromRPCAndCache("jane") + assert.Equal(t, "", rpcVal) + assert.ErrorIs(t, err, notFoundKeyErr) + + // test oauth keys + oauthClientKey := "oauth-clientid.my-client-id" + rpcHandler.EXPECT().GetKey(oauthClientKey).Return("value", nil) + setup.Local.EXPECT().SetKey(oauthClientKey, gomock.Any(), gomock.Any()).Times(1) + rpcVal, err = m.getFromRPCAndCache(oauthClientKey) + assert.Equal(t, "value", rpcVal) + assert.Nil(t, err) + + // test certs keys + // for certs we do not call directly the set key func, but the callback + count := 0 + mockSaveCert := func(_, _ string) error { + count++ + return nil + } + m.OnRPCCertPull = mockSaveCert + + certKey := "cert-my-cert-id" + rpcHandler.EXPECT().GetKey(certKey).Return("value", nil) + rpcVal, err = m.getFromRPCAndCache(certKey) + assert.Equal(t, "value", rpcVal) + assert.Equal(t, 1, count) + assert.Nil(t, err) +} + +func TestProcessResourceByType(t *testing.T) { + // Setup + + errCachingFailed := errors.New("caching failed") + // Test cases + testCases := []struct { + name string + key string + val string + setupMocks func(handler *mock.MockHandler) + expectedError error + }{ + { + name: "Successful OAuth client caching", + key: "oauth-clientid.client1", + val: "clientdata1", + setupMocks: func(mockLocal *mock.MockHandler) { + mockLocal.EXPECT().SetKey("oauth-clientid.client1", "clientdata1", gomock.Any()).Return(nil) + }, + expectedError: nil, + }, + { + name: "Failed OAuth client caching", + key: "oauth-clientid.failClient2", + val: "clientdata2", + setupMocks: func(mockLocal *mock.MockHandler) { + mockLocal.EXPECT().SetKey("oauth-clientid.failClient2", "clientdata2", gomock.Any()).Return(errCachingFailed) + }, + expectedError: errCachingFailed, + }, + { + name: "Successful Certificate caching", + key: "cert:cert1", + val: "certdata1", + setupMocks: func(_ *mock.MockHandler) { + // Setup expectations for certificate caching if needed + }, + expectedError: nil, + }, + { + name: "Failed Certificate caching", + key: "cert:failCert", + val: "certdata2", + setupMocks: func(_ *mock.MockHandler) { + // Setup expectations for failed certificate caching if needed + }, + expectedError: errCachingFailed, + }, + { + name: "Unknown resource type", + key: "unknown:resource1", + val: "data1", + setupMocks: func(_ *mock.MockHandler) {}, + expectedError: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + setup := setupTest(t) + defer setup.CleanUp() + + m := setup.MdcbStorage + tc.setupMocks(setup.Local) + + // If testing certificate caching, setup the callback + if strings.HasPrefix(tc.key, "cert:") { + m.OnRPCCertPull = func(key, _ string) error { + if key == "cert:failCert" { + return errCachingFailed + } + return nil + } + } + + err := m.processResourceByType(tc.key, tc.val) + + if tc.expectedError != nil { + assert.Error(t, err) + assert.ErrorIs(t, err, tc.expectedError) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestCacheOAuthClient(t *testing.T) { + + // Test cases + testCases := []struct { + name string + key string + val string + setKeyErr error + expectLog bool + }{ + { + name: "Successful cache", + key: "oauth1", + val: "clientdata1", + setKeyErr: nil, + expectLog: false, + }, + { + name: "Cache failure", + key: "oauth2", + val: "clientdata2", + setKeyErr: errors.New("failed to set key"), + expectLog: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Setup + setup := setupTest(t) + defer setup.CleanUp() + + m := setup.MdcbStorage + localHandler := setup.Local + + localHandler.EXPECT().SetKey(tc.key, tc.val, gomock.Any()).Return(tc.setKeyErr) + err := m.cacheOAuthClient(tc.key, tc.val) + + if tc.setKeyErr != nil { + assert.Error(t, err, "Should return an error when SetKey fails") + assert.ErrorIs(t, tc.setKeyErr, err, "Returned error should match the SetKey error") + } else { + assert.NoError(t, err, "Should not return an error when SetKey succeeds") + } + + }) + } +} + +func TestCacheCertificate(t *testing.T) { + + // Test cases + testCases := []struct { + name string + key string + val string + callbackError error + shouldUseCallback bool + }{ + { + name: "Successful cache", + key: "cert1", + val: "certdata1", + callbackError: nil, + shouldUseCallback: true, + }, + { + name: "Cache failure", + key: "cert2", + val: "certdata2", + callbackError: errors.New("failed to save"), + shouldUseCallback: true, + }, + { + name: "Nil callback", + key: "cert3", + val: "certdata3", + callbackError: nil, + shouldUseCallback: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + setup := setupTest(t) + defer setup.CleanUp() + + m := setup.MdcbStorage + + var callbackCalled bool + mockCallback := func(k, v string) error { + callbackCalled = true + assert.Equal(t, tc.key, k) + assert.Equal(t, tc.val, v) + return tc.callbackError + } + + if tc.shouldUseCallback { + m.OnRPCCertPull = mockCallback + } + + // Call the method + err := m.cacheCertificate(tc.key, tc.val) + + // Assertions + if tc.shouldUseCallback { + assert.True(t, callbackCalled, "Callback should have been called") + if tc.callbackError != nil { + assert.ErrorIs(t, tc.callbackError, err) + } + } else { + assert.NoError(t, err) + assert.False(t, callbackCalled, "Callback should not have been called") + } + + }) + } +} diff --git a/storage/mock/storage.go b/storage/mock/storage.go new file mode 100644 index 00000000000..362b2645eae --- /dev/null +++ b/storage/mock/storage.go @@ -0,0 +1,502 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/TykTechnologies/tyk/storage (interfaces: Handler) +// +// Generated by this command: +// +// mockgen -destination=./mock/storage.go -package mock . Handler +// + +// Package mock is a generated GoMock package. +package mock + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockHandler is a mock of Handler interface. +type MockHandler struct { + ctrl *gomock.Controller + recorder *MockHandlerMockRecorder +} + +// MockHandlerMockRecorder is the mock recorder for MockHandler. +type MockHandlerMockRecorder struct { + mock *MockHandler +} + +// NewMockHandler creates a new mock instance. +func NewMockHandler(ctrl *gomock.Controller) *MockHandler { + mock := &MockHandler{ctrl: ctrl} + mock.recorder = &MockHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { + return m.recorder +} + +// AddToSet mocks base method. +func (m *MockHandler) AddToSet(arg0, arg1 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddToSet", arg0, arg1) +} + +// AddToSet indicates an expected call of AddToSet. +func (mr *MockHandlerMockRecorder) AddToSet(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToSet", reflect.TypeOf((*MockHandler)(nil).AddToSet), arg0, arg1) +} + +// AddToSortedSet mocks base method. +func (m *MockHandler) AddToSortedSet(arg0, arg1 string, arg2 float64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddToSortedSet", arg0, arg1, arg2) +} + +// AddToSortedSet indicates an expected call of AddToSortedSet. +func (mr *MockHandlerMockRecorder) AddToSortedSet(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToSortedSet", reflect.TypeOf((*MockHandler)(nil).AddToSortedSet), arg0, arg1, arg2) +} + +// AppendToSet mocks base method. +func (m *MockHandler) AppendToSet(arg0, arg1 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AppendToSet", arg0, arg1) +} + +// AppendToSet indicates an expected call of AppendToSet. +func (mr *MockHandlerMockRecorder) AppendToSet(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendToSet", reflect.TypeOf((*MockHandler)(nil).AppendToSet), arg0, arg1) +} + +// Connect mocks base method. +func (m *MockHandler) Connect() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connect") + ret0, _ := ret[0].(bool) + return ret0 +} + +// Connect indicates an expected call of Connect. +func (mr *MockHandlerMockRecorder) Connect() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockHandler)(nil).Connect)) +} + +// Decrement mocks base method. +func (m *MockHandler) Decrement(arg0 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Decrement", arg0) +} + +// Decrement indicates an expected call of Decrement. +func (mr *MockHandlerMockRecorder) Decrement(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decrement", reflect.TypeOf((*MockHandler)(nil).Decrement), arg0) +} + +// DeleteAllKeys mocks base method. +func (m *MockHandler) DeleteAllKeys() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteAllKeys") + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteAllKeys indicates an expected call of DeleteAllKeys. +func (mr *MockHandlerMockRecorder) DeleteAllKeys() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllKeys", reflect.TypeOf((*MockHandler)(nil).DeleteAllKeys)) +} + +// DeleteKey mocks base method. +func (m *MockHandler) DeleteKey(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteKey", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteKey indicates an expected call of DeleteKey. +func (mr *MockHandlerMockRecorder) DeleteKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteKey", reflect.TypeOf((*MockHandler)(nil).DeleteKey), arg0) +} + +// DeleteKeys mocks base method. +func (m *MockHandler) DeleteKeys(arg0 []string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteKeys", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteKeys indicates an expected call of DeleteKeys. +func (mr *MockHandlerMockRecorder) DeleteKeys(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteKeys", reflect.TypeOf((*MockHandler)(nil).DeleteKeys), arg0) +} + +// DeleteRawKey mocks base method. +func (m *MockHandler) DeleteRawKey(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteRawKey", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteRawKey indicates an expected call of DeleteRawKey. +func (mr *MockHandlerMockRecorder) DeleteRawKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRawKey", reflect.TypeOf((*MockHandler)(nil).DeleteRawKey), arg0) +} + +// DeleteRawKeys mocks base method. +func (m *MockHandler) DeleteRawKeys(arg0 []string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteRawKeys", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteRawKeys indicates an expected call of DeleteRawKeys. +func (mr *MockHandlerMockRecorder) DeleteRawKeys(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRawKeys", reflect.TypeOf((*MockHandler)(nil).DeleteRawKeys), arg0) +} + +// DeleteScanMatch mocks base method. +func (m *MockHandler) DeleteScanMatch(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteScanMatch", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// DeleteScanMatch indicates an expected call of DeleteScanMatch. +func (mr *MockHandlerMockRecorder) DeleteScanMatch(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteScanMatch", reflect.TypeOf((*MockHandler)(nil).DeleteScanMatch), arg0) +} + +// Exists mocks base method. +func (m *MockHandler) Exists(arg0 string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Exists", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Exists indicates an expected call of Exists. +func (mr *MockHandlerMockRecorder) Exists(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockHandler)(nil).Exists), arg0) +} + +// GetAndDeleteSet mocks base method. +func (m *MockHandler) GetAndDeleteSet(arg0 string) []any { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAndDeleteSet", arg0) + ret0, _ := ret[0].([]any) + return ret0 +} + +// GetAndDeleteSet indicates an expected call of GetAndDeleteSet. +func (mr *MockHandlerMockRecorder) GetAndDeleteSet(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAndDeleteSet", reflect.TypeOf((*MockHandler)(nil).GetAndDeleteSet), arg0) +} + +// GetExp mocks base method. +func (m *MockHandler) GetExp(arg0 string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetExp", arg0) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetExp indicates an expected call of GetExp. +func (mr *MockHandlerMockRecorder) GetExp(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExp", reflect.TypeOf((*MockHandler)(nil).GetExp), arg0) +} + +// GetKey mocks base method. +func (m *MockHandler) GetKey(arg0 string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKey", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetKey indicates an expected call of GetKey. +func (mr *MockHandlerMockRecorder) GetKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKey", reflect.TypeOf((*MockHandler)(nil).GetKey), arg0) +} + +// GetKeyPrefix mocks base method. +func (m *MockHandler) GetKeyPrefix() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKeyPrefix") + ret0, _ := ret[0].(string) + return ret0 +} + +// GetKeyPrefix indicates an expected call of GetKeyPrefix. +func (mr *MockHandlerMockRecorder) GetKeyPrefix() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeyPrefix", reflect.TypeOf((*MockHandler)(nil).GetKeyPrefix)) +} + +// GetKeys mocks base method. +func (m *MockHandler) GetKeys(arg0 string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKeys", arg0) + ret0, _ := ret[0].([]string) + return ret0 +} + +// GetKeys indicates an expected call of GetKeys. +func (mr *MockHandlerMockRecorder) GetKeys(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeys", reflect.TypeOf((*MockHandler)(nil).GetKeys), arg0) +} + +// GetKeysAndValues mocks base method. +func (m *MockHandler) GetKeysAndValues() map[string]string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKeysAndValues") + ret0, _ := ret[0].(map[string]string) + return ret0 +} + +// GetKeysAndValues indicates an expected call of GetKeysAndValues. +func (mr *MockHandlerMockRecorder) GetKeysAndValues() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysAndValues", reflect.TypeOf((*MockHandler)(nil).GetKeysAndValues)) +} + +// GetKeysAndValuesWithFilter mocks base method. +func (m *MockHandler) GetKeysAndValuesWithFilter(arg0 string) map[string]string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKeysAndValuesWithFilter", arg0) + ret0, _ := ret[0].(map[string]string) + return ret0 +} + +// GetKeysAndValuesWithFilter indicates an expected call of GetKeysAndValuesWithFilter. +func (mr *MockHandlerMockRecorder) GetKeysAndValuesWithFilter(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysAndValuesWithFilter", reflect.TypeOf((*MockHandler)(nil).GetKeysAndValuesWithFilter), arg0) +} + +// GetListRange mocks base method. +func (m *MockHandler) GetListRange(arg0 string, arg1, arg2 int64) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetListRange", arg0, arg1, arg2) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetListRange indicates an expected call of GetListRange. +func (mr *MockHandlerMockRecorder) GetListRange(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetListRange", reflect.TypeOf((*MockHandler)(nil).GetListRange), arg0, arg1, arg2) +} + +// GetMultiKey mocks base method. +func (m *MockHandler) GetMultiKey(arg0 []string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMultiKey", arg0) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMultiKey indicates an expected call of GetMultiKey. +func (mr *MockHandlerMockRecorder) GetMultiKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultiKey", reflect.TypeOf((*MockHandler)(nil).GetMultiKey), arg0) +} + +// GetRawKey mocks base method. +func (m *MockHandler) GetRawKey(arg0 string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRawKey", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRawKey indicates an expected call of GetRawKey. +func (mr *MockHandlerMockRecorder) GetRawKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRawKey", reflect.TypeOf((*MockHandler)(nil).GetRawKey), arg0) +} + +// GetRollingWindow mocks base method. +func (m *MockHandler) GetRollingWindow(arg0 string, arg1 int64, arg2 bool) (int, []any) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRollingWindow", arg0, arg1, arg2) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].([]any) + return ret0, ret1 +} + +// GetRollingWindow indicates an expected call of GetRollingWindow. +func (mr *MockHandlerMockRecorder) GetRollingWindow(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRollingWindow", reflect.TypeOf((*MockHandler)(nil).GetRollingWindow), arg0, arg1, arg2) +} + +// GetSet mocks base method. +func (m *MockHandler) GetSet(arg0 string) (map[string]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSet", arg0) + ret0, _ := ret[0].(map[string]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSet indicates an expected call of GetSet. +func (mr *MockHandlerMockRecorder) GetSet(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSet", reflect.TypeOf((*MockHandler)(nil).GetSet), arg0) +} + +// GetSortedSetRange mocks base method. +func (m *MockHandler) GetSortedSetRange(arg0, arg1, arg2 string) ([]string, []float64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSortedSetRange", arg0, arg1, arg2) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].([]float64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetSortedSetRange indicates an expected call of GetSortedSetRange. +func (mr *MockHandlerMockRecorder) GetSortedSetRange(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSortedSetRange", reflect.TypeOf((*MockHandler)(nil).GetSortedSetRange), arg0, arg1, arg2) +} + +// IncrememntWithExpire mocks base method. +func (m *MockHandler) IncrememntWithExpire(arg0 string, arg1 int64) int64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IncrememntWithExpire", arg0, arg1) + ret0, _ := ret[0].(int64) + return ret0 +} + +// IncrememntWithExpire indicates an expected call of IncrememntWithExpire. +func (mr *MockHandlerMockRecorder) IncrememntWithExpire(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncrememntWithExpire", reflect.TypeOf((*MockHandler)(nil).IncrememntWithExpire), arg0, arg1) +} + +// RemoveFromList mocks base method. +func (m *MockHandler) RemoveFromList(arg0, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveFromList", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveFromList indicates an expected call of RemoveFromList. +func (mr *MockHandlerMockRecorder) RemoveFromList(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFromList", reflect.TypeOf((*MockHandler)(nil).RemoveFromList), arg0, arg1) +} + +// RemoveFromSet mocks base method. +func (m *MockHandler) RemoveFromSet(arg0, arg1 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveFromSet", arg0, arg1) +} + +// RemoveFromSet indicates an expected call of RemoveFromSet. +func (mr *MockHandlerMockRecorder) RemoveFromSet(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFromSet", reflect.TypeOf((*MockHandler)(nil).RemoveFromSet), arg0, arg1) +} + +// RemoveSortedSetRange mocks base method. +func (m *MockHandler) RemoveSortedSetRange(arg0, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveSortedSetRange", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveSortedSetRange indicates an expected call of RemoveSortedSetRange. +func (mr *MockHandlerMockRecorder) RemoveSortedSetRange(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveSortedSetRange", reflect.TypeOf((*MockHandler)(nil).RemoveSortedSetRange), arg0, arg1, arg2) +} + +// SetExp mocks base method. +func (m *MockHandler) SetExp(arg0 string, arg1 int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetExp", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetExp indicates an expected call of SetExp. +func (mr *MockHandlerMockRecorder) SetExp(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExp", reflect.TypeOf((*MockHandler)(nil).SetExp), arg0, arg1) +} + +// SetKey mocks base method. +func (m *MockHandler) SetKey(arg0, arg1 string, arg2 int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetKey", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetKey indicates an expected call of SetKey. +func (mr *MockHandlerMockRecorder) SetKey(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetKey", reflect.TypeOf((*MockHandler)(nil).SetKey), arg0, arg1, arg2) +} + +// SetRawKey mocks base method. +func (m *MockHandler) SetRawKey(arg0, arg1 string, arg2 int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetRawKey", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetRawKey indicates an expected call of SetRawKey. +func (mr *MockHandlerMockRecorder) SetRawKey(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRawKey", reflect.TypeOf((*MockHandler)(nil).SetRawKey), arg0, arg1, arg2) +} + +// SetRollingWindow mocks base method. +func (m *MockHandler) SetRollingWindow(arg0 string, arg1 int64, arg2 string, arg3 bool) (int, []any) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetRollingWindow", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].([]any) + return ret0, ret1 +} + +// SetRollingWindow indicates an expected call of SetRollingWindow. +func (mr *MockHandlerMockRecorder) SetRollingWindow(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRollingWindow", reflect.TypeOf((*MockHandler)(nil).SetRollingWindow), arg0, arg1, arg2, arg3) +} diff --git a/storage/storage.go b/storage/storage.go index 2c74e54e8a4..e4b889e18b6 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -17,6 +17,8 @@ import ( "github.com/TykTechnologies/tyk/internal/uuid" ) +//go:generate mockgen -destination=./mock/storage.go -package mock . Handler + var log = logger.Get() // ErrKeyNotFound is a standard error for when a key is not found in the storage engine