fix: add plugin id conflict checker (#78)
This commit is contained in:
parent
f0c339d231
commit
376e563e4f
|
|
@ -60,6 +60,7 @@ import (
|
||||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
|
||||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/pkg/safego"
|
||||||
"github.com/coze-dev/coze-studio/backend/pkg/taskgroup"
|
"github.com/coze-dev/coze-studio/backend/pkg/taskgroup"
|
||||||
"github.com/coze-dev/coze-studio/backend/types/consts"
|
"github.com/coze-dev/coze-studio/backend/types/consts"
|
||||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||||
|
|
@ -183,18 +184,19 @@ func (a *APPApplicationService) DraftProjectDelete(ctx context.Context, req *pro
|
||||||
logs.CtxErrorf(ctx, "publish project '%d' failed, err=%v", req.ProjectID, err)
|
logs.CtxErrorf(ctx, "publish project '%d' failed, err=%v", req.ProjectID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.deleteAPPResources(ctx, req.ProjectID)
|
safego.Go(ctx, func() {
|
||||||
if err != nil {
|
// When an app is deleted, resource deletion is currently handled as a weak dependency, meaning some resources might not be deleted, but they will be inaccessible to the user.
|
||||||
logs.CtxErrorf(ctx, "delete app '%d' resources failed, err=%v", req.ProjectID, err)
|
// TODO:: Application resources need to check the deletion status of the application
|
||||||
}
|
a.deleteAPPResources(ctx, req.ProjectID)
|
||||||
|
})
|
||||||
|
|
||||||
resp = &projectAPI.DraftProjectDeleteResponse{}
|
resp = &projectAPI.DraftProjectDeleteResponse{}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APPApplicationService) deleteAPPResources(ctx context.Context, appID int64) (err error) {
|
func (a *APPApplicationService) deleteAPPResources(ctx context.Context, appID int64) {
|
||||||
err = plugin.PluginApplicationSVC.DeleteAPPAllPlugins(ctx, appID)
|
err := plugin.PluginApplicationSVC.DeleteAPPAllPlugins(ctx, appID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.CtxErrorf(ctx, "delete app '%d' plugins failed, err=%v", appID, err)
|
logs.CtxErrorf(ctx, "delete app '%d' plugins failed, err=%v", appID, err)
|
||||||
}
|
}
|
||||||
|
|
@ -218,8 +220,6 @@ func (a *APPApplicationService) deleteAPPResources(ctx context.Context, appID in
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.CtxErrorf(ctx, "delete app '%d' workflow failed, err=%v", appID, err)
|
logs.CtxErrorf(ctx, "delete app '%d' workflow failed, err=%v", appID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APPApplicationService) DraftProjectUpdate(ctx context.Context, req *projectAPI.DraftProjectUpdateRequest) (resp *projectAPI.DraftProjectUpdateResponse, err error) {
|
func (a *APPApplicationService) DraftProjectUpdate(ctx context.Context, req *projectAPI.DraftProjectUpdateRequest) (resp *projectAPI.DraftProjectUpdateResponse, err error) {
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,12 @@ package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
|
||||||
pluginConf "github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
|
pluginConf "github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/repository"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/repository"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/service"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/service"
|
||||||
|
|
@ -28,6 +31,9 @@ import (
|
||||||
user "github.com/coze-dev/coze-studio/backend/domain/user/service"
|
user "github.com/coze-dev/coze-studio/backend/domain/user/service"
|
||||||
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
|
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
|
||||||
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
|
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceComponents struct {
|
type ServiceComponents struct {
|
||||||
|
|
@ -68,6 +74,11 @@ func InitService(ctx context.Context, components *ServiceComponents) (*PluginApp
|
||||||
OAuthRepo: oauthRepo,
|
OAuthRepo: oauthRepo,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
err = checkIDExist(ctx, pluginSVC)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
PluginApplicationSVC.DomainSVC = pluginSVC
|
PluginApplicationSVC.DomainSVC = pluginSVC
|
||||||
PluginApplicationSVC.eventbus = components.EventBus
|
PluginApplicationSVC.eventbus = components.EventBus
|
||||||
PluginApplicationSVC.oss = components.OSS
|
PluginApplicationSVC.oss = components.OSS
|
||||||
|
|
@ -77,3 +88,51 @@ func InitService(ctx context.Context, components *ServiceComponents) (*PluginApp
|
||||||
|
|
||||||
return PluginApplicationSVC, nil
|
return PluginApplicationSVC, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkIDExist(ctx context.Context, pluginService service.PluginService) error {
|
||||||
|
pluginProducts := conf.GetAllPluginProducts()
|
||||||
|
|
||||||
|
pluginIDs := make([]int64, 0, len(pluginProducts))
|
||||||
|
var toolIDs []int64
|
||||||
|
for _, p := range pluginProducts {
|
||||||
|
pluginIDs = append(pluginIDs, p.Info.ID)
|
||||||
|
toolIDs = append(toolIDs, p.ToolIDs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginInfos, err := pluginService.MGetDraftPlugins(ctx, pluginIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(pluginInfos) > 0 {
|
||||||
|
conflictsIDs := make([]int64, 0, len(pluginInfos))
|
||||||
|
for _, p := range pluginInfos {
|
||||||
|
conflictsIDs = append(conflictsIDs, p.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorx.New(errno.ErrPluginIDExist,
|
||||||
|
errorx.KV("plugin_id", strings.Join(slices.Transform(conflictsIDs, func(id int64) string {
|
||||||
|
return strconv.FormatInt(id, 10)
|
||||||
|
}), ",")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools, err := pluginService.MGetDraftTools(ctx, toolIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tools) > 0 {
|
||||||
|
conflictsIDs := make([]int64, 0, len(tools))
|
||||||
|
for _, t := range tools {
|
||||||
|
conflictsIDs = append(conflictsIDs, t.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorx.New(errno.ErrToolIDExist,
|
||||||
|
errorx.KV("tool_id", strings.Join(slices.Transform(conflictsIDs, func(id int64) string {
|
||||||
|
return strconv.FormatInt(id, 10)
|
||||||
|
}), ",")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
|
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
|
||||||
"github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
|
"github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/model"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/model"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/query"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/query"
|
||||||
|
|
@ -88,7 +89,7 @@ func (p *PluginDraftDAO) getSelected(opt *PluginSelectedOption) (selected []fiel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PluginDraftDAO) Create(ctx context.Context, plugin *entity.PluginInfo) (pluginID int64, err error) {
|
func (p *PluginDraftDAO) Create(ctx context.Context, plugin *entity.PluginInfo) (pluginID int64, err error) {
|
||||||
id, err := p.idGen.GenID(ctx)
|
id, err := p.genPluginID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -117,6 +118,25 @@ func (p *PluginDraftDAO) Create(ctx context.Context, plugin *entity.PluginInfo)
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PluginDraftDAO) genPluginID(ctx context.Context) (id int64, err error) {
|
||||||
|
|
||||||
|
retryTimes := 5
|
||||||
|
for i := 0; i < retryTimes; i++ {
|
||||||
|
id, err = p.idGen.GenID(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, ok := conf.GetPluginProduct(id); !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i == retryTimes-1 {
|
||||||
|
return 0, fmt.Errorf("id %d is confilict with product plugin id.", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PluginDraftDAO) Get(ctx context.Context, pluginID int64, opt *PluginSelectedOption) (plugin *entity.PluginInfo, exist bool, err error) {
|
func (p *PluginDraftDAO) Get(ctx context.Context, pluginID int64, opt *PluginSelectedOption) (plugin *entity.PluginInfo, exist bool, err error) {
|
||||||
table := p.query.PluginDraft
|
table := p.query.PluginDraft
|
||||||
pl, err := table.WithContext(ctx).
|
pl, err := table.WithContext(ctx).
|
||||||
|
|
@ -262,7 +282,7 @@ func (p *PluginDraftDAO) Update(ctx context.Context, plugin *entity.PluginInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PluginDraftDAO) CreateWithTX(ctx context.Context, tx *query.QueryTx, plugin *entity.PluginInfo) (pluginID int64, err error) {
|
func (p *PluginDraftDAO) CreateWithTX(ctx context.Context, tx *query.QueryTx, plugin *entity.PluginInfo) (pluginID int64, err error) {
|
||||||
id, err := p.idGen.GenID(ctx)
|
id, err := p.genPluginID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
|
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
|
||||||
common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
|
common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/conf"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/entity"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/model"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/model"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/query"
|
"github.com/coze-dev/coze-studio/backend/domain/plugin/internal/dal/query"
|
||||||
|
|
@ -90,7 +91,8 @@ func (t *ToolDraftDAO) getSelected(opt *ToolSelectedOption) (selected []field.Ex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ToolDraftDAO) Create(ctx context.Context, tool *entity.ToolInfo) (toolID int64, err error) {
|
func (t *ToolDraftDAO) Create(ctx context.Context, tool *entity.ToolInfo) (toolID int64, err error) {
|
||||||
id, err := t.idGen.GenID(ctx)
|
|
||||||
|
id, err := t.genToolID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -111,6 +113,27 @@ func (t *ToolDraftDAO) Create(ctx context.Context, tool *entity.ToolInfo) (toolI
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *ToolDraftDAO) genToolID(ctx context.Context) (id int64, err error) {
|
||||||
|
|
||||||
|
retryTimes := 5
|
||||||
|
|
||||||
|
for i := 0; i < retryTimes; i++ {
|
||||||
|
id, err = t.idGen.GenID(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := conf.GetToolProduct(id); !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i == retryTimes-1 {
|
||||||
|
return 0, fmt.Errorf("id %d is confilict with product tool id.", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *ToolDraftDAO) Get(ctx context.Context, toolID int64) (tool *entity.ToolInfo, exist bool, err error) {
|
func (t *ToolDraftDAO) Get(ctx context.Context, toolID int64) (tool *entity.ToolInfo, exist bool, err error) {
|
||||||
table := t.query.ToolDraft
|
table := t.query.ToolDraft
|
||||||
tl, err := table.WithContext(ctx).
|
tl, err := table.WithContext(ctx).
|
||||||
|
|
@ -335,7 +358,7 @@ func (t *ToolDraftDAO) BatchCreateWithTX(ctx context.Context, tx *query.QueryTx,
|
||||||
tls := make([]*model.ToolDraft, 0, len(tools))
|
tls := make([]*model.ToolDraft, 0, len(tools))
|
||||||
|
|
||||||
for _, tool := range tools {
|
for _, tool := range tools {
|
||||||
id, err := t.idGen.GenID(ctx)
|
id, err := t.genToolID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ const (
|
||||||
ErrPluginToolsCheckFailed = 109000011
|
ErrPluginToolsCheckFailed = 109000011
|
||||||
ErrPluginParseToolRespFailed = 109000012
|
ErrPluginParseToolRespFailed = 109000012
|
||||||
ErrPluginOAuthFailed = 109000013
|
ErrPluginOAuthFailed = 109000013
|
||||||
|
ErrPluginIDExist = 109000014
|
||||||
|
ErrToolIDExist = 109000015
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -45,6 +47,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
|
code.Register(
|
||||||
|
ErrPluginIDExist,
|
||||||
|
"Plugin ID already exists : {plugin_id}",
|
||||||
|
code.WithAffectStability(false),
|
||||||
|
)
|
||||||
|
code.Register(
|
||||||
|
ErrToolIDExist,
|
||||||
|
"Tool ID already exists : {tool_id}",
|
||||||
|
code.WithAffectStability(false),
|
||||||
|
)
|
||||||
code.Register(
|
code.Register(
|
||||||
ErrPluginPermissionCode,
|
ErrPluginPermissionCode,
|
||||||
fmt.Sprintf("unauthorized access : {%s}", PluginMsgKey),
|
fmt.Sprintf("unauthorized access : {%s}", PluginMsgKey),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue