Merge pull request #847 from yangkaa/configV1.4

更新应用配置组
This commit is contained in:
黄润豪 2020-09-24 18:55:49 +08:00 committed by GitHub
commit c384dbc1ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 265 additions and 35 deletions

View File

@ -154,6 +154,7 @@ type ApplicationInterface interface {
ListServices(w http.ResponseWriter, r *http.Request)
DeleteApp(w http.ResponseWriter, r *http.Request)
AddConfigGroup(w http.ResponseWriter, r *http.Request)
UpdateConfigGroup(w http.ResponseWriter, r *http.Request)
}
//Gatewayer gateway api interface

View File

@ -299,6 +299,7 @@ func (v2 *V2) applicationRouter() chi.Router {
// Application configuration group
r.Post("/configgroups", controller.GetManager().AddConfigGroup)
r.Put("/configgroups/{config_group_name}", controller.GetManager().UpdateConfigGroup)
return r
}

View File

@ -3,6 +3,7 @@ package controller
import (
"net/http"
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/api/handler"
"github.com/goodrain/rainbond/api/middleware"
"github.com/goodrain/rainbond/api/model"
@ -20,20 +21,9 @@ func (a *ApplicationStruct) AddConfigGroup(w http.ResponseWriter, r *http.Reques
return
}
// Get the application bound serviceIDs
availableServices := db.GetManager().TenantServiceDao().GetServiceIDsByAppID(appID)
// Judge whether the requested service ID is correct
set := make(map[string]struct{})
for _, s := range availableServices {
set[s.ServiceID] = struct{}{}
}
for _, sid := range configReq.ServiceIDs {
_, ok := set[sid]
if !ok {
logrus.Infof("The serviceID [%s] is not under the application or does not exist", sid)
httputil.ReturnBcodeError(r, w, bcode.ErrServiceNotFound)
return
}
if !CheckServiceExist(appID, configReq.ServiceIDs) {
httputil.ReturnBcodeError(r, w, bcode.ErrServiceNotFound)
return
}
// create app ConfigGroups
@ -44,3 +34,45 @@ func (a *ApplicationStruct) AddConfigGroup(w http.ResponseWriter, r *http.Reques
}
httputil.ReturnSuccess(r, w, app)
}
// UpdateConfigGroup -
func (a *ApplicationStruct) UpdateConfigGroup(w http.ResponseWriter, r *http.Request) {
var updateReq model.UpdateAppConfigGroupReq
configGroupname := chi.URLParam(r, "config_group_name")
appID := r.Context().Value(middleware.ContextKey("app_id")).(string)
if !httputil.ValidatorRequestStructAndErrorResponse(r, w, &updateReq, nil) {
return
}
if !CheckServiceExist(appID, updateReq.ServiceIDs) {
httputil.ReturnBcodeError(r, w, bcode.ErrServiceNotFound)
return
}
// update app ConfigGroups
app, err := handler.GetApplicationHandler().UpdateConfigGroup(appID, configGroupname, &updateReq)
if err != nil {
httputil.ReturnBcodeError(r, w, err)
return
}
httputil.ReturnSuccess(r, w, app)
}
// CheckServiceExist -
func CheckServiceExist(appID string, serviceIDs []string) bool {
// Get the application bound serviceIDs
availableServices := db.GetManager().TenantServiceDao().GetServiceIDsByAppID(appID)
// Judge whether the requested service ID is correct
set := make(map[string]struct{})
for _, s := range availableServices {
set[s.ServiceID] = struct{}{}
}
for _, sid := range serviceIDs {
_, ok := set[sid]
if !ok {
logrus.Infof("The serviceID [%s] is not under the application or does not exist", sid)
}
return ok
}
return false
}

View File

@ -69,7 +69,7 @@ func (a *ApplicationAction) AddConfigGroup(appID string, req *model.ApplicationC
return nil, err
}
appconfig, err := db.GetManager().AppConfigGroupDao().GetConfigByID(appID, req.ConfigGroupName)
appconfig, err := db.GetManager().AppConfigGroupDao().GetConfigGroupByID(appID, req.ConfigGroupName)
if err != nil {
return nil, err
}
@ -84,3 +84,70 @@ func (a *ApplicationAction) AddConfigGroup(appID string, req *model.ApplicationC
}
return resp, nil
}
// UpdateConfigGroup -
func (a *ApplicationAction) UpdateConfigGroup(appID, configGroupName string, req *model.UpdateAppConfigGroupReq) (*model.ApplicationConfigGroupResp, error) {
var serviceResp []dbmodel.ServiceConfigGroup
appconfig, err := db.GetManager().AppConfigGroupDao().GetConfigGroupByID(appID, configGroupName)
if err != nil {
return nil, err
}
services, err := db.GetManager().TenantServiceDao().GetServicesByServiceIDs(req.ServiceIDs)
if err != nil {
return nil, err
}
tx := db.GetManager().Begin()
// Update application configGroup-services
if err := db.GetManager().AppConfigGroupServiceDaoTransactions(tx).DeleteServiceConfig(appID, configGroupName); err != nil {
tx.Rollback()
return nil, err
}
for _, s := range services {
serviceConfigGroup := dbmodel.ServiceConfigGroup{
AppID: appID,
ConfigGroupName: configGroupName,
ServiceID: s.ServiceID,
ServiceAlias: s.ServiceAlias,
}
serviceResp = append(serviceResp, serviceConfigGroup)
if err := db.GetManager().AppConfigGroupServiceDaoTransactions(tx).AddModel(&serviceConfigGroup); err != nil {
tx.Rollback()
return nil, err
}
}
// Update application configGroup-configItem
if err := db.GetManager().AppConfigGroupItemDaoTransactions(tx).DeleteConfigGroupItem(appID, configGroupName); err != nil {
tx.Rollback()
return nil, err
}
for _, it := range req.ConfigItems {
configItem := &dbmodel.ConfigItem{
AppID: appID,
ConfigGroupName: configGroupName,
ItemKey: it.ItemKey,
ItemValue: it.ItemValue,
}
if err := db.GetManager().AppConfigGroupItemDaoTransactions(tx).AddModel(configItem); err != nil {
tx.Rollback()
return nil, err
}
}
if err := tx.Commit().Error; err != nil {
tx.Rollback()
return nil, err
}
// Build return data
var resp *model.ApplicationConfigGroupResp
resp = &model.ApplicationConfigGroupResp{
CreateTime: appconfig.CreatedAt,
AppID: appconfig.AppID,
ConfigGroupName: appconfig.ConfigGroupName,
DeployType: appconfig.DeployType,
ConfigItems: req.ConfigItems,
Services: serviceResp,
}
return resp, nil
}

