Files
upstream-corteza/server/compose/envoy/store_decode.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

302 lines
7.2 KiB
Go

package envoy
import (
"context"
"fmt"
"github.com/cortezaproject/corteza/server/compose/dalutils"
"github.com/cortezaproject/corteza/server/compose/service"
"github.com/cortezaproject/corteza/server/compose/types"
"github.com/cortezaproject/corteza/server/pkg/dal"
"github.com/cortezaproject/corteza/server/pkg/envoyx"
"github.com/cortezaproject/corteza/server/pkg/filter"
"github.com/cortezaproject/corteza/server/pkg/id"
"github.com/cortezaproject/corteza/server/pkg/rbac"
"github.com/cortezaproject/corteza/server/store"
"github.com/spf13/cast"
)
func (d StoreDecoder) extendNamespaceFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.NamespaceFilter) (out types.NamespaceFilter) {
out = base
if scope == nil {
return
}
if scope.ResourceType == "" {
return
}
// Overwrite it
out.NamespaceID = id.Strings(scope.Resource.GetID())
return
}
func (d StoreDecoder) extendModuleFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.ModuleFilter) (out types.ModuleFilter) {
out = base
if scope == nil {
return
}
if scope.ResourceType == "" {
return
}
// Overwrite it
out.NamespaceID = scope.Resource.GetID()
return
}
func (d StoreDecoder) extendPageFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.PageFilter) (out types.PageFilter) {
out = base
if scope == nil {
return
}
if scope.ResourceType == "" {
return
}
// Overwrite it
out.NamespaceID = scope.Resource.GetID()
return
}
func (d StoreDecoder) makeModuleFieldFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter) (out types.ModuleFieldFilter) {
out.Limit = auxf.Limit
ids, hh := auxf.Identifiers.Idents()
_ = ids
_ = hh
// Refs
var (
ar *envoyx.Node
ok bool
)
_ = ar
_ = ok
// ar, ok = refs["ModuleID"]
// if ok {
// out.ModuleID = ar.Resource.GetID()
// }
return
}
func (d StoreDecoder) extendedModuleDecoder(ctx context.Context, s store.Storer, dl dal.FullService, f types.ModuleFilter, base envoyx.NodeSet) (out envoyx.NodeSet, err error) {
var ff envoyx.NodeSet
for _, b := range base {
mod := b.Resource.(*types.Module)
// Get all of the related module fields, append them to the output and
// the original module (so other code can have access to the related fields)
ff, err = d.decodeModuleField(ctx, s, dl, types.ModuleFieldFilter{ModuleID: []uint64{mod.ID}})
if err != nil {
return
}
for _, f := range ff {
f.Scope = b.Scope
f.References = envoyx.MergeRefs(f.References, b.References, map[string]envoyx.Ref{
"ModuleID": b.ToRef(),
})
for k, ref := range f.References {
ref.Scope = b.Scope
f.References[k] = ref
}
mod.Fields = append(mod.Fields, f.Resource.(*types.ModuleField))
}
out = append(out, ff...)
}
return
}
func decodeChartRefs(c *types.Chart) (refs map[string]envoyx.Ref) {
refs = make(map[string]envoyx.Ref, len(c.Config.Reports))
for i, r := range c.Config.Reports {
if r.ModuleID == 0 {
continue
}
refs[fmt.Sprintf("Config.Reports.%d.ModuleID", i)] = envoyx.Ref{
ResourceType: types.ModuleResourceType,
Identifiers: envoyx.MakeIdentifiers(r.ModuleID),
}
}
return
}
func decodeModuleFieldRefs(c *types.ModuleField) (refs map[string]envoyx.Ref) {
refs = make(map[string]envoyx.Ref, 1)
refs["NamespaceID"] = envoyx.Ref{
ResourceType: types.NamespaceResourceType,
Identifiers: envoyx.MakeIdentifiers(c.NamespaceID),
}
id := c.Options.UInt64("moduleID")
if id == 0 {
return
}
refs["Options.ModuleID"] = envoyx.Ref{
ResourceType: types.ModuleResourceType,
Identifiers: envoyx.MakeIdentifiers(id),
}
return
}
func decodePageRefs(p *types.Page) (refs map[string]envoyx.Ref) {
refs = make(map[string]envoyx.Ref, len(p.Blocks)/2)
for index, b := range p.Blocks {
switch b.Kind {
case "RecordList":
refs = envoyx.MergeRefs(refs, getPageBlockRecordListRefs(b, index))
case "Automation":
refs = envoyx.MergeRefs(refs, getPageBlockAutomationRefs(b, index))
case "RecordOrganizer":
refs = envoyx.MergeRefs(refs, getPageBlockRecordOrganizerRefs(b, index))
case "Chart":
refs = envoyx.MergeRefs(refs, getPageBlockChartRefs(b, index))
case "Calendar":
refs = envoyx.MergeRefs(refs, getPageBlockCalendarRefs(b, index))
case "Metric":
refs = envoyx.MergeRefs(refs, getPageBlockMetricRefs(b, index))
case "Comment":
refs = envoyx.MergeRefs(refs, getPageBlockCommentRefs(b, index))
case "Progress":
refs = envoyx.MergeRefs(refs, getPageBlockProgressRefs(b, index))
}
}
return
}
func (d StoreDecoder) extendDecoder(ctx context.Context, s store.Storer, dl dal.FullService, p envoyx.DecodeParams, rt string, refs map[string]*envoyx.Node, rf envoyx.ResourceFilter) (out envoyx.NodeSet, err error) {
switch rt {
// @todo consider hooking into the regular record resource type as well
case ComposeRecordDatasourceAuxType:
return d.decodeRecordDatasource(ctx, s, dl, p, refs, rf)
}
return
}
func (d StoreDecoder) decodeRecordDatasource(ctx context.Context, s store.Storer, dl dal.FullService, p envoyx.DecodeParams, refs map[string]*envoyx.Node, rf envoyx.ResourceFilter) (out envoyx.NodeSet, err error) {
var (
ok bool
module *types.Module
moduleNode *envoyx.Node
namespace *types.Namespace
namespaceNode *envoyx.Node
)
// Get the refs
namespaceNode, ok = refs["NamespaceID"]
if !ok {
err = fmt.Errorf("missing NamespaceID reference")
return
}
namespace = namespaceNode.Resource.(*types.Namespace)
moduleNode, ok = refs["ModuleID"]
if !ok {
err = fmt.Errorf("missing ModuleID reference")
return
}
module = moduleNode.Resource.(*types.Module)
// Get the iterator
iter, _, err := dalutils.ComposeRecordsIterator(ctx, dl, module, types.RecordFilter{
Query: rf.Query,
ModuleID: module.ID,
NamespaceID: namespace.ID,
Paging: filter.Paging{
Limit: rf.Limit,
},
})
if err != nil {
return
}
mv := make(map[string]bool)
dt := make(map[string]bool)
for _, f := range module.Fields {
if f.Multi {
mv[f.Name] = true
}
if f.Kind == "DateTime" {
dt[f.Name] = true
}
}
for _, n := range []string{"createdAt", "updatedAt", "deletedAt"} {
dt[n] = true
}
rds := &RecordDatasource{
Provider: &iteratorProvider{iter: iter},
multivalues: mv,
datetimeFields: dt,
refToID: make(map[string]uint64),
existingIDs: make(map[uint64]bool),
// @todo consider providing defaults from the outside
Mapping: envoyx.DatasourceMapping{
KeyField: []string{"id"},
Defaultable: true,
},
}
// Get access controller to enforce field-level read permissions
ac := service.AccessControl(s)
if rbac.Global() == nil {
ac = nil
}
rds.Provider, err = mkIteratorProvider(ctx, ac, s, dl, iter, module, cast.ToBool(p.Params["resolveRefs"]), cast.ToBool(p.Params["includeRefID"]))
if err != nil {
return
}
rr := map[string]envoyx.Ref{
"NamespaceID": namespaceNode.ToRef(),
"ModuleID": moduleNode.ToRef(),
}
out = append(out, &envoyx.Node{
Datasource: rds,
ResourceType: ComposeRecordDatasourceAuxType,
Identifiers: envoyx.MakeIdentifiers(module.ID, module.Handle),
References: rr,
Scope: moduleNode.Scope,
})
return
}