fix: add plugin id conflict checker (#78)

This commit is contained in:
junwen-lee 2025-07-28 14:07:03 +08:00 committed by GitHub
parent f0c339d231
commit 376e563e4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 127 additions and 12 deletions

View File

@ -60,6 +60,7 @@ import (
"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/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/types/consts"
"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)
}
err = a.deleteAPPResources(ctx, req.ProjectID)
if err != nil {
logs.CtxErrorf(ctx, "delete app '%d' resources failed, err=%v", req.ProjectID, err)
}
safego.Go(ctx, func() {
// 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.
// TODO:: Application resources need to check the deletion status of the application
a.deleteAPPResources(ctx, req.ProjectID)
})
resp = &projectAPI.DraftProjectDeleteResponse{}
return resp, nil
}
func (a *APPApplicationService) deleteAPPResources(ctx context.Context, appID int64) (err error) {
err = plugin.PluginApplicationSVC.DeleteAPPAllPlugins(ctx, appID)
func (a *APPApplicationService) deleteAPPResources(ctx context.Context, appID int64) {
err := plugin.PluginApplicationSVC.DeleteAPPAllPlugins(ctx, appID)
if err != nil {
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 {
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) {

View File

@ -18,9 +18,12 @@ package plugin
import (
"context"
"strconv"
"strings"
"gorm.io/gorm"
"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/service"
@ -28,6 +31,9 @@ import (
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/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 {
@ -68,6 +74,11 @@ func InitService(ctx context.Context, components *ServiceComponents) (*PluginApp
OAuthRepo: oauthRepo,
})
err = checkIDExist(ctx, pluginSVC)
if err != nil {
return nil, err
}
PluginApplicationSVC.DomainSVC = pluginSVC
PluginApplicationSVC.eventbus = components.EventBus
PluginApplicationSVC.oss = components.OSS
@ -77,3 +88,51 @@ func InitService(ctx context.Context, components *ServiceComponents) (*PluginApp
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
}

View File

@ -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/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/internal/dal/model"
"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) {
id, err := p.idGen.GenID(ctx)
id, err := p.genPluginID(ctx)
if err != nil {
return 0, err
}
@ -117,6 +118,25 @@ func (p *PluginDraftDAO) Create(ctx context.Context, plugin *entity.PluginInfo)
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) {
table := p.query.PluginDraft
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) {
id, err := p.idGen.GenID(ctx)
id, err := p.genPluginID(ctx)
if err != nil {
return 0, err
}

View File

@ -27,6 +27,7 @@ import (
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
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/internal/dal/model"
"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) {
id, err := t.idGen.GenID(ctx)
id, err := t.genToolID(ctx)
if err != nil {
return 0, err
}
@ -111,6 +113,27 @@ func (t *ToolDraftDAO) Create(ctx context.Context, tool *entity.ToolInfo) (toolI
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) {
table := t.query.ToolDraft
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))
for _, tool := range tools {
id, err := t.idGen.GenID(ctx)
id, err := t.genToolID(ctx)
if err != nil {
return nil, err
}

View File

@ -38,6 +38,8 @@ const (
ErrPluginToolsCheckFailed = 109000011
ErrPluginParseToolRespFailed = 109000012
ErrPluginOAuthFailed = 109000013
ErrPluginIDExist = 109000014
ErrToolIDExist = 109000015
)
const (
@ -45,6 +47,17 @@ const (
)
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(
ErrPluginPermissionCode,
fmt.Sprintf("unauthorized access : {%s}", PluginMsgKey),