View File

@ -55,7 +55,7 @@ func TestAddAppConfigGroup(t *testing.T) {
applicationConfigDao := daomock.NewMockAppConfigGroupDao(ctrl)
applicationConfigDao.EXPECT().AddModel(gomock.Any()).Return(nil)
applicationConfigDao.EXPECT().GetConfigByID(gomock.Any(), gomock.Any()).Return(config, nil)
applicationConfigDao.EXPECT().GetConfigGroupByID(gomock.Any(), gomock.Any()).Return(config, nil)
manager.EXPECT().AppConfigGroupDao().Return(applicationConfigDao).AnyTimes()
},
wanterr: false,

View File

@ -1688,3 +1688,9 @@ type ApplicationConfigGroupResp struct {
Services []dbmodel.ServiceConfigGroup `json:"services"`
ConfigItems []ConfigItem `json:"config_items"`
}
// UpdateAppConfigGroupReq -
type UpdateAppConfigGroupReq struct {
ServiceIDs []string `json:"service_ids"`
ConfigItems []ConfigItem `json:"config_items" validate:"required"`
}

View File

@ -78,17 +78,19 @@ type ApplicationDao interface {
//AppConfigGroupDao Application config group Dao
type AppConfigGroupDao interface {
Dao
GetConfigByID(appID, name string) (*model.ApplicationConfigGroup, error)
GetConfigGroupByID(appID, configGroupName string) (*model.ApplicationConfigGroup, error)
}
//AppConfigGroupServiceDao service config group Dao
type AppConfigGroupServiceDao interface {
Dao
DeleteServiceConfig(appID, configGroupName string) error
}
//AppConfigGroupItemDao Application config item group Dao
type AppConfigGroupItemDao interface {
Dao
DeleteConfigGroupItem(appID, configGroupName string) error
}
// VolumeTypeDao volume type dao

View File

@ -554,19 +554,19 @@ func (mr *MockAppConfigGroupDaoMockRecorder) UpdateModel(arg0 interface{}) *gomo
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateModel", reflect.TypeOf((*MockAppConfigGroupDao)(nil).UpdateModel), arg0)
}
// GetConfigByID mocks base method.
func (m *MockAppConfigGroupDao) GetConfigByID(appID, name string) (*model.ApplicationConfigGroup, error) {
// GetConfigGroupByID mocks base method.
func (m *MockAppConfigGroupDao) GetConfigGroupByID(appID, name string) (*model.ApplicationConfigGroup, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetConfigByID", appID, name)
ret := m.ctrl.Call(m, "GetConfigGroupByID", appID, name)
ret0, _ := ret[0].(*model.ApplicationConfigGroup)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetConfigByID indicates an expected call of GetConfigByID.
func (mr *MockAppConfigGroupDaoMockRecorder) GetConfigByID(appID, name interface{}) *gomock.Call {
// GetConfigGroupByID indicates an expected call of GetConfigGroupByID.
func (mr *MockAppConfigGroupDaoMockRecorder) GetConfigGroupByID(appID, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConfigByID", reflect.TypeOf((*MockAppConfigGroupDao)(nil).GetConfigByID), appID, name)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConfigGroupByID", reflect.TypeOf((*MockAppConfigGroupDao)(nil).GetConfigGroupByID), appID, name)
}
// MockAppConfigGroupServiceDao is a mock of AppConfigGroupServiceDao interface.

View File

@ -26,14 +26,13 @@ func (a *AppConfigGroupDaoImpl) AddModel(mo model.Interface) error {
//UpdateModel -
func (a *AppConfigGroupDaoImpl) UpdateModel(mo model.Interface) error {
// updateReq := mo.(*model.Application)
return nil
}
// GetConfigByID -
func (a *AppConfigGroupDaoImpl) GetConfigByID(appID, name string) (*model.ApplicationConfigGroup, error) {
// GetConfigGroupByID -
func (a *AppConfigGroupDaoImpl) GetConfigGroupByID(appID, configGroupName string) (*model.ApplicationConfigGroup, error) {
var oldApp model.ApplicationConfigGroup
if err := a.DB.Where("app_id = ? AND config_group_name = ?", appID, name).Find(&oldApp).Error; err != nil {
if err := a.DB.Where("app_id = ? AND config_group_name = ?", appID, configGroupName).Find(&oldApp).Error; err != nil {
return nil, err
}
return &oldApp, nil
@ -54,15 +53,19 @@ func (a *AppConfigGroupServiceDaoImpl) AddModel(mo model.Interface) error {
}
return err
}
return bcode.ErrApplicationConfigGroupExist
return bcode.ErrServiceConfigGroupExist
}
//UpdateModel -
func (a *AppConfigGroupServiceDaoImpl) UpdateModel(mo model.Interface) error {
// updateReq := mo.(*model.Application)
return nil
}
//DeleteServiceConfig -
func (a *AppConfigGroupServiceDaoImpl) DeleteServiceConfig(appID, configGroupName string) error {
return a.DB.Where("app_id = ? AND config_group_name = ?", appID, configGroupName).Delete(model.ServiceConfigGroup{}).Error
}
// AppConfigGroupItemDaoImpl -
type AppConfigGroupItemDaoImpl struct {
DB *gorm.DB
@ -78,11 +81,18 @@ func (a *AppConfigGroupItemDaoImpl) AddModel(mo model.Interface) error {
}
return err
}
return bcode.ErrApplicationConfigGroupExist
return bcode.ErrConfigItemExist
}
//UpdateModel -
func (a *AppConfigGroupItemDaoImpl) UpdateModel(mo model.Interface) error {
// updateReq := mo.(*model.Application)
return nil
updateReq := mo.(*model.ConfigItem)
return a.DB.Model(&model.ConfigItem{}).
Where("app_id = ? AND config_group_name = ? AND item_key = ?", updateReq.AppID, updateReq.ConfigGroupName, updateReq.ItemKey).
Update("item_value", updateReq.ItemValue).Error
}
//DeleteConfigGroupItem -
func (a *AppConfigGroupItemDaoImpl) DeleteConfigGroupItem(appID, configGroupName string) error {
return a.DB.Where("app_id = ? AND config_group_name = ?", appID, configGroupName).Delete(model.ConfigItem{}).Error
}

View File

@ -9,7 +9,8 @@ import (
"github.com/pkg/errors"
)
func TestAppConfigDaoAddModel(t *testing.T) {
// Test AppConfigGroup Dao
func TestAppConfigGroupDaoAddModel(t *testing.T) {
req := &model.ApplicationConfigGroup{
AppID: "appID",
ConfigGroupName: "configname",
@ -83,7 +84,7 @@ func TestAppConfigDaoAddModel(t *testing.T) {
}
}
func TestAppGetConfigByID(t *testing.T) {
func TestAppGetConfigGroupByID(t *testing.T) {
tests := []struct {
name string
appID string
@ -125,7 +126,7 @@ func TestAppGetConfigByID(t *testing.T) {
}
tc.mockFunc(mock)
resp, err := appConfigDaoImpl.GetConfigByID("appID", "name")
resp, err := appConfigDaoImpl.GetConfigGroupByID("appID", "name")
if (err != nil) != tc.wanterr {
t.Errorf("Unexpected error = %v, wantErr %v", err, tc.wanterr)
return
@ -138,6 +139,7 @@ func TestAppGetConfigByID(t *testing.T) {
}
}
// Test AppConfigGroup Service Dao
func TestAppConfigGroupServiceDaoAddModel(t *testing.T) {
req := &model.ServiceConfigGroup{
AppID: "appID",
@ -213,6 +215,57 @@ func TestAppConfigGroupServiceDaoAddModel(t *testing.T) {
}
}
func TestDeleteServiceConfig(t *testing.T) {
tests := []struct {
name, appID, configGroupName string
request *model.ConfigItem
mockFunc func(mock sqlmock.Sqlmock)
wanterr bool
}{
{
name: "delete success",
mockFunc: func(mock sqlmock.Sqlmock) {
mock.ExpectBegin()
mock.ExpectExec("DELETE").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1)).WillReturnError(nil)
mock.ExpectCommit()
},
wanterr: false,
},
{
name: "delete failed",
mockFunc: func(mock sqlmock.Sqlmock) {
mock.ExpectBegin()
mock.ExpectExec("DELETE").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnError(errors.New("delete failed"))
mock.ExpectCommit()
},
wanterr: true,
},
}
for i := range tests {
tc := tests[i]
t.Run(tc.name, func(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
gdb, _ := gorm.Open("mysql", db)
appConfigGroupServiceDaoImpl := &AppConfigGroupServiceDaoImpl{
DB: gdb,
}
tc.mockFunc(mock)
err = appConfigGroupServiceDaoImpl.DeleteServiceConfig(tc.appID, tc.configGroupName)
if (err != nil) != tc.wanterr {
t.Errorf("Unexpected error = %v, wantErr %v", err, tc.wanterr)
return
}
})
}
}
// Test AppConfigGroup Item Dao
func TestAppConfigGroupItemDaoAddModel(t *testing.T) {
req := &model.ConfigItem{
AppID: "appID",
@ -288,3 +341,61 @@ func TestAppConfigGroupItemDaoAddModel(t *testing.T) {
})
}
}
func TestAppConfigGroupItemDaoUpdateModel(t *testing.T) {
req := &model.ConfigItem{
AppID: "appID",
ConfigGroupName: "configname",
ItemKey: "key1",
ItemValue: "value1",
}
tests := []struct {
name string
request *model.ConfigItem
mockFunc func(mock sqlmock.Sqlmock)
wanterr bool
}{
{
name: "update config item success",
request: req,
mockFunc: func(mock sqlmock.Sqlmock) {
mock.ExpectBegin()
mock.ExpectExec("UPDATE").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1)).WillReturnError(nil)
mock.ExpectCommit()
},
wanterr: false,
},
{
name: "update config item failed",
request: req,
mockFunc: func(mock sqlmock.Sqlmock) {
mock.ExpectBegin()
mock.ExpectExec("UPDATE").WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg()).WillReturnError(errors.New("database error"))
mock.ExpectCommit()
},
wanterr: true,
},
}
for i := range tests {
tc := tests[i]
t.Run(tc.name, func(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
gdb, _ := gorm.Open("mysql", db)
configItemDaoImpl := &AppConfigGroupItemDaoImpl{
DB: gdb,
}
tc.mockFunc(mock)
err = configItemDaoImpl.UpdateModel(req)
if (err != nil) != tc.wanterr {
t.Errorf("Unexpected error = %v, wantErr %v", err, tc.wanterr)
return
}
})
}
}