diff --git a/compose/dalutils/records.go b/compose/dalutils/records.go index ebf14dbd7..d3dd211d9 100644 --- a/compose/dalutils/records.go +++ b/compose/dalutils/records.go @@ -101,8 +101,8 @@ func WalkIterator(ctx context.Context, iter dal.Iterator, mod *types.Module, f f func prepFilter(filter types.RecordFilter, mod *types.Module) (dalFilter filter.Filter) { dalFilter = filter.ToFilter() - if mod.ModelConfig.Partitioned { - dalFilter = filter.ToConstraintedFilter(mod.ModelConfig.Constraints) + if mod.Config.DAL.Partitioned { + dalFilter = filter.ToConstraintedFilter(mod.Config.DAL.Constraints) } return @@ -253,15 +253,15 @@ func recToGetters(rr ...*types.Record) (out []dal.ValueGetter) { } func recCreateCapabilities(m *types.Module) (out capabilities.Set) { - return capabilities.CreateCapabilities(m.ModelConfig.Capabilities...) + return capabilities.CreateCapabilities(m.Config.DAL.Capabilities...) } func recUpdateCapabilities(m *types.Module) (out capabilities.Set) { - return capabilities.UpdateCapabilities(m.ModelConfig.Capabilities...) + return capabilities.UpdateCapabilities(m.Config.DAL.Capabilities...) } func recDeleteCapabilities(m *types.Module) (out capabilities.Set) { - return capabilities.DeleteCapabilities(m.ModelConfig.Capabilities...) + return capabilities.DeleteCapabilities(m.Config.DAL.Capabilities...) } func recFilterCapabilities(f types.RecordFilter) (out capabilities.Set) { @@ -285,10 +285,10 @@ func recFilterCapabilities(f types.RecordFilter) (out capabilities.Set) { } func recSearchCapabilities(m *types.Module, f types.RecordFilter) (out capabilities.Set) { - return capabilities.SearchCapabilities(m.ModelConfig.Capabilities...). + return capabilities.SearchCapabilities(m.Config.DAL.Capabilities...). Union(recFilterCapabilities(f)) } func recLookupCapabilities(m *types.Module) (out capabilities.Set) { - return capabilities.LookupCapabilities(m.ModelConfig.Capabilities...) + return capabilities.LookupCapabilities(m.Config.DAL.Capabilities...) } diff --git a/compose/module-field.cue b/compose/module-field.cue index ef697f0c6..9e46bdbd3 100644 --- a/compose/module-field.cue +++ b/compose/module-field.cue @@ -20,7 +20,7 @@ moduleField: schema.#Resource & { label: {sortable: true} options: { goType: "types.ModuleFieldOptions" } encoding_strategy: { goType: "types.EncodingStrategy" } - privacy: { goType: "types.DataPrivacyConfig" } + privacy: { goType: "types.ModuleFieldConfigDataPrivacy" } private: { goType: "bool", storeIdent: "is_private" } required: { goType: "bool", storeIdent: "is_required" } visible: { goType: "bool", storeIdent: "is_visible" } diff --git a/compose/module.cue b/compose/module.cue index 6fb90418f..254467b03 100644 --- a/compose/module.cue +++ b/compose/module.cue @@ -14,8 +14,7 @@ module: schema.#Resource & { id: schema.IdField handle: schema.HandleField meta: { goType: "rawJson" } - model_config: { goType: "types.ModelConfig" } - privacy: { goType: "types.DataPrivacyConfig" } + config: { goType: "types.ModuleConfig" } fields: { goType: "types.ModuleFieldSet", store: false } namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" } name: {sortable: true} diff --git a/compose/rest.yaml b/compose/rest.yaml index a30986d99..abbe1deb1 100644 --- a/compose/rest.yaml +++ b/compose/rest.yaml @@ -548,36 +548,12 @@ endpoints: path: "/" parameters: post: - - type: string - name: name - required: true - title: Module Name - - type: string - name: handle - required: false - title: Module handle - - type: types.ModelConfig - name: modelConfig - required: false - title: modelConfig - parser: types.ParseModelConfig - - type: types.DataPrivacyConfig - name: privacy - required: false - title: Data privacy config - parser: types.ParseDataPrivacyConfig - - type: types.ModuleFieldSet - name: fields - required: true - title: Fields JSON - - type: sqlxTypes.JSONText - name: meta - required: true - title: Module meta data - - type: map[string]string - name: labels - title: Module labels - parser: label.ParseStrings + - { type: "string", name: name, title: Name, required: true } + - { type: "string", name: handle, title: Handle } + - { type: "types.ModuleConfig", name: config, title: Configuration, parser: types.ParseModuleConfig } + - { type: "sqlxTypes.JSONText", name: meta, title: Meta data, required: true } + - { type: "types.ModuleFieldSet", name: fields, title: Fields, required: true } + - { type: "map[string]string", name: labels, title: Labels, parser: label.ParseStrings } - name: read method: GET title: Read module @@ -599,40 +575,13 @@ endpoints: required: true title: Module ID post: - - type: string - name: name - required: true - title: Module Name - - type: string - name: handle - required: false - title: Module Handle - - type: types.ModelConfig - name: modelConfig - required: false - title: modelConfig - parser: types.ParseModelConfig - - type: types.DataPrivacyConfig - name: privacy - required: false - title: Data privacy config - parser: types.ParseDataPrivacyConfig - - type: types.ModuleFieldSet - name: fields - required: true - title: Fields JSON - - type: sqlxTypes.JSONText - name: meta - required: true - title: Module meta data - - type: "*time.Time" - name: updatedAt - required: false - title: Last update (or creation) date - - type: map[string]string - name: labels - title: Module labels - parser: label.ParseStrings + - { type: "string", name: name, title: Name, required: true } + - { type: "string", name: handle, title: Handle } + - { type: "types.ModuleConfig", name: config, title: Configuration, parser: types.ParseModuleConfig } + - { type: "sqlxTypes.JSONText", name: meta, title: Meta data, required: true } + - { type: "types.ModuleFieldSet", name: fields, title: Fields, required: true } + - { type: "map[string]string", name: labels, title: Labels, parser: label.ParseStrings } + - { type: "*time.Time", name: updatedAt, title: Last update (or creation) date } - name: delete method: DELETE title: Delete module diff --git a/compose/rest/data_privacy.go b/compose/rest/data_privacy.go index ed15303f6..c6b9c4f82 100644 --- a/compose/rest/data_privacy.go +++ b/compose/rest/data_privacy.go @@ -75,7 +75,7 @@ func (ctrl *DataPrivacy) RecordList(ctx context.Context, r *request.DataPrivacyR for _, s := range ss { // Skip the ones we don't want - if hasReqConns && !reqConns[s.Module.ModelConfig.ConnectionID] { + if hasReqConns && !reqConns[s.Module.Config.DAL.ConnectionID] { continue } diff --git a/compose/rest/module.go b/compose/rest/module.go index 117b72940..705989cae 100644 --- a/compose/rest/module.go +++ b/compose/rest/module.go @@ -109,8 +109,7 @@ func (ctrl *Module) Create(ctx context.Context, r *request.ModuleCreate) (interf err error mod = &types.Module{ NamespaceID: r.NamespaceID, - ModelConfig: r.ModelConfig, - Privacy: r.Privacy, + Config: r.Config, Name: r.Name, Handle: r.Handle, Fields: r.Fields, @@ -129,8 +128,7 @@ func (ctrl *Module) Update(ctx context.Context, r *request.ModuleUpdate) (interf mod = &types.Module{ ID: r.ModuleID, NamespaceID: r.NamespaceID, - ModelConfig: r.ModelConfig, - Privacy: r.Privacy, + Config: r.Config, Name: r.Name, Handle: r.Handle, Fields: r.Fields, diff --git a/compose/rest/request/module.go b/compose/rest/request/module.go index b9845279c..bb15560f4 100644 --- a/compose/rest/request/module.go +++ b/compose/rest/request/module.go @@ -88,37 +88,32 @@ type ( // Name POST parameter // - // Module Name + // Name Name string // Handle POST parameter // - // Module handle + // Handle Handle string - // ModelConfig POST parameter + // Config POST parameter // - // modelConfig - ModelConfig types.ModelConfig - - // Privacy POST parameter - // - // Data privacy config - Privacy types.DataPrivacyConfig - - // Fields POST parameter - // - // Fields JSON - Fields types.ModuleFieldSet + // Configuration + Config types.ModuleConfig // Meta POST parameter // - // Module meta data + // Meta data Meta sqlxTypes.JSONText + // Fields POST parameter + // + // Fields + Fields types.ModuleFieldSet + // Labels POST parameter // - // Module labels + // Labels Labels map[string]string } @@ -147,43 +142,38 @@ type ( // Name POST parameter // - // Module Name + // Name Name string // Handle POST parameter // - // Module Handle + // Handle Handle string - // ModelConfig POST parameter + // Config POST parameter // - // modelConfig - ModelConfig types.ModelConfig - - // Privacy POST parameter - // - // Data privacy config - Privacy types.DataPrivacyConfig - - // Fields POST parameter - // - // Fields JSON - Fields types.ModuleFieldSet + // Configuration + Config types.ModuleConfig // Meta POST parameter // - // Module meta data + // Meta data Meta sqlxTypes.JSONText + // Fields POST parameter + // + // Fields + Fields types.ModuleFieldSet + + // Labels POST parameter + // + // Labels + Labels map[string]string + // UpdatedAt POST parameter // // Last update (or creation) date UpdatedAt *time.Time - - // Labels POST parameter - // - // Module labels - Labels map[string]string } ModuleDelete struct { @@ -391,10 +381,9 @@ func (r ModuleCreate) Auditable() map[string]interface{} { "namespaceID": r.NamespaceID, "name": r.Name, "handle": r.Handle, - "modelConfig": r.ModelConfig, - "privacy": r.Privacy, - "fields": r.Fields, + "config": r.Config, "meta": r.Meta, + "fields": r.Fields, "labels": r.Labels, } } @@ -415,18 +404,8 @@ func (r ModuleCreate) GetHandle() string { } // Auditable returns all auditable/loggable parameters -func (r ModuleCreate) GetModelConfig() types.ModelConfig { - return r.ModelConfig -} - -// Auditable returns all auditable/loggable parameters -func (r ModuleCreate) GetPrivacy() types.DataPrivacyConfig { - return r.Privacy -} - -// Auditable returns all auditable/loggable parameters -func (r ModuleCreate) GetFields() types.ModuleFieldSet { - return r.Fields +func (r ModuleCreate) GetConfig() types.ModuleConfig { + return r.Config } // Auditable returns all auditable/loggable parameters @@ -434,6 +413,11 @@ func (r ModuleCreate) GetMeta() sqlxTypes.JSONText { return r.Meta } +// Auditable returns all auditable/loggable parameters +func (r ModuleCreate) GetFields() types.ModuleFieldSet { + return r.Fields +} + // Auditable returns all auditable/loggable parameters func (r ModuleCreate) GetLabels() map[string]string { return r.Labels @@ -474,25 +458,13 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) { } } - if val, ok := req.MultipartForm.Value["modelConfig[]"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + if val, ok := req.MultipartForm.Value["config[]"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } - } else if val, ok := req.MultipartForm.Value["modelConfig"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) - if err != nil { - return err - } - } - - if val, ok := req.MultipartForm.Value["privacy[]"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) - if err != nil { - return err - } - } else if val, ok := req.MultipartForm.Value["privacy"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) + } else if val, ok := req.MultipartForm.Value["config"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } @@ -540,25 +512,20 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) { } } - if val, ok := req.Form["modelConfig[]"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + if val, ok := req.Form["config[]"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } - } else if val, ok := req.Form["modelConfig"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + } else if val, ok := req.Form["config"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } } - if val, ok := req.Form["privacy[]"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) - if err != nil { - return err - } - } else if val, ok := req.Form["privacy"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) + if val, ok := req.Form["meta"]; ok && len(val) > 0 { + r.Meta, err = payload.ParseJSONTextWithErr(val[0]) if err != nil { return err } @@ -571,13 +538,6 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) { // } //} - if val, ok := req.Form["meta"]; ok && len(val) > 0 { - r.Meta, err = payload.ParseJSONTextWithErr(val[0]) - if err != nil { - return err - } - } - if val, ok := req.Form["labels[]"]; ok { r.Labels, err = label.ParseStrings(val) if err != nil { @@ -665,12 +625,11 @@ func (r ModuleUpdate) Auditable() map[string]interface{} { "moduleID": r.ModuleID, "name": r.Name, "handle": r.Handle, - "modelConfig": r.ModelConfig, - "privacy": r.Privacy, - "fields": r.Fields, + "config": r.Config, "meta": r.Meta, - "updatedAt": r.UpdatedAt, + "fields": r.Fields, "labels": r.Labels, + "updatedAt": r.UpdatedAt, } } @@ -695,18 +654,8 @@ func (r ModuleUpdate) GetHandle() string { } // Auditable returns all auditable/loggable parameters -func (r ModuleUpdate) GetModelConfig() types.ModelConfig { - return r.ModelConfig -} - -// Auditable returns all auditable/loggable parameters -func (r ModuleUpdate) GetPrivacy() types.DataPrivacyConfig { - return r.Privacy -} - -// Auditable returns all auditable/loggable parameters -func (r ModuleUpdate) GetFields() types.ModuleFieldSet { - return r.Fields +func (r ModuleUpdate) GetConfig() types.ModuleConfig { + return r.Config } // Auditable returns all auditable/loggable parameters @@ -715,8 +664,8 @@ func (r ModuleUpdate) GetMeta() sqlxTypes.JSONText { } // Auditable returns all auditable/loggable parameters -func (r ModuleUpdate) GetUpdatedAt() *time.Time { - return r.UpdatedAt +func (r ModuleUpdate) GetFields() types.ModuleFieldSet { + return r.Fields } // Auditable returns all auditable/loggable parameters @@ -724,6 +673,11 @@ func (r ModuleUpdate) GetLabels() map[string]string { return r.Labels } +// Auditable returns all auditable/loggable parameters +func (r ModuleUpdate) GetUpdatedAt() *time.Time { + return r.UpdatedAt +} + // Fill processes request and fills internal variables func (r *ModuleUpdate) Fill(req *http.Request) (err error) { @@ -759,25 +713,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { } } - if val, ok := req.MultipartForm.Value["modelConfig[]"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + if val, ok := req.MultipartForm.Value["config[]"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } - } else if val, ok := req.MultipartForm.Value["modelConfig"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) - if err != nil { - return err - } - } - - if val, ok := req.MultipartForm.Value["privacy[]"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) - if err != nil { - return err - } - } else if val, ok := req.MultipartForm.Value["privacy"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) + } else if val, ok := req.MultipartForm.Value["config"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } @@ -790,13 +732,6 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { } } - if val, ok := req.MultipartForm.Value["updatedAt"]; ok && len(val) > 0 { - r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0]) - if err != nil { - return err - } - } - if val, ok := req.MultipartForm.Value["labels[]"]; ok { r.Labels, err = label.ParseStrings(val) if err != nil { @@ -808,6 +743,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { return err } } + + if val, ok := req.MultipartForm.Value["updatedAt"]; ok && len(val) > 0 { + r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0]) + if err != nil { + return err + } + } } } @@ -832,25 +774,20 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { } } - if val, ok := req.Form["modelConfig[]"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + if val, ok := req.Form["config[]"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } - } else if val, ok := req.Form["modelConfig"]; ok { - r.ModelConfig, err = types.ParseModelConfig(val) + } else if val, ok := req.Form["config"]; ok { + r.Config, err = types.ParseModuleConfig(val) if err != nil { return err } } - if val, ok := req.Form["privacy[]"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) - if err != nil { - return err - } - } else if val, ok := req.Form["privacy"]; ok { - r.Privacy, err = types.ParseDataPrivacyConfig(val) + if val, ok := req.Form["meta"]; ok && len(val) > 0 { + r.Meta, err = payload.ParseJSONTextWithErr(val[0]) if err != nil { return err } @@ -863,20 +800,6 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { // } //} - if val, ok := req.Form["meta"]; ok && len(val) > 0 { - r.Meta, err = payload.ParseJSONTextWithErr(val[0]) - if err != nil { - return err - } - } - - if val, ok := req.Form["updatedAt"]; ok && len(val) > 0 { - r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0]) - if err != nil { - return err - } - } - if val, ok := req.Form["labels[]"]; ok { r.Labels, err = label.ParseStrings(val) if err != nil { @@ -888,6 +811,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) { return err } } + + if val, ok := req.Form["updatedAt"]; ok && len(val) > 0 { + r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0]) + if err != nil { + return err + } + } } { diff --git a/compose/service/module.go b/compose/service/module.go index 36b976150..4c72dcf83 100644 --- a/compose/service/module.go +++ b/compose/service/module.go @@ -295,15 +295,15 @@ func (svc module) procDal(m *types.Module) { return } - ii := svc.dal.SearchModelIssues(m.ModelConfig.ConnectionID, m.ID) + ii := svc.dal.SearchModelIssues(m.Config.DAL.ConnectionID, m.ID) if len(ii) == 0 { - m.ModelConfig.Issues = nil + m.Config.DAL.Issues = nil return } - m.ModelConfig.Issues = make([]string, len(ii)) + m.Config.DAL.Issues = make([]string, len(ii)) for i, err := range ii { - m.ModelConfig.Issues[i] = err.Error() + m.Config.DAL.Issues[i] = err.Error() } } @@ -453,7 +453,7 @@ func (svc module) FindSensitive(ctx context.Context, filter types.PrivacyModuleF } for _, m := range mm { - cMeta, err := svc.dal.GetConnectionMeta(ctx, m.ModelConfig.ConnectionID) + cMeta, err := svc.dal.GetConnectionMeta(ctx, m.Config.DAL.ConnectionID) if err != nil { return err } @@ -534,7 +534,24 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act } if changes&moduleChanged > 0 { - if old.ModelConfig.ConnectionID != m.ModelConfig.ConnectionID { + { + // properly resolve connection ID 0 to the actual ID of the default connection + var defConn dal.ConnectionMeta + defConn, err = svc.dal.GetConnectionMeta(ctx, 0) + if err != nil { + return err + + } + + if old.Config.DAL.ConnectionID == 0 { + old.Config.DAL.ConnectionID = defConn.ConnectionID + } + if m.Config.DAL.ConnectionID == 0 { + m.Config.DAL.ConnectionID = defConn.ConnectionID + } + } + + if old.Config.DAL.ConnectionID != m.Config.DAL.ConnectionID { return fmt.Errorf("unable to switch connection for existing models: run data migration") } @@ -551,7 +568,7 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act // @todo rethink how model issues and attempted module update with records should interact. // this is a temporary solution but should be re-thinked. - modelIssues := svc.dal.SearchModelIssues(m.ModelConfig.ConnectionID, m.ID) + modelIssues := svc.dal.SearchModelIssues(m.Config.DAL.ConnectionID, m.ID) if len(modelIssues) == 0 { if set, _, err = dalutils.ComposeRecordsList(ctx, svc.dal, m, types.RecordFilter{Paging: filter.Paging{Limit: 1}, Check: func(r *types.Record) (bool, error) { return true, nil }}); err != nil { return err @@ -718,14 +735,9 @@ func (svc module) handleUpdate(ctx context.Context, upd *types.Module) moduleUpd } - if !reflect.DeepEqual(res.ModelConfig, upd.ModelConfig) { + if !reflect.DeepEqual(res.Config, upd.Config) { changes |= moduleChanged - res.ModelConfig = upd.ModelConfig - } - - if !reflect.DeepEqual(res.Privacy, upd.Privacy) { - changes |= moduleChanged - res.Privacy = upd.Privacy + res.Config = upd.Config } // @todo make field-change detection more optimal @@ -1148,7 +1160,7 @@ func dalAttributeReplace(ctx context.Context, dmm dalModelManager, ns *types.Nam // Removes a connection from DAL service func DalModelRemove(ctx context.Context, dmm dalModelManager, mm ...*types.Module) (err error) { for _, m := range mm { - if err = dmm.RemoveModel(ctx, m.ModelConfig.ConnectionID, m.ID); err != nil { + if err = dmm.RemoveModel(ctx, m.Config.DAL.ConnectionID, m.ID); err != nil { return err } } @@ -1188,14 +1200,14 @@ func moduleToModel(ctx context.Context, dmm dalModelManager, ns *types.Namespace Resource: mod.RbacResource(), ResourceID: mod.ID, ResourceType: types.ModuleResourceType, - SensitivityLevel: mod.Privacy.SensitivityLevel, - Capabilities: mod.ModelConfig.Capabilities, + SensitivityLevel: mod.Config.Privacy.SensitivityLevel, + Capabilities: mod.Config.DAL.Capabilities, } // - make the model ident ident := cm.DefaultModelIdent - if mod.ModelConfig.Partitioned { - tpl := mod.ModelConfig.PartitionFormat + if mod.Config.DAL.Partitioned { + tpl := mod.Config.DAL.PartitionFormat if tpl == "" { tpl = cm.DefaultPartitionFormat } @@ -1249,7 +1261,7 @@ func moduleFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta, ns *ty // moduleSystemFieldsToAttributes converts all system-defined module fields to attributes func moduleSystemFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta, ns *types.Namespace, mod *types.Module) (out dal.AttributeSet, err error) { - if mod.ModelConfig.Partitioned { + if mod.Config.DAL.Partitioned { return partitionedModuleSystemFieldsToAttributes(cm, mod), nil } return defaultModuleSystemFieldsToAttributes(), nil @@ -1258,7 +1270,7 @@ func moduleSystemFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta, // partitionedModuleSystemFieldsToAttributes converts all system-defined module fields to attributes // keeping user-defined codec in mind func partitionedModuleSystemFieldsToAttributes(cm dal.ConnectionMeta, mod *types.Module) (out dal.AttributeSet) { - sysEnc := mod.ModelConfig.SystemFieldEncoding + sysEnc := mod.Config.DAL.SystemFieldEncoding if sysEnc.ID != nil { out = append(out, dal.PrimaryAttribute(sysID, modelFieldCodec(cm, mod, &types.ModuleField{Name: sysID, EncodingStrategy: *sysEnc.ID}))) @@ -1410,7 +1422,7 @@ func moduleFieldToAttribute(ctx context.Context, cm dal.ConnectionMeta, mod *typ func modulesByConnection(modules ...*types.Module) map[uint64]types.ModuleSet { out := make(map[uint64]types.ModuleSet) for _, mod := range modules { - out[mod.ModelConfig.ConnectionID] = append(out[mod.ModelConfig.ConnectionID], mod) + out[mod.Config.DAL.ConnectionID] = append(out[mod.Config.DAL.ConnectionID], mod) } return out @@ -1452,7 +1464,7 @@ func modelFieldCodec(cm dal.ConnectionMeta, mod *types.Module, f *types.ModuleFi // baseModelFieldCodec returns the DAL codec the given module field should use by default func baseModelFieldCodec(cm dal.ConnectionMeta, mod *types.Module, f *types.ModuleField) dal.Codec { - if mod.ModelConfig.Partitioned { + if mod.Config.DAL.Partitioned { return &dal.CodecPlain{} } diff --git a/compose/types/module.go b/compose/types/module.go index 30f87ed50..73e9a8d74 100644 --- a/compose/types/module.go +++ b/compose/types/module.go @@ -3,44 +3,31 @@ package types import ( "database/sql/driver" "encoding/json" + discovery "github.com/cortezaproject/corteza-server/discovery/types" + "github.com/cortezaproject/corteza-server/pkg/sql" + "github.com/jmoiron/sqlx/types" "time" - discovery "github.com/cortezaproject/corteza-server/discovery/types" "github.com/cortezaproject/corteza-server/pkg/dal" "github.com/cortezaproject/corteza-server/pkg/dal/capabilities" "github.com/cortezaproject/corteza-server/pkg/filter" "github.com/cortezaproject/corteza-server/pkg/locale" - "github.com/jmoiron/sqlx/types" - "github.com/pkg/errors" ) type ( - ModelConfig struct { - ConnectionID uint64 `json:"connectionID,string"` - Capabilities capabilities.Set `json:"capabilities"` - - Issues []string `json:"issues,omitempty"` - - Constraints map[string][]any `json:"constraints"` - - Partitioned bool `json:"partitioned"` - PartitionFormat string `json:"partitionFormat"` - - SystemFieldEncoding SystemFieldEncoding `json:"systemFieldEncoding"` - } - - DataPrivacyConfig struct { - SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"` - UsageDisclosure string `json:"usageDisclosure"` - } - Module struct { - ID uint64 `json:"moduleID,string"` - Handle string `json:"handle"` - Meta types.JSONText `json:"meta"` + ID uint64 `json:"moduleID,string"` + Handle string `json:"handle"` - ModelConfig ModelConfig `json:"modelConfig"` - Privacy DataPrivacyConfig `json:"privacy"` + // collection of configurations for various subsystems that + // use this module and how it affects their behaviour + Config ModuleConfig `json:"config"` + + // @todo should be removed and placed into a separate subsystem + // mostly because we want to allow client apps to store + // application configs away from the module config + // using separate access-control + Meta types.JSONText `json:"meta"` Fields ModuleFieldSet `json:"fields"` @@ -76,10 +63,41 @@ type ( DeletedBy *EncodingStrategy `json:"deletedBy"` } - ModuleMeta struct { + ModuleConfig struct { + // How and where the records of this module are stored in the database + DAL ModuleConfigDAL `json:"dal"` + + // Record data privacy settings + Privacy ModuleConfigDataPrivacy `json:"privacy"` + + // @todo we need to transfer this from meta!! Discovery discovery.ModuleMeta `json:"discovery"` } + ModuleConfigDAL struct { + ConnectionID uint64 `json:"connectionID,string"` + Capabilities capabilities.Set `json:"capabilities"` + + Issues []string `json:"issues,omitempty"` + + Constraints map[string][]any `json:"constraints"` + + Partitioned bool `json:"partitioned"` + PartitionFormat string `json:"partitionFormat"` + + SystemFieldEncoding SystemFieldEncoding `json:"systemFieldEncoding"` + } + + ModuleConfigDataPrivacy struct { + // Define the highest sensitivity level which + // can be configured on the module fields + SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"` + + UsageDisclosure string `json:"usageDisclosure"` + } + + ModelMeta map[string]any + ModuleFilter struct { ModuleID []uint64 `json:"moduleID"` NamespaceID uint64 `json:"namespaceID,string"` @@ -111,7 +129,7 @@ func (m Module) Clone() *Module { } func (m Module) HasIssues() bool { - return len(m.ModelConfig.Issues) > 0 + return len(m.Config.DAL.Issues) > 0 } // We won't worry about fields at this point @@ -126,7 +144,7 @@ func (m *Module) encodeTranslations() (out locale.ResourceTranslationSet) { func (m *Module) ModelRef() dal.ModelRef { return dal.ModelRef{ - ConnectionID: m.ModelConfig.ConnectionID, + ConnectionID: m.Config.DAL.ConnectionID, ResourceID: m.ID, @@ -147,45 +165,13 @@ func (set ModuleSet) FindByHandle(handle string) *Module { return nil } -func (nm *ModuleMeta) Scan(value interface{}) error { - //lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8 - switch value.(type) { - case nil: - *nm = ModuleMeta{} - case []uint8: - b := value.([]byte) - if err := json.Unmarshal(b, nm); err != nil { - return errors.Wrapf(err, "cannot scan '%v' into ModuleMeta", string(b)) - } - } +func (c *ModuleConfig) Scan(src any) error { return sql.ParseJSON(src, c) } +func (c ModuleConfig) Value() (driver.Value, error) { return json.Marshal(c) } - return nil -} +func (m *ModelMeta) Scan(src any) error { return sql.ParseJSON(src, m) } +func (m ModelMeta) Value() (driver.Value, error) { return json.Marshal(m) } -func (nm ModuleMeta) Value() (driver.Value, error) { - return json.Marshal(nm) -} - -func (nm *ModelConfig) Scan(value interface{}) error { - //lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8 - switch value.(type) { - case nil: - *nm = ModelConfig{} - case []uint8: - b := value.([]byte) - if err := json.Unmarshal(b, nm); err != nil { - return errors.Wrapf(err, "cannot scan '%v' into ModelConfig", string(b)) - } - } - - return nil -} - -func (nm ModelConfig) Value() (driver.Value, error) { - return json.Marshal(nm) -} - -func ParseModelConfig(ss []string) (m ModelConfig, err error) { +func ParseModuleConfig(ss []string) (m ModuleConfig, err error) { if len(ss) == 0 { return } @@ -193,31 +179,3 @@ func ParseModelConfig(ss []string) (m ModelConfig, err error) { err = json.Unmarshal([]byte(ss[0]), &m) return } - -func (nm *DataPrivacyConfig) Scan(value interface{}) error { - //lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8 - switch value.(type) { - case nil: - *nm = DataPrivacyConfig{} - case []uint8: - b := value.([]byte) - if err := json.Unmarshal(b, nm); err != nil { - return errors.Wrapf(err, "cannot scan '%v' into DataPrivacyConfig", string(b)) - } - } - - return nil -} - -func (nm DataPrivacyConfig) Value() (driver.Value, error) { - return json.Marshal(nm) -} - -func ParseDataPrivacyConfig(ss []string) (dpc DataPrivacyConfig, err error) { - if len(ss) == 0 { - return - } - - err = json.Unmarshal([]byte(ss[0]), &dpc) - return -} diff --git a/compose/types/module_field.go b/compose/types/module_field.go index 68a78efc5..9925ce263 100644 --- a/compose/types/module_field.go +++ b/compose/types/module_field.go @@ -3,6 +3,7 @@ package types import ( "database/sql/driver" "encoding/json" + "github.com/cortezaproject/corteza-server/pkg/sql" "sort" "strconv" "strings" @@ -28,7 +29,7 @@ type ( EncodingStrategy EncodingStrategy `json:"encodingStrategy"` - Privacy DataPrivacyConfig `json:"privacy"` + Privacy ModuleFieldConfigDataPrivacy `json:"privacy"` Private bool `json:"isPrivate"` Required bool `json:"isRequired"` @@ -50,6 +51,14 @@ type ( Label string `json:"label"` } + ModuleFieldConfigDataPrivacy struct { + // Define the highest sensitivity level which + // can be configured on the module fields + SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"` + + UsageDisclosure string `json:"usageDisclosure"` + } + EncodingStrategy struct { *EncodingStrategyAlias `json:"alias,omitempty"` *EncodingStrategyJSON `json:"json,omitempty"` @@ -520,3 +529,6 @@ func (f ModuleField) IsRef() bool { func (f ModuleField) IsSensitive() bool { return f.Privacy.SensitivityLevel > 0 } + +func (p *ModuleFieldConfigDataPrivacy) Scan(src any) error { return sql.ParseJSON(src, p) } +func (p ModuleFieldConfigDataPrivacy) Value() (driver.Value, error) { return json.Marshal(p) } diff --git a/pkg/sql/json.go b/pkg/sql/json.go new file mode 100644 index 000000000..2c2ebd0f0 --- /dev/null +++ b/pkg/sql/json.go @@ -0,0 +1,26 @@ +package sql + +import ( + "encoding/json" + "fmt" +) + +func ParseJSON(raw any, dest any) (error) { + var ( + data []byte + ) + + if b, ok := raw.([]byte); ok { + data = b + } else if s, ok := raw.(string); ok { + data = []byte(s) + } else if raw == nil { + return nil + } + + if err := json.Unmarshal(data, dest); err != nil { + return fmt.Errorf("can not scan JSON into %T: %w", dest, err) + } + + return nil +} diff --git a/store/adapters/rdbms/aux_types.gen.go b/store/adapters/rdbms/aux_types.gen.go index 6499e877a..0a3e1de91 100644 --- a/store/adapters/rdbms/aux_types.gen.go +++ b/store/adapters/rdbms/aux_types.gen.go @@ -244,38 +244,37 @@ type ( // auxComposeModule is an auxiliary structure used for transporting to/from RDBMS store auxComposeModule struct { - ID uint64 `db:"id"` - Handle string `db:"handle"` - Meta rawJson `db:"meta"` - ModelConfig composeType.ModelConfig `db:"model_config"` - Privacy composeType.DataPrivacyConfig `db:"privacy"` - NamespaceID uint64 `db:"namespace_id"` - Name string `db:"name"` - CreatedAt time.Time `db:"created_at"` - UpdatedAt *time.Time `db:"updated_at"` - DeletedAt *time.Time `db:"deleted_at"` + ID uint64 `db:"id"` + Handle string `db:"handle"` + Meta rawJson `db:"meta"` + Config composeType.ModuleConfig `db:"config"` + NamespaceID uint64 `db:"namespace_id"` + Name string `db:"name"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt *time.Time `db:"updated_at"` + DeletedAt *time.Time `db:"deleted_at"` } // auxComposeModuleField is an auxiliary structure used for transporting to/from RDBMS store auxComposeModuleField struct { - ID uint64 `db:"id"` - ModuleID uint64 `db:"module_id"` - Place int `db:"place"` - Kind string `db:"kind"` - Name string `db:"name"` - Label string `db:"label"` - Options composeType.ModuleFieldOptions `db:"options"` - EncodingStrategy composeType.EncodingStrategy `db:"encoding_strategy"` - Privacy composeType.DataPrivacyConfig `db:"privacy"` - Private bool `db:"private"` - Required bool `db:"required"` - Visible bool `db:"visible"` - Multi bool `db:"multi"` - DefaultValue composeType.RecordValueSet `db:"default_value"` - Expressions composeType.ModuleFieldExpr `db:"expressions"` - CreatedAt time.Time `db:"created_at"` - UpdatedAt *time.Time `db:"updated_at"` - DeletedAt *time.Time `db:"deleted_at"` + ID uint64 `db:"id"` + ModuleID uint64 `db:"module_id"` + Place int `db:"place"` + Kind string `db:"kind"` + Name string `db:"name"` + Label string `db:"label"` + Options composeType.ModuleFieldOptions `db:"options"` + EncodingStrategy composeType.EncodingStrategy `db:"encoding_strategy"` + Privacy composeType.ModuleFieldConfigDataPrivacy `db:"privacy"` + Private bool `db:"private"` + Required bool `db:"required"` + Visible bool `db:"visible"` + Multi bool `db:"multi"` + DefaultValue composeType.RecordValueSet `db:"default_value"` + Expressions composeType.ModuleFieldExpr `db:"expressions"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt *time.Time `db:"updated_at"` + DeletedAt *time.Time `db:"deleted_at"` } // auxComposeNamespace is an auxiliary structure used for transporting to/from RDBMS store @@ -1442,8 +1441,7 @@ func (aux *auxComposeModule) encode(res *composeType.Module) (_ error) { aux.ID = res.ID aux.Handle = res.Handle aux.Meta = res.Meta - aux.ModelConfig = res.ModelConfig - aux.Privacy = res.Privacy + aux.Config = res.Config aux.NamespaceID = res.NamespaceID aux.Name = res.Name aux.CreatedAt = res.CreatedAt @@ -1460,8 +1458,7 @@ func (aux auxComposeModule) decode() (res *composeType.Module, _ error) { res.ID = aux.ID res.Handle = aux.Handle res.Meta = aux.Meta - res.ModelConfig = aux.ModelConfig - res.Privacy = aux.Privacy + res.Config = aux.Config res.NamespaceID = aux.NamespaceID res.Name = aux.Name res.CreatedAt = aux.CreatedAt @@ -1478,8 +1475,7 @@ func (aux *auxComposeModule) scan(row scanner) error { &aux.ID, &aux.Handle, &aux.Meta, - &aux.ModelConfig, - &aux.Privacy, + &aux.Config, &aux.NamespaceID, &aux.Name, &aux.CreatedAt, diff --git a/store/adapters/rdbms/queries.gen.go b/store/adapters/rdbms/queries.gen.go index 968a138e9..9a30c100a 100644 --- a/store/adapters/rdbms/queries.gen.go +++ b/store/adapters/rdbms/queries.gen.go @@ -1636,8 +1636,7 @@ var ( "id", "handle", "meta", - "model_config", - "privacy", + "config", "rel_namespace", "name", "created_at", @@ -1655,8 +1654,7 @@ var ( "id": res.ID, "handle": res.Handle, "meta": res.Meta, - "model_config": res.ModelConfig, - "privacy": res.Privacy, + "config": res.Config, "rel_namespace": res.NamespaceID, "name": res.Name, "created_at": res.CreatedAt, @@ -1677,8 +1675,7 @@ var ( goqu.Record{ "handle": res.Handle, "meta": res.Meta, - "model_config": res.ModelConfig, - "privacy": res.Privacy, + "config": res.Config, "rel_namespace": res.NamespaceID, "name": res.Name, "created_at": res.CreatedAt, @@ -1697,8 +1694,7 @@ var ( Set(goqu.Record{ "handle": res.Handle, "meta": res.Meta, - "model_config": res.ModelConfig, - "privacy": res.Privacy, + "config": res.Config, "rel_namespace": res.NamespaceID, "name": res.Name, "created_at": res.CreatedAt, diff --git a/store/adapters/rdbms/upgrade_fixes.go b/store/adapters/rdbms/upgrade_fixes.go index 7470dbdea..c8f0b4c96 100644 --- a/store/adapters/rdbms/upgrade_fixes.go +++ b/store/adapters/rdbms/upgrade_fixes.go @@ -6,12 +6,11 @@ import ( ) func fix202209_extendComposeModuleForPrivacyAndDAL(ctx context.Context, s *Store) (err error) { - s.log(ctx).Info("extending compose_module table with privacy and model_config columns") + s.log(ctx).Info("extending compose_module table with config column") return s.SchemaAPI.AddColumn( ctx, s.DB, &Table{Name: "compose_module"}, - &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "privacy"}, - &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "model_config"}, + &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "config"}, ) } diff --git a/store/adapters/rdbms/upgrade_tables.go b/store/adapters/rdbms/upgrade_tables.go index efdc758f5..a8f8987fc 100644 --- a/store/adapters/rdbms/upgrade_tables.go +++ b/store/adapters/rdbms/upgrade_tables.go @@ -448,8 +448,7 @@ func tableComposeModule() *Table { ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), ColumnDef("name", ColumnTypeText), ColumnDef("meta", ColumnTypeJson), - ColumnDef("privacy", ColumnTypeJson), - ColumnDef("model_config", ColumnTypeJson), + ColumnDef("config", ColumnTypeJson), CUDTimestamps, AddIndex("namespace", IColumn("rel_namespace")), diff --git a/tests/dal/dal_crud_compose_record_test.go b/tests/dal/dal_crud_compose_record_test.go index 3d26b958d..d358e953b 100644 --- a/tests/dal/dal_crud_compose_record_test.go +++ b/tests/dal/dal_crud_compose_record_test.go @@ -22,9 +22,11 @@ func Test_dal_crud_compose_record_create(t *testing.T) { helpers.AllowMeRecordCRUD(h) ns := h.createNamespace("test") - module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{ - ConnectionID: 0, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: 0, + Capabilities: capabilities.FullCapabilities(), + }, }) // create @@ -81,9 +83,11 @@ func Test_dal_crud_compose_record_update(t *testing.T) { helpers.AllowMeRecordCRUD(h) ns := h.createNamespace("test") - module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{ - ConnectionID: 0, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: 0, + Capabilities: capabilities.FullCapabilities(), + }, }) record := createRecordFromGenerics(ctx, t, "ok_record.json", ns.ID, module.ID) @@ -140,9 +144,11 @@ func Test_dal_crud_compose_record_delete(t *testing.T) { helpers.AllowMeRecordCRUD(h) ns := h.createNamespace("test") - module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{ - ConnectionID: 0, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: 0, + Capabilities: capabilities.FullCapabilities(), + }, }) record := createRecordFromGenerics(ctx, t, "ok_record.json", ns.ID, module.ID) diff --git a/tests/dal/dal_crud_issues_compose_module_test.go b/tests/dal/dal_crud_issues_compose_module_test.go index 5dbc91057..2aa19c01b 100644 --- a/tests/dal/dal_crud_issues_compose_module_test.go +++ b/tests/dal/dal_crud_issues_compose_module_test.go @@ -27,7 +27,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) { Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.Len("$.response.modelConfig.issues", 1)). + Assert(jsonpath.Len("$.response.config.dal.issues", 1)). End() dd := json.NewDecoder(rsp.Response.Body) @@ -42,7 +42,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) { Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.NotPresent("$.response.modelConfig.issues")). + Assert(jsonpath.NotPresent("$.response.config.dal.issues")). End() rsp = h.apiInit(). @@ -54,7 +54,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) { Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.Len("$.response.modelConfig.issues", 1)). + Assert(jsonpath.Len("$.response.config.dal.issues", 1)). End() rsp = h.apiInit(). @@ -84,7 +84,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T) Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.Len("$.response.modelConfig.issues", 1)). + Assert(jsonpath.Len("$.response.config.dal.issues", 1)). End() dd := json.NewDecoder(rsp.Response.Body) @@ -98,7 +98,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T) Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.NotPresent("$.response.modelConfig.issues")). + Assert(jsonpath.NotPresent("$.response.config.dal.issues")). End() rsp = h.apiInit(). @@ -110,7 +110,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T) Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.Len("$.response.modelConfig.issues", 1)). + Assert(jsonpath.Len("$.response.config.dal.issues", 1)). End() rsp = h.apiInit(). @@ -143,7 +143,7 @@ func Test_dal_crud_issues_compose_module_nok_connection(t *testing.T) { Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.Len("$.response.modelConfig.issues", 1)). + Assert(jsonpath.Len("$.response.config.dal.issues", 1)). End() dd := json.NewDecoder(rsp.Response.Body) @@ -170,7 +170,7 @@ func Test_dal_crud_issues_compose_module_nok_connection(t *testing.T) { Status(http.StatusOK). Assert(helpers.AssertNoErrors). Assert(jsonpath.Present("$.response.moduleID")). - Assert(jsonpath.NotPresent("$.response.modelConfig.issues")). + Assert(jsonpath.NotPresent("$.response.config.dal.issues")). End() rsp = h.apiInit(). diff --git a/tests/dal/dal_crud_issues_compose_record_test.go b/tests/dal/dal_crud_issues_compose_record_test.go index 3806089fb..3d5575833 100644 --- a/tests/dal/dal_crud_issues_compose_record_test.go +++ b/tests/dal/dal_crud_issues_compose_record_test.go @@ -21,9 +21,11 @@ func Test_dal_crud_issues_compose_record_nok_connection(t *testing.T) { ns := h.createNamespace("test") connection := createConnectionFromGenerics(h.secCtx(), t, "nok_connection_connectivity.json") - module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModelConfig{ - ConnectionID: connection.ID, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: connection.ID, + Capabilities: capabilities.FullCapabilities(), + }, }) h.apiInit(). @@ -48,9 +50,11 @@ func Test_dal_crud_issues_compose_record_nok_model(t *testing.T) { ns := h.createNamespace("test") connection := createConnectionFromGenerics(h.secCtx(), t, "ok_connection.json") - module := createModuleFromGenerics(h.secCtx(), t, "nok_module_sensitivity_level.json", ns.ID, &types.ModelConfig{ - ConnectionID: connection.ID, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(h.secCtx(), t, "nok_module_sensitivity_level.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: connection.ID, + Capabilities: capabilities.FullCapabilities(), + }, }) h.apiInit(). @@ -75,9 +79,11 @@ func Test_dal_crud_issues_compose_record_ok(t *testing.T) { ns := h.createNamespace("test") connection := createConnectionFromGenerics(h.secCtx(), t, "ok_connection.json") - module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModelConfig{ - ConnectionID: connection.ID, - Capabilities: capabilities.FullCapabilities(), + module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModuleConfig{ + DAL: types.ModuleConfigDAL{ + ConnectionID: connection.ID, + Capabilities: capabilities.FullCapabilities(), + }, }) h.apiInit(). diff --git a/tests/dal/main_test.go b/tests/dal/main_test.go index ec9d0afc2..089f30eed 100644 --- a/tests/dal/main_test.go +++ b/tests/dal/main_test.go @@ -129,7 +129,7 @@ func loadRequestFromScenarioWithConnection(t *testing.T, req string, connectionI aux := &composeTypes.Module{} require.NoError(t, json.Unmarshal([]byte(out), &aux)) - aux.ModelConfig.ConnectionID = connectionID + aux.Config.DAL.ConnectionID = connectionID a, err := json.Marshal(aux) require.NoError(t, err) @@ -158,13 +158,13 @@ func createRecordFrom(ctx context.Context, t *testing.T, suite, name string, nam return record } -func createModuleFromCase(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) { +func createModuleFromCase(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) { return createModuleFrom(ctx, t, suiteFromT(t), name, namespaceID, config) } -func createModuleFromGenerics(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) { +func createModuleFromGenerics(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) { return createModuleFrom(ctx, t, "generic", name, namespaceID, config) } -func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) { +func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) { raw := loadRequestFrom(t, suite, name) module = &composeTypes.Module{} @@ -173,7 +173,8 @@ func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, nam module.NamespaceID = namespaceID if config != nil { - module.ModelConfig = *config + // let's be careful not to override whole config + module.Config.DAL = config.DAL } module, err := composeService.DefaultModule.Create(ctx, module) diff --git a/tests/dal/testdata/dal_crud_issues_compose_module_nok_connection/module.json b/tests/dal/testdata/dal_crud_issues_compose_module_nok_connection/module.json index f171db499..7ef3803f5 100644 --- a/tests/dal/testdata/dal_crud_issues_compose_module_nok_connection/module.json +++ b/tests/dal/testdata/dal_crud_issues_compose_module_nok_connection/module.json @@ -2,16 +2,19 @@ "name": "internal_non_partitioned", "handle": "internal_non_partitioned", - "modelConfig": { - "connectionID": "42", - "capabilities": [], - "partitioned": false + "config": { + "dal": { + "connectionID": "42", + "capabilities": [], + "partitioned": false + }, + + "privacy": { + "sensitivityLevel": "0", + "usageDisclosure": "A" + } }, - "privacy": { - "sensitivityLevel": "0", - "usageDisclosure": "A" - }, "fields": [ { diff --git a/tests/dal/testdata/generic/nok_module_missing_field_sensitivity_level.json b/tests/dal/testdata/generic/nok_module_missing_field_sensitivity_level.json index f654df11c..01bb3e62f 100644 --- a/tests/dal/testdata/generic/nok_module_missing_field_sensitivity_level.json +++ b/tests/dal/testdata/generic/nok_module_missing_field_sensitivity_level.json @@ -2,15 +2,16 @@ "name": "internal_non_partitioned", "handle": "internal_non_partitioned", - "modelConfig": { - "connectionID": "0", - "capabilities": [], - "partitioned": false - }, - - "privacy": { - "sensitivityLevel": "0", - "usageDisclosure": "A" + "config": { + "dal": { + "connectionID": "0", + "capabilities": [], + "partitioned": false + }, + "privacy": { + "sensitivityLevel": "0", + "usageDisclosure": "A" + } }, "fields": [ diff --git a/tests/dal/testdata/generic/nok_module_missing_sensitivity_level.json b/tests/dal/testdata/generic/nok_module_missing_sensitivity_level.json index 5d08efec6..683b584d2 100644 --- a/tests/dal/testdata/generic/nok_module_missing_sensitivity_level.json +++ b/tests/dal/testdata/generic/nok_module_missing_sensitivity_level.json @@ -2,15 +2,16 @@ "name": "internal_non_partitioned", "handle": "internal_non_partitioned", - "modelConfig": { - "connectionID": "0", - "capabilities": [], - "partitioned": false - }, - - "privacy": { - "sensitivityLevel": "42", - "usageDisclosure": "A" + "config": { + "dal": { + "connectionID": "0", + "capabilities": [], + "partitioned": false + }, + "privacy": { + "sensitivityLevel": "42", + "usageDisclosure": "A" + } }, "fields": [ diff --git a/tests/dal/testdata/generic/nok_module_sensitivity_level.json b/tests/dal/testdata/generic/nok_module_sensitivity_level.json index 5d08efec6..894a41a88 100644 --- a/tests/dal/testdata/generic/nok_module_sensitivity_level.json +++ b/tests/dal/testdata/generic/nok_module_sensitivity_level.json @@ -2,15 +2,17 @@ "name": "internal_non_partitioned", "handle": "internal_non_partitioned", - "modelConfig": { - "connectionID": "0", - "capabilities": [], - "partitioned": false - }, + "config": { + "dal": { + "connectionID": "0", + "capabilities": [], + "partitioned": false + }, - "privacy": { - "sensitivityLevel": "42", - "usageDisclosure": "A" + "privacy": { + "sensitivityLevel": "42", + "usageDisclosure": "A" + } }, "fields": [ diff --git a/tests/dal/testdata/generic/ok_module.json b/tests/dal/testdata/generic/ok_module.json index 8520d316f..5f0e8130d 100644 --- a/tests/dal/testdata/generic/ok_module.json +++ b/tests/dal/testdata/generic/ok_module.json @@ -2,15 +2,16 @@ "name": "internal_non_partitioned", "handle": "internal_non_partitioned", - "modelConfig": { - "connectionID": "0", - "capabilities": [], - "partitioned": false - }, - - "privacy": { - "sensitivityLevel": "0", - "usageDisclosure": "A" + "config": { + "dal": { + "connectionID": "0", + "capabilities": [], + "partitioned": false + }, + "privacy": { + "sensitivityLevel": "0", + "usageDisclosure": "A" + } }, "fields": [