154 lines
4.6 KiB
Go
154 lines
4.6 KiB
Go
package integration
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
|
|
integrationbiz "kra/internal/biz/integration"
|
|
"kra/pkg/database/migration"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func Migrations() []migration.Step {
|
|
return []migration.Step{
|
|
{ID: "202608200001_data_infrastructure", Migrate: func(db *gorm.DB) error {
|
|
return migration.CreateMissingTables(db, &ConfigPO{})
|
|
}},
|
|
{ID: "202608210001_communication_integration_defaults", Migrate: ensureCommunicationIntegrationConfigs},
|
|
{ID: "202608200004_payment_defaults", Migrate: ensurePaymentIntegrationConfigs},
|
|
{ID: "202608290004_kafka_integration_default", Migrate: ensureKafkaIntegrationConfig},
|
|
{ID: "202608290005_communication_integration_default_upgrade", Migrate: upgradeCommunicationIntegrationDefaults},
|
|
}
|
|
}
|
|
|
|
func ensureCommunicationIntegrationConfigs(db *gorm.DB) error {
|
|
defaults := []struct{ kind, provider string }{
|
|
{integrationbiz.IntegrationKindMQ, "emqx"},
|
|
{integrationbiz.IntegrationKindMQ, "kafka"},
|
|
{integrationbiz.IntegrationKindMQ, "rabbitmq"},
|
|
{integrationbiz.IntegrationKindWebSocket, "melody"},
|
|
}
|
|
for _, item := range defaults {
|
|
if err := ensureIntegrationConfig(db, item.kind, item.provider); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ensureKafkaIntegrationConfig(db *gorm.DB) error {
|
|
return ensureIntegrationConfig(db, integrationbiz.IntegrationKindMQ, "kafka")
|
|
}
|
|
|
|
func ensureIntegrationConfig(db *gorm.DB, kind, provider string) error {
|
|
var row ConfigPO
|
|
err := db.Where("kind = ? AND provider = ?", kind, provider).First(&row).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
values, marshalErr := json.Marshal(integrationbiz.DefaultIntegrationConfig(kind, provider))
|
|
if marshalErr != nil {
|
|
return marshalErr
|
|
}
|
|
return db.Create(&ConfigPO{Kind: kind, Provider: provider, Enabled: false, Config: string(values)}).Error
|
|
}
|
|
return err
|
|
}
|
|
|
|
func upgradeCommunicationIntegrationDefaults(db *gorm.DB) error {
|
|
for _, kind := range []string{integrationbiz.IntegrationKindMQ, integrationbiz.IntegrationKindWebSocket} {
|
|
for _, definition := range integrationbiz.IntegrationDefinitions(kind) {
|
|
var row ConfigPO
|
|
err := db.Where("kind = ? AND provider = ?", kind, definition.Provider).First(&row).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
values := integrationObject(json.RawMessage(row.Config))
|
|
changed := false
|
|
for key, value := range definition.Defaults {
|
|
if _, exists := values[key]; !exists {
|
|
values[key] = value
|
|
changed = true
|
|
}
|
|
}
|
|
for _, field := range definition.Fields {
|
|
if !field.Required || !emptyIntegrationConfigValue(values[field.Key]) || emptyIntegrationConfigValue(definition.Defaults[field.Key]) {
|
|
continue
|
|
}
|
|
values[field.Key] = definition.Defaults[field.Key]
|
|
changed = true
|
|
}
|
|
if _, exists := values["enabled"]; exists {
|
|
delete(values, "enabled")
|
|
changed = true
|
|
}
|
|
if !changed {
|
|
continue
|
|
}
|
|
encoded, marshalErr := json.Marshal(values)
|
|
if marshalErr != nil {
|
|
return marshalErr
|
|
}
|
|
if err := db.Model(&row).Update("config", string(encoded)).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func emptyIntegrationConfigValue(value any) bool {
|
|
switch typed := value.(type) {
|
|
case nil:
|
|
return true
|
|
case string:
|
|
return strings.TrimSpace(typed) == ""
|
|
case []any:
|
|
return len(typed) == 0
|
|
case []string:
|
|
return len(typed) == 0
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func ensurePaymentIntegrationConfigs(db *gorm.DB) error {
|
|
for _, definition := range integrationbiz.IntegrationDefinitions(integrationbiz.IntegrationKindPayment) {
|
|
provider := definition.Provider
|
|
var row ConfigPO
|
|
err := db.Where("kind = ? AND provider = ?", integrationbiz.IntegrationKindPayment, provider).First(&row).Error
|
|
defaults := integrationbiz.DefaultIntegrationConfig(integrationbiz.IntegrationKindPayment, provider)
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
encoded, marshalErr := json.Marshal(defaults)
|
|
if marshalErr != nil {
|
|
return marshalErr
|
|
}
|
|
if err := db.Create(&ConfigPO{Kind: integrationbiz.IntegrationKindPayment, Provider: provider, Config: string(encoded)}).Error; err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
values := integrationObject(json.RawMessage(row.Config))
|
|
merged := integrationbiz.MergeIntegrationDefaults(defaults, values)
|
|
changed := !reflect.DeepEqual(values, merged)
|
|
values = merged
|
|
if changed {
|
|
encoded, marshalErr := json.Marshal(values)
|
|
if marshalErr != nil {
|
|
return marshalErr
|
|
}
|
|
if err := db.Model(&row).Update("config", string(encoded)).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|