* Enable gossip encryption

* Fix order

* Auto-generate key

* Update gorp fork to include BeginTx

* Add a test for InsertIfExists

And point gorp to a custom branch for now

Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Agniva De Sarker
2020-06-03 14:16:15 +05:30
коммит произвёл GitHub
родитель fc028e703a
Коммит e3255879ba
51 изменённых файлов: 12514 добавлений и 6755 удалений

Просмотреть файл

@@ -6079,6 +6079,24 @@ func (s *OpenTracingLayerSystemStore) GetByName(name string) (*model.System, *mo
return resultVar0, resultVar1
}
func (s *OpenTracingLayerSystemStore) InsertIfExists(system *model.System) (*model.System, *model.AppError) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SystemStore.InsertIfExists")
s.Root.Store.SetContext(newCtx)
defer func() {
s.Root.Store.SetContext(origCtx)
}()
defer span.Finish()
resultVar0, resultVar1 := s.SystemStore.InsertIfExists(system)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (s *OpenTracingLayerSystemStore) PermanentDeleteByName(name string) (*model.System, *model.AppError) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SystemStore.PermanentDeleteByName")

Просмотреть файл

@@ -4,6 +4,8 @@
package sqlstore
import (
"context"
"database/sql"
"net/http"
"github.com/mattermost/mattermost-server/v5/model"
@@ -86,3 +88,37 @@ func (s SqlSystemStore) PermanentDeleteByName(name string) (*model.System, *mode
return &system, nil
}
// InsertIfExists inserts a given system value if it does not already exist. If a value
// already exists, it returns the old one, else returns the new one.
func (s SqlSystemStore) InsertIfExists(system *model.System) (*model.System, *model.AppError) {
tx, err := s.GetMaster().BeginTx(context.Background(), &sql.TxOptions{
Isolation: sql.LevelSerializable,
})
if err != nil {
return nil, model.NewAppError("SqlSystemStore.InsertIfExists", "store.sql_system.save.app_error", nil, err.Error(), http.StatusInternalServerError)
}
defer finalizeTransaction(tx)
var origSystem model.System
if err := tx.SelectOne(&origSystem, `SELECT * FROM Systems
WHERE Name = :Name`,
map[string]interface{}{"Name": system.Name}); err != nil && err != sql.ErrNoRows {
return nil, model.NewAppError("SqlSystemStore.InsertIfExists", "store.sql_system.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError)
}
if origSystem.Value != "" {
// Already a value exists, return that.
return &origSystem, nil
}
// Key does not exist, need to insert.
if err := tx.Insert(system); err != nil {
return nil, model.NewAppError("SqlSystemStore.InsertIfExists", "store.sql_system.save.app_error", nil, err.Error(), http.StatusInternalServerError)
}
if err := tx.Commit(); err != nil {
return nil, model.NewAppError("SqlSystemStore.InsertIfExists", "store.sql_system.save.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return system, nil
}

Просмотреть файл

@@ -418,6 +418,7 @@ type SystemStore interface {
Get() (model.StringMap, *model.AppError)
GetByName(name string) (*model.System, *model.AppError)
PermanentDeleteByName(name string) (*model.System, *model.AppError)
InsertIfExists(system *model.System) (*model.System, *model.AppError)
}
type WebhookStore interface {

Просмотреть файл

@@ -64,6 +64,31 @@ func (_m *SystemStore) GetByName(name string) (*model.System, *model.AppError) {
return r0, r1
}
// InsertIfExists provides a mock function with given fields: system
func (_m *SystemStore) InsertIfExists(system *model.System) (*model.System, *model.AppError) {
ret := _m.Called(system)
var r0 *model.System
if rf, ok := ret.Get(0).(func(*model.System) *model.System); ok {
r0 = rf(system)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.System)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(*model.System) *model.AppError); ok {
r1 = rf(system)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// PermanentDeleteByName provides a mock function with given fields: name
func (_m *SystemStore) PermanentDeleteByName(name string) (*model.System, *model.AppError) {
ret := _m.Called(name)

Просмотреть файл

@@ -4,6 +4,7 @@
package storetest
import (
"sync"
"testing"
"github.com/stretchr/testify/assert"
@@ -17,6 +18,9 @@ func TestSystemStore(t *testing.T, ss store.Store) {
t.Run("", func(t *testing.T) { testSystemStore(t, ss) })
t.Run("SaveOrUpdate", func(t *testing.T) { testSystemStoreSaveOrUpdate(t, ss) })
t.Run("PermanentDeleteByName", func(t *testing.T) { testSystemStorePermanentDeleteByName(t, ss) })
t.Run("InsertIfExists", func(t *testing.T) {
testInsertIfExists(t, ss)
})
}
func testSystemStore(t *testing.T, ss store.Store) {
@@ -84,3 +88,42 @@ func testSystemStorePermanentDeleteByName(t *testing.T, ss store.Store) {
_, err = ss.System().GetByName(s2.Name)
assert.NotNil(t, err)
}
func testInsertIfExists(t *testing.T, ss store.Store) {
t.Run("Serial", func(t *testing.T) {
s1 := &model.System{Name: model.SYSTEM_CLUSTER_ENCRYPTION_KEY, Value: "somekey"}
s2, err := ss.System().InsertIfExists(s1)
require.Nil(t, err)
assert.Equal(t, s1.Value, s2.Value)
s1New := &model.System{Name: model.SYSTEM_CLUSTER_ENCRYPTION_KEY, Value: "anotherKey"}
s3, err := ss.System().InsertIfExists(s1New)
require.Nil(t, err)
assert.Equal(t, s1.Value, s3.Value)
})
t.Run("Concurrent", func(t *testing.T) {
var s2, s3 *model.System
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
s1 := &model.System{Name: model.SYSTEM_CLUSTER_ENCRYPTION_KEY, Value: "firstKey"}
var err *model.AppError
s2, err = ss.System().InsertIfExists(s1)
require.Nil(t, err)
}()
go func() {
defer wg.Done()
s1 := &model.System{Name: model.SYSTEM_CLUSTER_ENCRYPTION_KEY, Value: "secondKey"}
var err *model.AppError
s3, err = ss.System().InsertIfExists(s1)
require.Nil(t, err)
}()
wg.Wait()
assert.Equal(t, s2.Value, s3.Value)
})
}

Просмотреть файл

@@ -5499,6 +5499,22 @@ func (s *TimerLayerSystemStore) GetByName(name string) (*model.System, *model.Ap
return resultVar0, resultVar1
}
func (s *TimerLayerSystemStore) InsertIfExists(system *model.System) (*model.System, *model.AppError) {
start := timemodule.Now()
resultVar0, resultVar1 := s.SystemStore.InsertIfExists(system)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if resultVar1 == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SystemStore.InsertIfExists", success, elapsed)
}
return resultVar0, resultVar1
}
func (s *TimerLayerSystemStore) PermanentDeleteByName(name string) (*model.System, *model.AppError) {
start := timemodule.Now()