// Package transform ... // // Description : 数据迁移 // // Author : go_developer@163.com<白茶清欢> // // Date : 2021-11-30 3:57 下午 package transform import ( "errors" "fmt" "git.zhangdeman.cn/zhangdeman/center-config/define/form" "git.zhangdeman.cn/zhangdeman/center-config/define/model" "git.zhangdeman.cn/zhangdeman/center-config/manager" ) // MigrateOption 迁移的配置选项 // // Author : go_developer@163.com<白茶清欢> // // Date : 5:41 下午 2021/11/30 type MigrateOption struct { Force bool // 强制迁移 } // SetMigrateOption 设置迁移选项 type SetMigrateOption func(mo *MigrateOption) // WithOptionForce 配置是否强制迁移 // // Author : go_developer@163.com<白茶清欢> // // Date : 5:43 下午 2021/11/30 func WithOptionForce(force bool) SetMigrateOption { return func(mo *MigrateOption) { mo.Force = force } } // Migrate 数据迁移 // // Author : go_developer@163.com<白茶清欢> // // Date : 3:58 下午 2021/11/30 func Migrate(dataDriver ITransform, optionList ...SetMigrateOption) error { if nil == dataDriver { return errors.New("data driver is nil") } namespace := dataDriver.GetNamespace() if len(namespace) == 0 { return errors.New("数据驱动器中, 未设置namespace") } mo := &MigrateOption{} for _, o := range optionList { o(mo) } var ( sourceData map[string]string err error namespaceDetail *model.Namespace hasCreateConfigList []*model.Config ) if sourceData, err = dataDriver.GetSourceData(); nil != err { return err } namespaceID := int64(0) if namespaceDetail, err = manager.Namespace.GetNamespaceDetail(0, namespace); nil == err && nil != namespaceDetail { namespaceID = namespaceDetail.ID if !mo.Force { // 非强制迁移, 报错 return fmt.Errorf("当前命名空间 %s(%v) 已存在, 迁移存在风险, 若要强制迁移, 请使用force=true", namespace, namespaceDetail.ID) } // 强制迁移, 需要查询已有的key, 用于判断后续是 if hasCreateConfigList, err = manager.Config.GetNamespaceConfig(namespaceDetail.ID); nil != err { return fmt.Errorf("当前命名空间 %s(%v) 已存在, 强制迁移查询已存在的配置失败: %s", namespace, namespaceDetail.ID, err.Error()) } } if namespaceID == 0 { // 创建命名空间 if err = manager.Namespace.Create(&form.CreateNamespace{ Namespace: namespace, Name: "apollo迁移-" + namespace, Description: "从apollo迁移过来的配置", CreateUserID: "migrate-script", }); nil != err { return errors.New("创建命名空间失败 : " + err.Error()) } } if nil != namespaceDetail && namespaceDetail.Status != model.NamespaceStatusNormal { // 激活命名空间 if err = manager.Namespace.Active(&form.ActiveNamespace{ NamespaceID: 0, Namespace: namespace, UpdateUserID: "system-script", }); nil != err { return errors.New("激活命名空间失败 : " + err.Error()) } } hasCreateConfigTable := make(map[string]*model.Config) for _, item := range hasCreateConfigList { hasCreateConfigTable[item.Field] = item } // 迁移配置 for key, value := range sourceData { hasSetConfig, exist := hasCreateConfigTable[key] if !exist { if err = manager.Config.Create(&form.CreateOrUpdateConfig{ NamespaceID: 0, Namespace: namespace, Key: key, Value: value, OperateUserID: "system-script", Description: fmt.Sprintf("从apollo-%s-%s迁移过来的配置", namespace, key), }, namespaceDetail); nil != err { dataDriver.MigrateKeyFailCallback(namespace, key, value, err) } continue } // 已存在更新,执行下面的逻辑 if hasSetConfig.Value == value { // 已存在值和目标值一致,无需处理 continue } if err = manager.Config.Update(&form.CreateOrUpdateConfig{ NamespaceID: namespaceDetail.ID, Namespace: namespace, Key: key, Value: value, OperateUserID: "system-script", Description: fmt.Sprintf("从apollo-%s-%s迁移过来的配置", namespace, key), }, namespaceDetail, hasSetConfig); nil != err { dataDriver.MigrateKeyFailCallback(namespace, key, value, err) } } return nil }