From f1325f6631750c4e4a323e712a468f149ceabd58 Mon Sep 17 00:00:00 2001 From: steiler Date: Thu, 15 Jan 2026 10:55:33 +0100 Subject: [PATCH 1/6] tmp adjust go.mod --- go.mod | 2 ++ go.sum | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 23656402..c151e4ad 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.24.0 replace github.com/openconfig/goyang v1.6.0 => github.com/sdcio/goyang v1.6.2-2 +replace github.com/sdcio/sdc-protos => /home/mava/projects/sdc-protos + require ( github.com/AlekSi/pointer v1.2.0 github.com/beevik/etree v1.6.0 diff --git a/go.sum b/go.sum index cc73088d..896a0c65 100644 --- a/go.sum +++ b/go.sum @@ -193,8 +193,6 @@ github.com/sdcio/logger v0.0.3 h1:IFUbObObGry+S8lHGwOQKKRxJSuOphgRU/hxVhOdMOM= github.com/sdcio/logger v0.0.3/go.mod h1:yWaOxK/G6vszjg8tKZiMqiEjlZouHsjFME4zSk+SAEA= github.com/sdcio/schema-server v0.0.34 h1:NNDOkvtUMONtBA7cVvN96F+FWGD/Do6HNqfchy9B8eI= github.com/sdcio/schema-server v0.0.34/go.mod h1:6t8HLXpqUqEJmE5yNZh29u/KZw0jlOICdNWns7zE4GE= -github.com/sdcio/sdc-protos v0.0.50 h1:aR6Av1QMTFNXKKxnrz8vlIXQ0y21lxQJEMut1oLd2Bg= -github.com/sdcio/sdc-protos v0.0.50/go.mod h1:huh1QVE023w+reU2Gt6h1f83R3lJidcFLbQje7cMY1M= github.com/sdcio/yang-parser v0.0.12 h1:RSSeqfAOIsJx5Lno5u4/ezyOmQYUduQ22rBfU/mtpJ4= github.com/sdcio/yang-parser v0.0.12/go.mod h1:CBqn3Miq85qmFVGHxHXHLluXkaIOsTzV06IM4DW6+D4= github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4 h1:FHUL2HofYJuslFOQdy/JjjP36zxqIpd/dcoiwLMIs7k= From 0fa2b1c21b7eeec67c89a0aec6be4bb685e20934 Mon Sep 17 00:00:00 2001 From: steiler Date: Mon, 19 Jan 2026 13:37:49 +0100 Subject: [PATCH 2/6] Make the syncing of running not blindly overwrite but transfor the sync tree --- pkg/datastore/sync.go | 18 ++++++++++++++++++ pkg/tree/leaf_variants.go | 14 ++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pkg/datastore/sync.go b/pkg/datastore/sync.go index 57c243d5..ce2c28c4 100644 --- a/pkg/datastore/sync.go +++ b/pkg/datastore/sync.go @@ -2,6 +2,7 @@ package datastore import ( "context" + "fmt" "sync" "github.com/sdcio/data-server/pkg/tree" @@ -60,6 +61,23 @@ func (d *Datastore) ApplyToRunning(ctx context.Context, deletes []*sdcpb.Path, i } } + // run remove deleted processor to clean up entries marked as deleted by owner + delProcessorParams = tree.NewRemoveDeletedProcessorParameters(tree.RunningIntentName) + err = tree.NewRemoveDeletedProcessor(delProcessorParams).Run(d.syncTree.GetRoot(), d.taskPool) + if err != nil { + return err + } + + // delete entries that have zero-length leaf variant entries after remove deleted processing + for _, e := range delProcessorParams.GetZeroLengthLeafVariantEntries() { + fmt.Println("entry has zero-length leaf variant entries after remove deleted", "entry", e.SdcpbPath().ToXPath(false)) + + err := e.GetParent().DeleteBranch(ctx, &sdcpb.Path{Elem: []*sdcpb.PathElem{sdcpb.NewPathElem(e.PathName(), nil)}}, tree.RunningIntentName) + if err != nil { + return err + } + } + // conditional trace logging if log := log.V(logger.VTrace); log.Enabled() { treeExport, err := d.syncTree.TreeExport(tree.RunningIntentName, tree.RunningValuesPrio) diff --git a/pkg/tree/leaf_variants.go b/pkg/tree/leaf_variants.go index d3d8f17a..0bc81ef1 100644 --- a/pkg/tree/leaf_variants.go +++ b/pkg/tree/leaf_variants.go @@ -135,6 +135,20 @@ func (lv *LeafVariants) checkOnlyRunningAndMaybeDefault() bool { return hasRunning && hasDefault } +// RemoveDeletedByOwner removes and returns the LeafEntry owned by the given owner if it is marked for deletion. +func (lv *LeafVariants) RemoveDeletedByOwner(owner string) *LeafEntry { + lv.lesMutex.Lock() + defer lv.lesMutex.Unlock() + for i, l := range lv.les { + if l.Owner() == owner && l.GetDeleteFlag() { + // Remove element from slice + lv.les = append(lv.les[:i], lv.les[i+1:]...) + return l + } + } + return nil +} + // canDelete returns true if leafValues exist that are not owned by default or running that do not have the DeleteFlag set [or if delete is set, also the DeleteOnlyIntendedFlag set] func (lv *LeafVariants) canDelete() bool { lv.lesMutex.RLock() From 2a08938b632df8b5bb34bb49edf4bd1a8c660155 Mon Sep 17 00:00:00 2001 From: steiler Date: Mon, 26 Jan 2026 11:12:40 +0100 Subject: [PATCH 3/6] working darft for revertives --- mocks/mocktreeentry/entry.go | 15 +++++++++++++++ pkg/tree/leaf_variants.go | 14 -------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/mocks/mocktreeentry/entry.go b/mocks/mocktreeentry/entry.go index ff0b493b..86297e81 100644 --- a/mocks/mocktreeentry/entry.go +++ b/mocks/mocktreeentry/entry.go @@ -601,6 +601,21 @@ func (mr *MockEntryMockRecorder) addUpdateRecursiveInternal(ctx, path, idx, u, f return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "addUpdateRecursiveInternal", reflect.TypeOf((*MockEntry)(nil).addUpdateRecursiveInternal), ctx, path, idx, u, flags) } +// addUpdateRecursiveInternal mocks base method. +func (m *MockEntry) addUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (tree.Entry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "addUpdateRecursiveInternal", ctx, path, idx, u, flags) + ret0, _ := ret[0].(tree.Entry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// addUpdateRecursiveInternal indicates an expected call of addUpdateRecursiveInternal. +func (mr *MockEntryMockRecorder) addUpdateRecursiveInternal(ctx, path, idx, u, flags any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "addUpdateRecursiveInternal", reflect.TypeOf((*MockEntry)(nil).addUpdateRecursiveInternal), ctx, path, idx, u, flags) +} + // canDelete mocks base method. func (m *MockEntry) canDelete() bool { m.ctrl.T.Helper() diff --git a/pkg/tree/leaf_variants.go b/pkg/tree/leaf_variants.go index 0bc81ef1..d3d8f17a 100644 --- a/pkg/tree/leaf_variants.go +++ b/pkg/tree/leaf_variants.go @@ -135,20 +135,6 @@ func (lv *LeafVariants) checkOnlyRunningAndMaybeDefault() bool { return hasRunning && hasDefault } -// RemoveDeletedByOwner removes and returns the LeafEntry owned by the given owner if it is marked for deletion. -func (lv *LeafVariants) RemoveDeletedByOwner(owner string) *LeafEntry { - lv.lesMutex.Lock() - defer lv.lesMutex.Unlock() - for i, l := range lv.les { - if l.Owner() == owner && l.GetDeleteFlag() { - // Remove element from slice - lv.les = append(lv.les[:i], lv.les[i+1:]...) - return l - } - } - return nil -} - // canDelete returns true if leafValues exist that are not owned by default or running that do not have the DeleteFlag set [or if delete is set, also the DeleteOnlyIntendedFlag set] func (lv *LeafVariants) canDelete() bool { lv.lesMutex.RLock() From 333f7583bb6fec17bda1b25f45a23104a20cc5b0 Mon Sep 17 00:00:00 2001 From: steiler Date: Tue, 27 Jan 2026 12:02:13 +0100 Subject: [PATCH 4/6] non-revertive now working --- mocks/mocktreeentry/entry.go | 15 --------------- pkg/tree/sharedEntryAttributes_test.go | 4 ++-- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/mocks/mocktreeentry/entry.go b/mocks/mocktreeentry/entry.go index 86297e81..ff0b493b 100644 --- a/mocks/mocktreeentry/entry.go +++ b/mocks/mocktreeentry/entry.go @@ -601,21 +601,6 @@ func (mr *MockEntryMockRecorder) addUpdateRecursiveInternal(ctx, path, idx, u, f return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "addUpdateRecursiveInternal", reflect.TypeOf((*MockEntry)(nil).addUpdateRecursiveInternal), ctx, path, idx, u, flags) } -// addUpdateRecursiveInternal mocks base method. -func (m *MockEntry) addUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "addUpdateRecursiveInternal", ctx, path, idx, u, flags) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// addUpdateRecursiveInternal indicates an expected call of addUpdateRecursiveInternal. -func (mr *MockEntryMockRecorder) addUpdateRecursiveInternal(ctx, path, idx, u, flags any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "addUpdateRecursiveInternal", reflect.TypeOf((*MockEntry)(nil).addUpdateRecursiveInternal), ctx, path, idx, u, flags) -} - // canDelete mocks base method. func (m *MockEntry) canDelete() bool { m.ctrl.T.Helper() diff --git a/pkg/tree/sharedEntryAttributes_test.go b/pkg/tree/sharedEntryAttributes_test.go index 36f1aac5..d2f22349 100644 --- a/pkg/tree/sharedEntryAttributes_test.go +++ b/pkg/tree/sharedEntryAttributes_test.go @@ -1006,7 +1006,7 @@ func Test_sharedEntryAttributes_validateMandatory(t *testing.T) { t.Fatal(err) } - tc := NewTreeContext(scb, owner1) + tc := NewTreeContext(scb, owner1, pool.NewSharedTaskPool(ctx, runtime.NumCPU())) root, err := NewTreeRoot(ctx, tc) if err != nil { t.Fatal(err) @@ -1020,7 +1020,7 @@ func Test_sharedEntryAttributes_validateMandatory(t *testing.T) { }, }, } - err = testhelper.LoadYgotStructIntoTreeRoot(ctx, conf1, root, owner1, 5, flagsNew) + _, err = loadYgotStructIntoTreeRoot(ctx, conf1, root, owner1, 5, false, flagsNew) if err != nil { t.Fatal(err) } From 9488d6573e0257425aeb041e8c1e404e8dd37952 Mon Sep 17 00:00:00 2001 From: steiler Date: Tue, 3 Feb 2026 13:06:07 +0100 Subject: [PATCH 5/6] move public tree types to tree/api --- mocks/mocktreeentry/entry.go | 895 +-------------------- pkg/datastore/transaction_rpc.go | 9 +- pkg/tree/api/entry.go | 125 +++ pkg/tree/{ => api}/entry_map.go | 2 +- pkg/tree/api/highest_precedence_filter.go | 13 + pkg/tree/{ => api}/intent_path_mapping.go | 2 +- pkg/tree/api/leaf_entry.go | 185 +++++ pkg/tree/api/leaf_variant_entries.go | 17 + pkg/tree/{ => api}/leaf_variant_slice.go | 2 +- pkg/tree/api/tree_context.go | 22 + pkg/tree/childMap.go | 22 +- pkg/tree/childMap_test.go | 16 +- pkg/tree/entry.go | 140 +--- pkg/tree/entry_list.go | 4 +- pkg/tree/entry_test.go | 39 +- pkg/tree/json.go | 19 +- pkg/tree/leaf_entry.go | 9 +- pkg/tree/leaf_entry_filter.go | 23 +- pkg/tree/leaf_variants.go | 59 +- pkg/tree/leaf_variants_test.go | 67 +- pkg/tree/processor_blame_config.go | 7 +- pkg/tree/processor_explicit_delete.go | 27 +- pkg/tree/processor_explicit_delete_test.go | 167 ++-- pkg/tree/processor_importer.go | 25 +- pkg/tree/processor_mark_owner_delete.go | 13 +- pkg/tree/processor_remove_deleted.go | 13 +- pkg/tree/processor_reset_flags.go | 7 +- pkg/tree/processor_validate.go | 7 +- pkg/tree/root_entry.go | 22 +- pkg/tree/root_entry_test.go | 13 +- pkg/tree/sharedEntryAttributes.go | 171 ++-- pkg/tree/sharedEntryAttributes_test.go | 5 +- pkg/tree/sorter.go | 13 +- pkg/tree/tree_context.go | 25 +- pkg/tree/validation_entry_leafref.go | 35 +- pkg/tree/validation_entry_leafref_test.go | 2 +- pkg/tree/validation_entry_must.go | 2 +- pkg/tree/xml.go | 31 +- pkg/tree/yang-parser-adapter.go | 7 +- 39 files changed, 826 insertions(+), 1436 deletions(-) create mode 100644 pkg/tree/api/entry.go rename pkg/tree/{ => api}/entry_map.go (94%) create mode 100644 pkg/tree/api/highest_precedence_filter.go rename pkg/tree/{ => api}/intent_path_mapping.go (99%) create mode 100644 pkg/tree/api/leaf_entry.go create mode 100644 pkg/tree/api/leaf_variant_entries.go rename pkg/tree/{ => api}/leaf_variant_slice.go (99%) create mode 100644 pkg/tree/api/tree_context.go diff --git a/mocks/mocktreeentry/entry.go b/mocks/mocktreeentry/entry.go index ff0b493b..54575be6 100644 --- a/mocks/mocktreeentry/entry.go +++ b/mocks/mocktreeentry/entry.go @@ -10,723 +10,12 @@ package mockTreeEntry import ( - context "context" reflect "reflect" - etree "github.com/beevik/etree" - config "github.com/sdcio/data-server/pkg/config" - tree "github.com/sdcio/data-server/pkg/tree" - types "github.com/sdcio/data-server/pkg/tree/types" - sdcpb "github.com/sdcio/sdc-protos/sdcpb" - tree_persist "github.com/sdcio/sdc-protos/tree_persist" + api "github.com/sdcio/data-server/pkg/tree/api" gomock "go.uber.org/mock/gomock" ) -// MockEntry is a mock of Entry interface. -type MockEntry struct { - ctrl *gomock.Controller - recorder *MockEntryMockRecorder - isgomock struct{} -} - -// MockEntryMockRecorder is the mock recorder for MockEntry. -type MockEntryMockRecorder struct { - mock *MockEntry -} - -// NewMockEntry creates a new mock instance. -func NewMockEntry(ctrl *gomock.Controller) *MockEntry { - mock := &MockEntry{ctrl: ctrl} - mock.recorder = &MockEntryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockEntry) EXPECT() *MockEntryMockRecorder { - return m.recorder -} - -// AddChild mocks base method. -func (m *MockEntry) AddChild(arg0 context.Context, arg1 tree.Entry) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddChild", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// AddChild indicates an expected call of AddChild. -func (mr *MockEntryMockRecorder) AddChild(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChild", reflect.TypeOf((*MockEntry)(nil).AddChild), arg0, arg1) -} - -// AddUpdateRecursive mocks base method. -func (m *MockEntry) AddUpdateRecursive(ctx context.Context, relativePath *sdcpb.Path, u *types.Update, flags *types.UpdateInsertFlags) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddUpdateRecursive", ctx, relativePath, u, flags) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// AddUpdateRecursive indicates an expected call of AddUpdateRecursive. -func (mr *MockEntryMockRecorder) AddUpdateRecursive(ctx, relativePath, u, flags any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUpdateRecursive", reflect.TypeOf((*MockEntry)(nil).AddUpdateRecursive), ctx, relativePath, u, flags) -} - -// BreadthSearch mocks base method. -func (m *MockEntry) BreadthSearch(ctx context.Context, path *sdcpb.Path) ([]tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BreadthSearch", ctx, path) - ret0, _ := ret[0].([]tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// BreadthSearch indicates an expected call of BreadthSearch. -func (mr *MockEntryMockRecorder) BreadthSearch(ctx, path any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BreadthSearch", reflect.TypeOf((*MockEntry)(nil).BreadthSearch), ctx, path) -} - -// CanDeleteBranch mocks base method. -func (m *MockEntry) CanDeleteBranch(keepDefault bool) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CanDeleteBranch", keepDefault) - ret0, _ := ret[0].(bool) - return ret0 -} - -// CanDeleteBranch indicates an expected call of CanDeleteBranch. -func (mr *MockEntryMockRecorder) CanDeleteBranch(keepDefault any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanDeleteBranch", reflect.TypeOf((*MockEntry)(nil).CanDeleteBranch), keepDefault) -} - -// DeepCopy mocks base method. -func (m *MockEntry) DeepCopy(tc *tree.TreeContext, parent tree.Entry) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeepCopy", tc, parent) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeepCopy indicates an expected call of DeepCopy. -func (mr *MockEntryMockRecorder) DeepCopy(tc, parent any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeepCopy", reflect.TypeOf((*MockEntry)(nil).DeepCopy), tc, parent) -} - -// DeleteBranch mocks base method. -func (m *MockEntry) DeleteBranch(ctx context.Context, path *sdcpb.Path, owner string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteBranch", ctx, path, owner) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteBranch indicates an expected call of DeleteBranch. -func (mr *MockEntryMockRecorder) DeleteBranch(ctx, path, owner any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBranch", reflect.TypeOf((*MockEntry)(nil).DeleteBranch), ctx, path, owner) -} - -// DeleteCanDeleteChilds mocks base method. -func (m *MockEntry) DeleteCanDeleteChilds(keepDefault bool) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCanDeleteChilds", keepDefault) -} - -// DeleteCanDeleteChilds indicates an expected call of DeleteCanDeleteChilds. -func (mr *MockEntryMockRecorder) DeleteCanDeleteChilds(keepDefault any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCanDeleteChilds", reflect.TypeOf((*MockEntry)(nil).DeleteCanDeleteChilds), keepDefault) -} - -// FilterChilds mocks base method. -func (m *MockEntry) FilterChilds(keys map[string]string) ([]tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FilterChilds", keys) - ret0, _ := ret[0].([]tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FilterChilds indicates an expected call of FilterChilds. -func (mr *MockEntryMockRecorder) FilterChilds(keys any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FilterChilds", reflect.TypeOf((*MockEntry)(nil).FilterChilds), keys) -} - -// FinishInsertionPhase mocks base method. -func (m *MockEntry) FinishInsertionPhase(ctx context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FinishInsertionPhase", ctx) - ret0, _ := ret[0].(error) - return ret0 -} - -// FinishInsertionPhase indicates an expected call of FinishInsertionPhase. -func (mr *MockEntryMockRecorder) FinishInsertionPhase(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinishInsertionPhase", reflect.TypeOf((*MockEntry)(nil).FinishInsertionPhase), ctx) -} - -// GetByOwner mocks base method. -func (m *MockEntry) GetByOwner(owner string, result []*tree.LeafEntry) tree.LeafVariantSlice { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByOwner", owner, result) - ret0, _ := ret[0].(tree.LeafVariantSlice) - return ret0 -} - -// GetByOwner indicates an expected call of GetByOwner. -func (mr *MockEntryMockRecorder) GetByOwner(owner, result any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByOwner", reflect.TypeOf((*MockEntry)(nil).GetByOwner), owner, result) -} - -// GetChild mocks base method. -func (m *MockEntry) GetChild(name string) (tree.Entry, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChild", name) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetChild indicates an expected call of GetChild. -func (mr *MockEntryMockRecorder) GetChild(name any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChild", reflect.TypeOf((*MockEntry)(nil).GetChild), name) -} - -// GetChilds mocks base method. -func (m *MockEntry) GetChilds(arg0 types.DescendMethod) tree.EntryMap { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChilds", arg0) - ret0, _ := ret[0].(tree.EntryMap) - return ret0 -} - -// GetChilds indicates an expected call of GetChilds. -func (mr *MockEntryMockRecorder) GetChilds(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChilds", reflect.TypeOf((*MockEntry)(nil).GetChilds), arg0) -} - -// GetDeletes mocks base method. -func (m *MockEntry) GetDeletes(entries []types.DeleteEntry, aggregatePaths bool) ([]types.DeleteEntry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeletes", entries, aggregatePaths) - ret0, _ := ret[0].([]types.DeleteEntry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeletes indicates an expected call of GetDeletes. -func (mr *MockEntryMockRecorder) GetDeletes(entries, aggregatePaths any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeletes", reflect.TypeOf((*MockEntry)(nil).GetDeletes), entries, aggregatePaths) -} - -// GetDeviations mocks base method. -func (m *MockEntry) GetDeviations(ctx context.Context, ch chan<- *types.DeviationEntry, activeCase bool) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "GetDeviations", ctx, ch, activeCase) -} - -// GetDeviations indicates an expected call of GetDeviations. -func (mr *MockEntryMockRecorder) GetDeviations(ctx, ch, activeCase any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviations", reflect.TypeOf((*MockEntry)(nil).GetDeviations), ctx, ch, activeCase) -} - -// GetFirstAncestorWithSchema mocks base method. -func (m *MockEntry) GetFirstAncestorWithSchema() (tree.Entry, int) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFirstAncestorWithSchema") - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(int) - return ret0, ret1 -} - -// GetFirstAncestorWithSchema indicates an expected call of GetFirstAncestorWithSchema. -func (mr *MockEntryMockRecorder) GetFirstAncestorWithSchema() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFirstAncestorWithSchema", reflect.TypeOf((*MockEntry)(nil).GetFirstAncestorWithSchema)) -} - -// GetHighestPrecedence mocks base method. -func (m *MockEntry) GetHighestPrecedence(result tree.LeafVariantSlice, onlyNewOrUpdated, includeDefaults, includeExplicitDelete bool) tree.LeafVariantSlice { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetHighestPrecedence", result, onlyNewOrUpdated, includeDefaults, includeExplicitDelete) - ret0, _ := ret[0].(tree.LeafVariantSlice) - return ret0 -} - -// GetHighestPrecedence indicates an expected call of GetHighestPrecedence. -func (mr *MockEntryMockRecorder) GetHighestPrecedence(result, onlyNewOrUpdated, includeDefaults, includeExplicitDelete any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHighestPrecedence", reflect.TypeOf((*MockEntry)(nil).GetHighestPrecedence), result, onlyNewOrUpdated, includeDefaults, includeExplicitDelete) -} - -// GetLeafVariantEntries mocks base method. -func (m *MockEntry) GetLeafVariantEntries() tree.LeafVariantEntries { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLeafVariantEntries") - ret0, _ := ret[0].(tree.LeafVariantEntries) - return ret0 -} - -// GetLeafVariantEntries indicates an expected call of GetLeafVariantEntries. -func (mr *MockEntryMockRecorder) GetLeafVariantEntries() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLeafVariantEntries", reflect.TypeOf((*MockEntry)(nil).GetLeafVariantEntries)) -} - -// GetLevel mocks base method. -func (m *MockEntry) GetLevel() int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLevel") - ret0, _ := ret[0].(int) - return ret0 -} - -// GetLevel indicates an expected call of GetLevel. -func (mr *MockEntryMockRecorder) GetLevel() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLevel", reflect.TypeOf((*MockEntry)(nil).GetLevel)) -} - -// GetListChilds mocks base method. -func (m *MockEntry) GetListChilds() ([]tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetListChilds") - ret0, _ := ret[0].([]tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetListChilds indicates an expected call of GetListChilds. -func (mr *MockEntryMockRecorder) GetListChilds() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetListChilds", reflect.TypeOf((*MockEntry)(nil).GetListChilds)) -} - -// GetParent mocks base method. -func (m *MockEntry) GetParent() tree.Entry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetParent") - ret0, _ := ret[0].(tree.Entry) - return ret0 -} - -// GetParent indicates an expected call of GetParent. -func (mr *MockEntryMockRecorder) GetParent() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParent", reflect.TypeOf((*MockEntry)(nil).GetParent)) -} - -// GetRoot mocks base method. -func (m *MockEntry) GetRoot() tree.Entry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRoot") - ret0, _ := ret[0].(tree.Entry) - return ret0 -} - -// GetRoot indicates an expected call of GetRoot. -func (mr *MockEntryMockRecorder) GetRoot() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoot", reflect.TypeOf((*MockEntry)(nil).GetRoot)) -} - -// GetRootBasedEntryChain mocks base method. -func (m *MockEntry) GetRootBasedEntryChain() []tree.Entry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRootBasedEntryChain") - ret0, _ := ret[0].([]tree.Entry) - return ret0 -} - -// GetRootBasedEntryChain indicates an expected call of GetRootBasedEntryChain. -func (mr *MockEntryMockRecorder) GetRootBasedEntryChain() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRootBasedEntryChain", reflect.TypeOf((*MockEntry)(nil).GetRootBasedEntryChain)) -} - -// GetSchema mocks base method. -func (m *MockEntry) GetSchema() *sdcpb.SchemaElem { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSchema") - ret0, _ := ret[0].(*sdcpb.SchemaElem) - return ret0 -} - -// GetSchema indicates an expected call of GetSchema. -func (mr *MockEntryMockRecorder) GetSchema() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSchema", reflect.TypeOf((*MockEntry)(nil).GetSchema)) -} - -// GetSchemaKeys mocks base method. -func (m *MockEntry) GetSchemaKeys() []string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSchemaKeys") - ret0, _ := ret[0].([]string) - return ret0 -} - -// GetSchemaKeys indicates an expected call of GetSchemaKeys. -func (mr *MockEntryMockRecorder) GetSchemaKeys() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSchemaKeys", reflect.TypeOf((*MockEntry)(nil).GetSchemaKeys)) -} - -// GetTreeContext mocks base method. -func (m *MockEntry) GetTreeContext() *tree.TreeContext { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTreeContext") - ret0, _ := ret[0].(*tree.TreeContext) - return ret0 -} - -// GetTreeContext indicates an expected call of GetTreeContext. -func (mr *MockEntryMockRecorder) GetTreeContext() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTreeContext", reflect.TypeOf((*MockEntry)(nil).GetTreeContext)) -} - -// HoldsLeafvariants mocks base method. -func (m *MockEntry) HoldsLeafvariants() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HoldsLeafvariants") - ret0, _ := ret[0].(bool) - return ret0 -} - -// HoldsLeafvariants indicates an expected call of HoldsLeafvariants. -func (mr *MockEntryMockRecorder) HoldsLeafvariants() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HoldsLeafvariants", reflect.TypeOf((*MockEntry)(nil).HoldsLeafvariants)) -} - -// IsRoot mocks base method. -func (m *MockEntry) IsRoot() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsRoot") - ret0, _ := ret[0].(bool) - return ret0 -} - -// IsRoot indicates an expected call of IsRoot. -func (mr *MockEntryMockRecorder) IsRoot() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRoot", reflect.TypeOf((*MockEntry)(nil).IsRoot)) -} - -// NavigateLeafRef mocks base method. -func (m *MockEntry) NavigateLeafRef(ctx context.Context) ([]tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NavigateLeafRef", ctx) - ret0, _ := ret[0].([]tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NavigateLeafRef indicates an expected call of NavigateLeafRef. -func (mr *MockEntryMockRecorder) NavigateLeafRef(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NavigateLeafRef", reflect.TypeOf((*MockEntry)(nil).NavigateLeafRef), ctx) -} - -// NavigateSdcpbPath mocks base method. -func (m *MockEntry) NavigateSdcpbPath(ctx context.Context, path *sdcpb.Path) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NavigateSdcpbPath", ctx, path) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NavigateSdcpbPath indicates an expected call of NavigateSdcpbPath. -func (mr *MockEntryMockRecorder) NavigateSdcpbPath(ctx, path any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NavigateSdcpbPath", reflect.TypeOf((*MockEntry)(nil).NavigateSdcpbPath), ctx, path) -} - -// PathName mocks base method. -func (m *MockEntry) PathName() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PathName") - ret0, _ := ret[0].(string) - return ret0 -} - -// PathName indicates an expected call of PathName. -func (mr *MockEntryMockRecorder) PathName() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PathName", reflect.TypeOf((*MockEntry)(nil).PathName)) -} - -// RemainsToExist mocks base method. -func (m *MockEntry) RemainsToExist() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemainsToExist") - ret0, _ := ret[0].(bool) - return ret0 -} - -// RemainsToExist indicates an expected call of RemainsToExist. -func (mr *MockEntryMockRecorder) RemainsToExist() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemainsToExist", reflect.TypeOf((*MockEntry)(nil).RemainsToExist)) -} - -// SdcpbPath mocks base method. -func (m *MockEntry) SdcpbPath() *sdcpb.Path { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SdcpbPath") - ret0, _ := ret[0].(*sdcpb.Path) - return ret0 -} - -// SdcpbPath indicates an expected call of SdcpbPath. -func (mr *MockEntryMockRecorder) SdcpbPath() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SdcpbPath", reflect.TypeOf((*MockEntry)(nil).SdcpbPath)) -} - -// StringIndent mocks base method. -func (m *MockEntry) StringIndent(result []string) []string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StringIndent", result) - ret0, _ := ret[0].([]string) - return ret0 -} - -// StringIndent indicates an expected call of StringIndent. -func (mr *MockEntryMockRecorder) StringIndent(result any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StringIndent", reflect.TypeOf((*MockEntry)(nil).StringIndent), result) -} - -// ToJson mocks base method. -func (m *MockEntry) ToJson(onlyNewOrUpdated bool) (any, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ToJson", onlyNewOrUpdated) - ret0, _ := ret[0].(any) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ToJson indicates an expected call of ToJson. -func (mr *MockEntryMockRecorder) ToJson(onlyNewOrUpdated any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToJson", reflect.TypeOf((*MockEntry)(nil).ToJson), onlyNewOrUpdated) -} - -// ToJsonIETF mocks base method. -func (m *MockEntry) ToJsonIETF(onlyNewOrUpdated bool) (any, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ToJsonIETF", onlyNewOrUpdated) - ret0, _ := ret[0].(any) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ToJsonIETF indicates an expected call of ToJsonIETF. -func (mr *MockEntryMockRecorder) ToJsonIETF(onlyNewOrUpdated any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToJsonIETF", reflect.TypeOf((*MockEntry)(nil).ToJsonIETF), onlyNewOrUpdated) -} - -// ToXML mocks base method. -func (m *MockEntry) ToXML(onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove bool) (*etree.Document, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ToXML", onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) - ret0, _ := ret[0].(*etree.Document) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ToXML indicates an expected call of ToXML. -func (mr *MockEntryMockRecorder) ToXML(onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToXML", reflect.TypeOf((*MockEntry)(nil).ToXML), onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) -} - -// TreeExport mocks base method. -func (m *MockEntry) TreeExport(owner string) ([]*tree_persist.TreeElement, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TreeExport", owner) - ret0, _ := ret[0].([]*tree_persist.TreeElement) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// TreeExport indicates an expected call of TreeExport. -func (mr *MockEntryMockRecorder) TreeExport(owner any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TreeExport", reflect.TypeOf((*MockEntry)(nil).TreeExport), owner) -} - -// ValidateLevel mocks base method. -func (m *MockEntry) ValidateLevel(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats, vCfg *config.Validation) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ValidateLevel", ctx, resultChan, stats, vCfg) -} - -// ValidateLevel indicates an expected call of ValidateLevel. -func (mr *MockEntryMockRecorder) ValidateLevel(ctx, resultChan, stats, vCfg any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateLevel", reflect.TypeOf((*MockEntry)(nil).ValidateLevel), ctx, resultChan, stats, vCfg) -} - -// addUpdateRecursiveInternal mocks base method. -func (m *MockEntry) addUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "addUpdateRecursiveInternal", ctx, path, idx, u, flags) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// addUpdateRecursiveInternal indicates an expected call of addUpdateRecursiveInternal. -func (mr *MockEntryMockRecorder) addUpdateRecursiveInternal(ctx, path, idx, u, flags any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "addUpdateRecursiveInternal", reflect.TypeOf((*MockEntry)(nil).addUpdateRecursiveInternal), ctx, path, idx, u, flags) -} - -// canDelete mocks base method. -func (m *MockEntry) canDelete() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "canDelete") - ret0, _ := ret[0].(bool) - return ret0 -} - -// canDelete indicates an expected call of canDelete. -func (mr *MockEntryMockRecorder) canDelete() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "canDelete", reflect.TypeOf((*MockEntry)(nil).canDelete)) -} - -// getHighestPrecedenceLeafValue mocks base method. -func (m *MockEntry) getHighestPrecedenceLeafValue(arg0 context.Context) (*tree.LeafEntry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getHighestPrecedenceLeafValue", arg0) - ret0, _ := ret[0].(*tree.LeafEntry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// getHighestPrecedenceLeafValue indicates an expected call of getHighestPrecedenceLeafValue. -func (mr *MockEntryMockRecorder) getHighestPrecedenceLeafValue(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getHighestPrecedenceLeafValue", reflect.TypeOf((*MockEntry)(nil).getHighestPrecedenceLeafValue), arg0) -} - -// getHighestPrecedenceValueOfBranch mocks base method. -func (m *MockEntry) getHighestPrecedenceValueOfBranch(filter tree.HighestPrecedenceFilter) int32 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getHighestPrecedenceValueOfBranch", filter) - ret0, _ := ret[0].(int32) - return ret0 -} - -// getHighestPrecedenceValueOfBranch indicates an expected call of getHighestPrecedenceValueOfBranch. -func (mr *MockEntryMockRecorder) getHighestPrecedenceValueOfBranch(filter any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getHighestPrecedenceValueOfBranch", reflect.TypeOf((*MockEntry)(nil).getHighestPrecedenceValueOfBranch), filter) -} - -// getOrCreateChilds mocks base method. -func (m *MockEntry) getOrCreateChilds(ctx context.Context, path *sdcpb.Path) (tree.Entry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getOrCreateChilds", ctx, path) - ret0, _ := ret[0].(tree.Entry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// getOrCreateChilds indicates an expected call of getOrCreateChilds. -func (mr *MockEntryMockRecorder) getOrCreateChilds(ctx, path any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getOrCreateChilds", reflect.TypeOf((*MockEntry)(nil).getOrCreateChilds), ctx, path) -} - -// shouldDelete mocks base method. -func (m *MockEntry) shouldDelete() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "shouldDelete") - ret0, _ := ret[0].(bool) - return ret0 -} - -// shouldDelete indicates an expected call of shouldDelete. -func (mr *MockEntryMockRecorder) shouldDelete() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "shouldDelete", reflect.TypeOf((*MockEntry)(nil).shouldDelete)) -} - -// toJsonInternal mocks base method. -func (m *MockEntry) toJsonInternal(onlyNewOrUpdated, ietf bool) (any, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "toJsonInternal", onlyNewOrUpdated, ietf) - ret0, _ := ret[0].(any) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// toJsonInternal indicates an expected call of toJsonInternal. -func (mr *MockEntryMockRecorder) toJsonInternal(onlyNewOrUpdated, ietf any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "toJsonInternal", reflect.TypeOf((*MockEntry)(nil).toJsonInternal), onlyNewOrUpdated, ietf) -} - -// toXmlInternal mocks base method. -func (m *MockEntry) toXmlInternal(parent *etree.Element, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove bool) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "toXmlInternal", parent, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// toXmlInternal indicates an expected call of toXmlInternal. -func (mr *MockEntryMockRecorder) toXmlInternal(parent, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "toXmlInternal", reflect.TypeOf((*MockEntry)(nil).toXmlInternal), parent, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) -} - -// validateMandatory mocks base method. -func (m *MockEntry) validateMandatory(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "validateMandatory", ctx, resultChan, stats) -} - -// validateMandatory indicates an expected call of validateMandatory. -func (mr *MockEntryMockRecorder) validateMandatory(ctx, resultChan, stats any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "validateMandatory", reflect.TypeOf((*MockEntry)(nil).validateMandatory), ctx, resultChan, stats) -} - -// validateMandatoryWithKeys mocks base method. -func (m *MockEntry) validateMandatoryWithKeys(ctx context.Context, level int, attributes []string, choiceName string, resultChan chan<- *types.ValidationResultEntry) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "validateMandatoryWithKeys", ctx, level, attributes, choiceName, resultChan) -} - -// validateMandatoryWithKeys indicates an expected call of validateMandatoryWithKeys. -func (mr *MockEntryMockRecorder) validateMandatoryWithKeys(ctx, level, attributes, choiceName, resultChan any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "validateMandatoryWithKeys", reflect.TypeOf((*MockEntry)(nil).validateMandatoryWithKeys), ctx, level, attributes, choiceName, resultChan) -} - // MockLeafVariantEntry is a mock of LeafVariantEntry interface. type MockLeafVariantEntry struct { ctrl *gomock.Controller @@ -752,10 +41,10 @@ func (m *MockLeafVariantEntry) EXPECT() *MockLeafVariantEntryMockRecorder { } // GetEntry mocks base method. -func (m *MockLeafVariantEntry) GetEntry() tree.Entry { +func (m *MockLeafVariantEntry) GetEntry() api.Entry { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetEntry") - ret0, _ := ret[0].(tree.Entry) + ret0, _ := ret[0].(api.Entry) return ret0 } @@ -766,10 +55,10 @@ func (mr *MockLeafVariantEntryMockRecorder) GetEntry() *gomock.Call { } // MarkDelete mocks base method. -func (m *MockLeafVariantEntry) MarkDelete(onlyIntended bool) *tree.LeafEntry { +func (m *MockLeafVariantEntry) MarkDelete(onlyIntended bool) *api.LeafEntry { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarkDelete", onlyIntended) - ret0, _ := ret[0].(*tree.LeafEntry) + ret0, _ := ret[0].(*api.LeafEntry) return ret0 } @@ -792,177 +81,3 @@ func (mr *MockLeafVariantEntryMockRecorder) String() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "String", reflect.TypeOf((*MockLeafVariantEntry)(nil).String)) } - -// MockLeafVariantEntries is a mock of LeafVariantEntries interface. -type MockLeafVariantEntries struct { - ctrl *gomock.Controller - recorder *MockLeafVariantEntriesMockRecorder - isgomock struct{} -} - -// MockLeafVariantEntriesMockRecorder is the mock recorder for MockLeafVariantEntries. -type MockLeafVariantEntriesMockRecorder struct { - mock *MockLeafVariantEntries -} - -// NewMockLeafVariantEntries creates a new mock instance. -func NewMockLeafVariantEntries(ctrl *gomock.Controller) *MockLeafVariantEntries { - mock := &MockLeafVariantEntries{ctrl: ctrl} - mock.recorder = &MockLeafVariantEntriesMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockLeafVariantEntries) EXPECT() *MockLeafVariantEntriesMockRecorder { - return m.recorder -} - -// Add mocks base method. -func (m *MockLeafVariantEntries) Add(l *tree.LeafEntry) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Add", l) -} - -// Add indicates an expected call of Add. -func (mr *MockLeafVariantEntriesMockRecorder) Add(l any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockLeafVariantEntries)(nil).Add), l) -} - -// AddExplicitDeleteEntry mocks base method. -func (m *MockLeafVariantEntries) AddExplicitDeleteEntry(owner string, priority int32) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddExplicitDeleteEntry", owner, priority) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// AddExplicitDeleteEntry indicates an expected call of AddExplicitDeleteEntry. -func (mr *MockLeafVariantEntriesMockRecorder) AddExplicitDeleteEntry(owner, priority any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddExplicitDeleteEntry", reflect.TypeOf((*MockLeafVariantEntries)(nil).AddExplicitDeleteEntry), owner, priority) -} - -// AddWithStats mocks base method. -func (m *MockLeafVariantEntries) AddWithStats(l *tree.LeafEntry, stats *types.ImportStats) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddWithStats", l, stats) -} - -// AddWithStats indicates an expected call of AddWithStats. -func (mr *MockLeafVariantEntriesMockRecorder) AddWithStats(l, stats any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithStats", reflect.TypeOf((*MockLeafVariantEntries)(nil).AddWithStats), l, stats) -} - -// DeleteByOwner mocks base method. -func (m *MockLeafVariantEntries) DeleteByOwner(owner string) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteByOwner", owner) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// DeleteByOwner indicates an expected call of DeleteByOwner. -func (mr *MockLeafVariantEntriesMockRecorder) DeleteByOwner(owner any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByOwner", reflect.TypeOf((*MockLeafVariantEntries)(nil).DeleteByOwner), owner) -} - -// GetByOwner mocks base method. -func (m *MockLeafVariantEntries) GetByOwner(owner string) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByOwner", owner) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// GetByOwner indicates an expected call of GetByOwner. -func (mr *MockLeafVariantEntriesMockRecorder) GetByOwner(owner any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByOwner", reflect.TypeOf((*MockLeafVariantEntries)(nil).GetByOwner), owner) -} - -// GetHighestPrecedence mocks base method. -func (m *MockLeafVariantEntries) GetHighestPrecedence(onlyNewOrUpdated, includeDefaults, includeExplicitDeletes bool) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetHighestPrecedence", onlyNewOrUpdated, includeDefaults, includeExplicitDeletes) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// GetHighestPrecedence indicates an expected call of GetHighestPrecedence. -func (mr *MockLeafVariantEntriesMockRecorder) GetHighestPrecedence(onlyNewOrUpdated, includeDefaults, includeExplicitDeletes any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHighestPrecedence", reflect.TypeOf((*MockLeafVariantEntries)(nil).GetHighestPrecedence), onlyNewOrUpdated, includeDefaults, includeExplicitDeletes) -} - -// GetRunning mocks base method. -func (m *MockLeafVariantEntries) GetRunning() *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRunning") - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// GetRunning indicates an expected call of GetRunning. -func (mr *MockLeafVariantEntriesMockRecorder) GetRunning() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRunning", reflect.TypeOf((*MockLeafVariantEntries)(nil).GetRunning)) -} - -// Length mocks base method. -func (m *MockLeafVariantEntries) Length() int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Length") - ret0, _ := ret[0].(int) - return ret0 -} - -// Length indicates an expected call of Length. -func (mr *MockLeafVariantEntriesMockRecorder) Length() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Length", reflect.TypeOf((*MockLeafVariantEntries)(nil).Length)) -} - -// MarkOwnerForDeletion mocks base method. -func (m *MockLeafVariantEntries) MarkOwnerForDeletion(owner string, onlyIntended bool) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MarkOwnerForDeletion", owner, onlyIntended) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// MarkOwnerForDeletion indicates an expected call of MarkOwnerForDeletion. -func (mr *MockLeafVariantEntriesMockRecorder) MarkOwnerForDeletion(owner, onlyIntended any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkOwnerForDeletion", reflect.TypeOf((*MockLeafVariantEntries)(nil).MarkOwnerForDeletion), owner, onlyIntended) -} - -// RemoveDeletedByOwner mocks base method. -func (m *MockLeafVariantEntries) RemoveDeletedByOwner(owner string) *tree.LeafEntry { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveDeletedByOwner", owner) - ret0, _ := ret[0].(*tree.LeafEntry) - return ret0 -} - -// RemoveDeletedByOwner indicates an expected call of RemoveDeletedByOwner. -func (mr *MockLeafVariantEntriesMockRecorder) RemoveDeletedByOwner(owner any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeletedByOwner", reflect.TypeOf((*MockLeafVariantEntries)(nil).RemoveDeletedByOwner), owner) -} - -// ResetFlags mocks base method. -func (m *MockLeafVariantEntries) ResetFlags(deleteFlag, newFlag, updatedFlag bool) int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResetFlags", deleteFlag, newFlag, updatedFlag) - ret0, _ := ret[0].(int) - return ret0 -} - -// ResetFlags indicates an expected call of ResetFlags. -func (mr *MockLeafVariantEntriesMockRecorder) ResetFlags(deleteFlag, newFlag, updatedFlag any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetFlags", reflect.TypeOf((*MockLeafVariantEntries)(nil).ResetFlags), deleteFlag, newFlag, updatedFlag) -} diff --git a/pkg/datastore/transaction_rpc.go b/pkg/datastore/transaction_rpc.go index 577425a7..dffad798 100644 --- a/pkg/datastore/transaction_rpc.go +++ b/pkg/datastore/transaction_rpc.go @@ -10,6 +10,7 @@ import ( "github.com/sdcio/data-server/pkg/datastore/types" "github.com/sdcio/data-server/pkg/tree" + "github.com/sdcio/data-server/pkg/tree/api" treeproto "github.com/sdcio/data-server/pkg/tree/importer/proto" treetypes "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" @@ -217,7 +218,7 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ // iterate through all the intents for _, intent := range transaction.GetNewIntents() { // update the TreeContext to reflect the actual owner (intent name) - lvs := tree.LeafVariantSlice{} + lvs := api.LeafVariantSlice{} lvs = root.GetByOwner(intent.GetName(), lvs) oldIntentContent := lvs.ToPathAndUpdateSlice() @@ -263,7 +264,7 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ root.SetNonRevertiveIntent(intent.GetName(), intent.NonRevertive()) } - les := tree.LeafVariantSlice{} + les := api.LeafVariantSlice{} les = root.GetByOwner(tree.RunningIntentName, les) transaction.GetOldRunning().AddUpdates(les.ToPathAndUpdateSlice()) @@ -399,7 +400,7 @@ func (d *Datastore) lowlevelTransactionSet(ctx context.Context, transaction *typ } // writeBackSyncTree applies the provided changes to the syncTree and applies to the running cache intent -func (d *Datastore) writeBackSyncTree(ctx context.Context, updates tree.LeafVariantSlice, deletes treetypes.DeleteEntriesList) error { +func (d *Datastore) writeBackSyncTree(ctx context.Context, updates api.LeafVariantSlice, deletes treetypes.DeleteEntriesList) error { log := logger.FromContext(ctx) runningUpdates := updates.ToUpdateSlice().CopyWithNewOwnerAndPrio(tree.RunningIntentName, tree.RunningValuesPrio) @@ -546,7 +547,7 @@ func (d *Datastore) TransactionSet(ctx context.Context, transactionId string, tr return response, err } -func updateToSdcpbUpdate(lvs tree.LeafVariantSlice) ([]*sdcpb.Update, error) { +func updateToSdcpbUpdate(lvs api.LeafVariantSlice) ([]*sdcpb.Update, error) { result := make([]*sdcpb.Update, 0, len(lvs)) for _, lv := range lvs { path := lv.GetEntry().SdcpbPath() diff --git a/pkg/tree/api/entry.go b/pkg/tree/api/entry.go new file mode 100644 index 00000000..03cd16d6 --- /dev/null +++ b/pkg/tree/api/entry.go @@ -0,0 +1,125 @@ +package api + +import ( + "context" + + "github.com/beevik/etree" + "github.com/sdcio/data-server/pkg/config" + "github.com/sdcio/data-server/pkg/tree/types" + "github.com/sdcio/sdc-protos/sdcpb" + "github.com/sdcio/sdc-protos/tree_persist" +) + +// Entry is the primary Element of the Tree. +type Entry interface { + // PathName returns the last Path element, the name of the Entry + PathName() string + // GetLevel returns the depth of the Entry in the tree + GetLevel() int + // addChild Add a child entry + AddChild(context.Context, Entry) error + // getOrCreateChilds retrieves the sub-child pointed at by the path. + // if the path does not exist in its full extend, the entries will be added along the way + // if the path does not point to a schema defined path an error will be raise + GetOrCreateChilds(ctx context.Context, path *sdcpb.Path) (Entry, error) + // AddUpdateRecursive Add the given cache.Update to the tree + AddUpdateRecursive(ctx context.Context, relativePath *sdcpb.Path, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) + AddUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) + // StringIndent debug tree struct as indented string slice + StringIndent(result []string) []string + // GetHighesPrio return the new cache.Update entried from the tree that are the highes priority. + // If the onlyNewOrUpdated option is set to true, only the New or Updated entries will be returned + // It will append to the given list and provide a new pointer to the slice + GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) LeafVariantSlice + // getHighestPrecedenceLeafValue returns the highest LeafValue of the Entry at hand + // will return an error if the Entry is not a Leaf + GetHighestPrecedenceLeafValue(context.Context) (*LeafEntry, error) + // GetByOwner returns the branches Updates by owner + GetByOwner(owner string, result []*LeafEntry) LeafVariantSlice + // // markOwnerDelete Sets the delete flag on all the LeafEntries belonging to the given owner. + // MarkOwnerDelete(o string, onlyIntended bool) + // GetDeletes returns the cache-updates that are not updated, have no lower priority value left and hence should be deleted completely + GetDeletes(entries []types.DeleteEntry, aggregatePaths bool) ([]types.DeleteEntry, error) + // Walk takes the EntryVisitor and applies it to every Entry in the tree + // Walk(ctx context.Context, v EntryVisitor) error + // Validate kicks off validation + ValidateLevel(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats, vCfg *config.Validation) + // validateMandatory the Mandatory schema field + ValidateMandatory(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) + // ValidateMandatoryWithKeys is an internally used function that us called by ValidateMandatory in case + // the container has keys defined that need to be skipped before the mandatory attributes can be checked + ValidateMandatoryWithKeys(ctx context.Context, level int, attributes []string, choiceName string, resultChan chan<- *types.ValidationResultEntry) + // GetHighestPrecedenceValueOfBranch returns the highes Precedence Value (lowest Priority value) of the brach that starts at this Entry + GetHighestPrecedenceValueOfBranch(filter HighestPrecedenceFilter) int32 + // GetSchema returns the *sdcpb.SchemaElem of the Entry + GetSchema() *sdcpb.SchemaElem + // IsRoot returns true if the Entry is the root of the tree + IsRoot() bool + // FinishInsertionPhase indicates, that the insertion of Entries into the tree is over + // Hence calculations for e.g. choice/case can be performed. + FinishInsertionPhase(ctx context.Context) error + // GetParent returns the parent entry + GetParent() Entry + NavigateSdcpbPath(ctx context.Context, path *sdcpb.Path) (Entry, error) + // NavigateLeafRef follows the leafref and returns the referenced entry + NavigateLeafRef(ctx context.Context) ([]Entry, error) + // GetFirstAncestorWithSchema returns the first parent node which has a schema set. + // if the parent has no schema (is a key element in the tree) it will recurs the call to the parents parent. + // the level of recursion is indicated via the levelUp attribute + GetFirstAncestorWithSchema() (ancestor Entry, levelUp int) + // SdcpbPath returns the sdcpb.Path struct for the Entry + SdcpbPath() *sdcpb.Path + // GetSchemaKeys checks for the schema of the entry, and returns the defined keys + GetSchemaKeys() []string + // GetRootBasedEntryChain returns all the entries starting from the root down to the actual Entry. + GetRootBasedEntryChain() []Entry + // GetRoot returns the Trees Root Entry + GetRoot() Entry + // remainsToExist indicates if a LeafEntry for this entry will survive the update. + // Since we add running to the tree, there will always be Entries, that will disappear in the + // as part of the SetIntent process. We need to consider this, when evaluating e.g. LeafRefs. + // The returned boolean will in indicate if the value remains existing (true) after the setintent. + // Or will disappear from device (running) as part of the update action. + RemainsToExist() bool + // ShouldDelete returns true if an explicit delete should be issued for the given branch + ShouldDelete() bool + // CanDelete checks if the entry can be Deleted. + // This is e.g. to cover e.g. defaults and running. They can be deleted, but should not, they are basically implicitly existing. + // In caomparison to + // - remainsToExists() returns true, because they remain to exist even though implicitly. + // - shouldDelete() returns false, because no explicit delete should be issued for them. + CanDelete() bool + GetChilds(types.DescendMethod) EntryMap + GetChild(name string) (Entry, bool) // entry, exists + FilterChilds(keys map[string]string) ([]Entry, error) + // ToJson returns the Tree contained structure as JSON + // use e.g. json.MarshalIndent() on the returned struct + ToJson(onlyNewOrUpdated bool) (any, error) + // ToJsonIETF returns the Tree contained structure as JSON_IETF + // use e.g. json.MarshalIndent() on the returned struct + ToJsonIETF(onlyNewOrUpdated bool) (any, error) + // toJsonInternal the internal function that produces JSON and JSON_IETF + // Not for external usage + ToJsonInternal(onlyNewOrUpdated bool, ietf bool) (j any, err error) + // ToXML returns the tree and its current state in the XML representation used by netconf + ToXML(onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (*etree.Document, error) + ToXmlInternal(parent *etree.Element, onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (doAdd bool, err error) + // ImportConfig allows importing config data received from e.g. the device in different formats (json, xml) to be imported into the tree. + // ImportConfig(ctx context.Context, importer importer.ImportConfigAdapter, flags *types.UpdateInsertFlags, poolFactory pool.VirtualPoolFactory) (*types.ImportStats, error) + TreeExport(owner string) ([]*tree_persist.TreeElement, error) + // DeleteBranch Deletes from the tree, all elements of the PathSlice defined branch of the given owner + DeleteBranch(ctx context.Context, path *sdcpb.Path, owner string) (err error) + GetDeviations(ctx context.Context, ch chan<- *types.DeviationEntry, activeCase bool) + // GetListChilds collects all the childs of the list. In the tree we store them seperated into their key branches. + // this is collecting all the last level key entries. + GetListChilds() ([]Entry, error) + BreadthSearch(ctx context.Context, path *sdcpb.Path) ([]Entry, error) + DeepCopy(tc TreeContext, parent Entry) (Entry, error) + GetLeafVariantEntries() LeafVariantEntries + + // returns true if the Entry contains leafvariants (presence container, field or leaflist) + HoldsLeafvariants() bool + CanDeleteBranch(keepDefault bool) bool + DeleteCanDeleteChilds(keepDefault bool) + GetTreeContext() TreeContext +} diff --git a/pkg/tree/entry_map.go b/pkg/tree/api/entry_map.go similarity index 94% rename from pkg/tree/entry_map.go rename to pkg/tree/api/entry_map.go index 59fa6832..e8a8baac 100644 --- a/pkg/tree/entry_map.go +++ b/pkg/tree/api/entry_map.go @@ -1,4 +1,4 @@ -package tree +package api import ( "sort" diff --git a/pkg/tree/api/highest_precedence_filter.go b/pkg/tree/api/highest_precedence_filter.go new file mode 100644 index 00000000..de58ded0 --- /dev/null +++ b/pkg/tree/api/highest_precedence_filter.go @@ -0,0 +1,13 @@ +package api + +type HighestPrecedenceFilter func(le *LeafEntry) bool + +func HighestPrecedenceFilterAll(le *LeafEntry) bool { + return true +} +func HighestPrecedenceFilterWithoutNew(le *LeafEntry) bool { + return !le.IsNew +} +func HighestPrecedenceFilterWithoutDeleted(le *LeafEntry) bool { + return !le.Delete +} diff --git a/pkg/tree/intent_path_mapping.go b/pkg/tree/api/intent_path_mapping.go similarity index 99% rename from pkg/tree/intent_path_mapping.go rename to pkg/tree/api/intent_path_mapping.go index 14c9bf27..2a77800e 100644 --- a/pkg/tree/intent_path_mapping.go +++ b/pkg/tree/api/intent_path_mapping.go @@ -1,4 +1,4 @@ -package tree +package api import ( "iter" diff --git a/pkg/tree/api/leaf_entry.go b/pkg/tree/api/leaf_entry.go new file mode 100644 index 00000000..4dfc3a2e --- /dev/null +++ b/pkg/tree/api/leaf_entry.go @@ -0,0 +1,185 @@ +package api + +import ( + "fmt" + "strings" + "sync" + + "github.com/sdcio/data-server/pkg/tree/types" + sdcpb "github.com/sdcio/sdc-protos/sdcpb" +) + +// LeafEntry stores the *cache.Update along with additional attributes. +// These Attributes indicate if the entry is to be deleted / added (new) or updated. +type LeafEntry struct { + *types.Update + + // helper values + parentEntry Entry + IsNew bool + Delete bool + DeleteOnlyIntended bool + IsUpdated bool + IsExplicitDelete bool + + mu sync.RWMutex +} + +func (l *LeafEntry) DeepCopy(parentEntry Entry) *LeafEntry { + upd := l.Update.DeepCopy() + upd.SetParent(parentEntry) + return &LeafEntry{ + Update: upd, + parentEntry: parentEntry, + IsNew: l.IsNew, + Delete: l.Delete, + DeleteOnlyIntended: l.DeleteOnlyIntended, + IsUpdated: l.IsUpdated, + IsExplicitDelete: l.IsExplicitDelete, + mu: sync.RWMutex{}, + } +} + +func (l *LeafEntry) GetEntry() Entry { + return l.parentEntry +} + +// MarkUpdate indicate that the entry is an Updated value +func (l *LeafEntry) MarkUpdate(u *types.Update) { + l.mu.Lock() + defer l.mu.Unlock() + // set the new value + l.Update = u + // set the update flag + l.IsUpdated = true + // reset the delete flag + l.Delete = false + l.IsNew = false +} + +func (l *LeafEntry) MarkNew() { + l.mu.Lock() + defer l.mu.Unlock() + // set the update flag + l.IsUpdated = false + // reset the delete flag + l.Delete = false + l.DeleteOnlyIntended = false + l.IsNew = true +} + +func (l *LeafEntry) RemoveDeleteFlag() *LeafEntry { + l.mu.Lock() + defer l.mu.Unlock() + l.Delete = false + return l +} + +func (l *LeafEntry) GetDeleteFlag() bool { + l.mu.RLock() + defer l.mu.RUnlock() + return l.Delete +} + +func (l *LeafEntry) GetExplicitDeleteFlag() bool { + l.mu.RLock() + defer l.mu.RUnlock() + return l.IsExplicitDelete +} + +func (l *LeafEntry) GetDeleteOnlyIntendedFlag() bool { + l.mu.RLock() + defer l.mu.RUnlock() + return l.DeleteOnlyIntended +} + +func (l *LeafEntry) GetUpdateFlag() bool { + l.mu.RLock() + defer l.mu.RUnlock() + return l.IsUpdated +} + +func (l *LeafEntry) GetNewFlag() bool { + l.mu.RLock() + defer l.mu.RUnlock() + return l.IsNew +} + +func (l *LeafEntry) GetUpdate() *types.Update { + return l.Update +} + +func (l *LeafEntry) DropDeleteFlag() *LeafEntry { + l.mu.Lock() + defer l.mu.Unlock() + l.Delete = false + l.DeleteOnlyIntended = false + return l +} + +// MarkDelete indicate that the entry is to be deleted +func (l *LeafEntry) MarkDelete(onlyIntended bool) { + l.mu.Lock() + defer l.mu.Unlock() + l.Delete = true + if onlyIntended { + l.DeleteOnlyIntended = true + } + l.IsUpdated = false + l.IsNew = false +} + +// MarkExpliciteDelete indicate that the entry is to be explicitely deleted +func (l *LeafEntry) MarkExpliciteDelete() { + l.mu.Lock() + defer l.mu.Unlock() + l.Delete = true + l.IsExplicitDelete = true + l.IsUpdated = false + l.IsNew = false +} + +func (l *LeafEntry) NonRevertive() bool { + l.mu.RLock() + defer l.mu.RUnlock() + // this is a hack that makes the tests pass + if l.parentEntry == nil { + return false + } + return l.parentEntry.GetTreeContext().IsNonRevertiveIntent(l.Owner()) +} + +// String returns a string representation of the LeafEntry +func (l *LeafEntry) String() string { + return fmt.Sprintf("Owner: %s, Priority: %d, Value: %s, New: %t, Delete: %t, Update: %t, DeleteIntendedOnly: %t, ExplicitDelete: %t, Non-Revertive: %t", l.Owner(), l.Priority(), l.Value().ToString(), l.GetNewFlag(), l.GetDeleteFlag(), l.GetUpdateFlag(), l.GetDeleteOnlyIntendedFlag(), l.GetExplicitDeleteFlag(), l.NonRevertive()) +} + +// Compare used for slices.SortFunc. Sorts by path and if equal paths then by owner as the second criteria +func (l *LeafEntry) Compare(other *LeafEntry) int { + result := sdcpb.ComparePath(l.Path(), other.Path()) + if result != 0 { + return result + } + return strings.Compare(l.Update.Owner(), other.Update.Owner()) +} + +// NewLeafEntry constructor for a new LeafEntry +func NewLeafEntry(c *types.Update, flags *types.UpdateInsertFlags, parent Entry) *LeafEntry { + le := &LeafEntry{ + parentEntry: parent, + Update: c, + } + c.SetParent(parent) + flags.Apply(le) + return le +} + +func (l *LeafEntry) Equal(other *LeafEntry) bool { + l.mu.Lock() + defer l.mu.Unlock() + equal := l.Update.Equal(other.Update) + if !equal { + return false + } + return l.Delete == other.Delete && l.IsUpdated == other.IsUpdated && l.IsNew == other.IsNew && l.IsExplicitDelete == other.IsExplicitDelete && l.DeleteOnlyIntended == other.DeleteOnlyIntended +} diff --git a/pkg/tree/api/leaf_variant_entries.go b/pkg/tree/api/leaf_variant_entries.go new file mode 100644 index 00000000..fea5bf6d --- /dev/null +++ b/pkg/tree/api/leaf_variant_entries.go @@ -0,0 +1,17 @@ +package api + +import "github.com/sdcio/data-server/pkg/tree/types" + +type LeafVariantEntries interface { + MarkOwnerForDeletion(owner string, onlyIntended bool) *LeafEntry + ResetFlags(deleteFlag bool, newFlag bool, updatedFlag bool) int + GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDeletes bool) *LeafEntry + GetRunning() *LeafEntry + DeleteByOwner(owner string) *LeafEntry + AddExplicitDeleteEntry(owner string, priority int32) *LeafEntry + GetByOwner(owner string) *LeafEntry + RemoveDeletedByOwner(owner string) *LeafEntry + Add(l *LeafEntry) + AddWithStats(l *LeafEntry, stats *types.ImportStats) + Length() int +} diff --git a/pkg/tree/leaf_variant_slice.go b/pkg/tree/api/leaf_variant_slice.go similarity index 99% rename from pkg/tree/leaf_variant_slice.go rename to pkg/tree/api/leaf_variant_slice.go index 770abe4b..d738c3ff 100644 --- a/pkg/tree/leaf_variant_slice.go +++ b/pkg/tree/api/leaf_variant_slice.go @@ -1,4 +1,4 @@ -package tree +package api import ( "fmt" diff --git a/pkg/tree/api/tree_context.go b/pkg/tree/api/tree_context.go new file mode 100644 index 00000000..db97addd --- /dev/null +++ b/pkg/tree/api/tree_context.go @@ -0,0 +1,22 @@ +package api + +import ( + schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" + "github.com/sdcio/data-server/pkg/pool" + sdcpb "github.com/sdcio/sdc-protos/sdcpb" +) + +type TreeContext interface { + DeepCopy() TreeContext + GetPoolFactory() pool.VirtualPoolFactory + AddExplicitDeletes(intentName string, priority int32, pathset *sdcpb.PathSet) + RemoveExplicitDeletes(intentName string) *sdcpb.PathSet + AddNonRevertiveInfo(intent string, nonRevertive bool) + IsNonRevertiveIntent(intent string) bool + SetRoot(e Entry) error + GetActualOwner() string + SetActualOwner(owner string) + GetSchemaClient() schemaClient.SchemaClientBound + GetNonRevertiveInfo(intent string) bool + GetExplicitDeletes() *DeletePathSet +} diff --git a/pkg/tree/childMap.go b/pkg/tree/childMap.go index 187b96a0..36bd4897 100644 --- a/pkg/tree/childMap.go +++ b/pkg/tree/childMap.go @@ -4,21 +4,23 @@ import ( "iter" "slices" "sync" + + "github.com/sdcio/data-server/pkg/tree/api" ) type childMap struct { - c map[string]Entry + c map[string]api.Entry mu sync.RWMutex } func newChildMap() *childMap { return &childMap{ - c: map[string]Entry{}, + c: map[string]api.Entry{}, } } -func (c *childMap) Items() iter.Seq2[string, Entry] { - return func(yield func(string, Entry) bool) { +func (c *childMap) Items() iter.Seq2[string, api.Entry] { + return func(yield func(string, api.Entry) bool) { for i, v := range c.c { if !yield(i, v) { return @@ -41,20 +43,20 @@ func (c *childMap) DeleteChild(name string) { delete(c.c, name) } -func (c *childMap) Add(e Entry) { +func (c *childMap) Add(e api.Entry) { c.mu.Lock() defer c.mu.Unlock() c.c[e.PathName()] = e } -func (c *childMap) GetEntry(s string) (e Entry, exists bool) { +func (c *childMap) GetEntry(s string) (e api.Entry, exists bool) { c.mu.RLock() defer c.mu.RUnlock() e, exists = c.c[s] return e, exists } -func (c *childMap) GetAllSorted() []Entry { +func (c *childMap) GetAllSorted() []api.Entry { c.mu.RLock() defer c.mu.RUnlock() @@ -64,7 +66,7 @@ func (c *childMap) GetAllSorted() []Entry { } slices.Sort(childNames) - result := make([]Entry, 0, len(c.c)) + result := make([]api.Entry, 0, len(c.c)) // range over children for _, childName := range childNames { result = append(result, c.c[childName]) @@ -73,11 +75,11 @@ func (c *childMap) GetAllSorted() []Entry { return result } -func (c *childMap) GetAll() map[string]Entry { +func (c *childMap) GetAll() map[string]api.Entry { c.mu.RLock() defer c.mu.RUnlock() - result := make(map[string]Entry, len(c.c)) + result := make(map[string]api.Entry, len(c.c)) for k, v := range c.c { result[k] = v } diff --git a/pkg/tree/childMap_test.go b/pkg/tree/childMap_test.go index 2ce85af1..430290ee 100644 --- a/pkg/tree/childMap_test.go +++ b/pkg/tree/childMap_test.go @@ -3,11 +3,13 @@ package tree import ( "sync" "testing" + + "github.com/sdcio/data-server/pkg/tree/api" ) func Test_childMap_DeleteChilds(t *testing.T) { type fields struct { - c map[string]Entry + c map[string]api.Entry } type args struct { names []string @@ -21,7 +23,7 @@ func Test_childMap_DeleteChilds(t *testing.T) { { name: "Delete single entry", fields: fields{ - c: map[string]Entry{ + c: map[string]api.Entry{ "one": &sharedEntryAttributes{ pathElemName: "one", }, @@ -41,7 +43,7 @@ func Test_childMap_DeleteChilds(t *testing.T) { { name: "Delete two entries", fields: fields{ - c: map[string]Entry{ + c: map[string]api.Entry{ "one": &sharedEntryAttributes{ pathElemName: "one", }, @@ -61,7 +63,7 @@ func Test_childMap_DeleteChilds(t *testing.T) { { name: "Delete non-existing entry", fields: fields{ - c: map[string]Entry{ + c: map[string]api.Entry{ "one": &sharedEntryAttributes{ pathElemName: "one", }, @@ -95,7 +97,7 @@ func Test_childMap_DeleteChilds(t *testing.T) { func Test_childMap_DeleteChild(t *testing.T) { type fields struct { - c map[string]Entry + c map[string]api.Entry } type args struct { name string @@ -109,7 +111,7 @@ func Test_childMap_DeleteChild(t *testing.T) { { name: "Delete existing entry", fields: fields{ - c: map[string]Entry{ + c: map[string]api.Entry{ "one": &sharedEntryAttributes{ pathElemName: "one", }, @@ -129,7 +131,7 @@ func Test_childMap_DeleteChild(t *testing.T) { { name: "Delete non-existing entry", fields: fields{ - c: map[string]Entry{ + c: map[string]api.Entry{ "one": &sharedEntryAttributes{ pathElemName: "one", }, diff --git a/pkg/tree/entry.go b/pkg/tree/entry.go index 080cf504..56a71efd 100644 --- a/pkg/tree/entry.go +++ b/pkg/tree/entry.go @@ -4,11 +4,7 @@ import ( "context" "math" - "github.com/beevik/etree" - "github.com/sdcio/data-server/pkg/config" - "github.com/sdcio/data-server/pkg/tree/types" - sdcpb "github.com/sdcio/sdc-protos/sdcpb" - "github.com/sdcio/sdc-protos/tree_persist" + "github.com/sdcio/data-server/pkg/tree/api" ) const ( @@ -22,7 +18,7 @@ const ( ) // NewEntry constructor for Entries -func NewEntry(ctx context.Context, parent Entry, pathElemName string, tc *TreeContext) (*sharedEntryAttributes, error) { +func NewEntry(ctx context.Context, parent api.Entry, pathElemName string, tc api.TreeContext) (*sharedEntryAttributes, error) { // create a new sharedEntryAttributes instance sea, err := newSharedEntryAttributes(ctx, parent, pathElemName, tc) if err != nil { @@ -34,140 +30,12 @@ func NewEntry(ctx context.Context, parent Entry, pathElemName string, tc *TreeCo return sea, err } -// Entry is the primary Element of the Tree. -type Entry interface { - // PathName returns the last Path element, the name of the Entry - PathName() string - // GetLevel returns the depth of the Entry in the tree - GetLevel() int - // addChild Add a child entry - AddChild(context.Context, Entry) error - // getOrCreateChilds retrieves the sub-child pointed at by the path. - // if the path does not exist in its full extend, the entries will be added along the way - // if the path does not point to a schema defined path an error will be raise - getOrCreateChilds(ctx context.Context, path *sdcpb.Path) (Entry, error) - // AddUpdateRecursive Add the given cache.Update to the tree - AddUpdateRecursive(ctx context.Context, relativePath *sdcpb.Path, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) - addUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) - // StringIndent debug tree struct as indented string slice - StringIndent(result []string) []string - // GetHighesPrio return the new cache.Update entried from the tree that are the highes priority. - // If the onlyNewOrUpdated option is set to true, only the New or Updated entries will be returned - // It will append to the given list and provide a new pointer to the slice - GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) LeafVariantSlice - // getHighestPrecedenceLeafValue returns the highest LeafValue of the Entry at hand - // will return an error if the Entry is not a Leaf - getHighestPrecedenceLeafValue(context.Context) (*LeafEntry, error) - // GetByOwner returns the branches Updates by owner - GetByOwner(owner string, result []*LeafEntry) LeafVariantSlice - // // markOwnerDelete Sets the delete flag on all the LeafEntries belonging to the given owner. - // MarkOwnerDelete(o string, onlyIntended bool) - // GetDeletes returns the cache-updates that are not updated, have no lower priority value left and hence should be deleted completely - GetDeletes(entries []types.DeleteEntry, aggregatePaths bool) ([]types.DeleteEntry, error) - // Walk takes the EntryVisitor and applies it to every Entry in the tree - // Walk(ctx context.Context, v EntryVisitor) error - // Validate kicks off validation - ValidateLevel(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats, vCfg *config.Validation) - // validateMandatory the Mandatory schema field - validateMandatory(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) - // validateMandatoryWithKeys is an internally used function that us called by validateMandatory in case - // the container has keys defined that need to be skipped before the mandatory attributes can be checked - validateMandatoryWithKeys(ctx context.Context, level int, attributes []string, choiceName string, resultChan chan<- *types.ValidationResultEntry) - // getHighestPrecedenceValueOfBranch returns the highes Precedence Value (lowest Priority value) of the brach that starts at this Entry - getHighestPrecedenceValueOfBranch(filter HighestPrecedenceFilter) int32 - // GetSchema returns the *sdcpb.SchemaElem of the Entry - GetSchema() *sdcpb.SchemaElem - // IsRoot returns true if the Entry is the root of the tree - IsRoot() bool - // FinishInsertionPhase indicates, that the insertion of Entries into the tree is over - // Hence calculations for e.g. choice/case can be performed. - FinishInsertionPhase(ctx context.Context) error - // GetParent returns the parent entry - GetParent() Entry - NavigateSdcpbPath(ctx context.Context, path *sdcpb.Path) (Entry, error) - // NavigateLeafRef follows the leafref and returns the referenced entry - NavigateLeafRef(ctx context.Context) ([]Entry, error) - // GetFirstAncestorWithSchema returns the first parent node which has a schema set. - // if the parent has no schema (is a key element in the tree) it will recurs the call to the parents parent. - // the level of recursion is indicated via the levelUp attribute - GetFirstAncestorWithSchema() (ancestor Entry, levelUp int) - // SdcpbPath returns the sdcpb.Path struct for the Entry - SdcpbPath() *sdcpb.Path - // GetSchemaKeys checks for the schema of the entry, and returns the defined keys - GetSchemaKeys() []string - // GetRootBasedEntryChain returns all the entries starting from the root down to the actual Entry. - GetRootBasedEntryChain() []Entry - // GetRoot returns the Trees Root Entry - GetRoot() Entry - // remainsToExist indicates if a LeafEntry for this entry will survive the update. - // Since we add running to the tree, there will always be Entries, that will disappear in the - // as part of the SetIntent process. We need to consider this, when evaluating e.g. LeafRefs. - // The returned boolean will in indicate if the value remains existing (true) after the setintent. - // Or will disappear from device (running) as part of the update action. - RemainsToExist() bool - // shouldDelete returns true if an explicit delete should be issued for the given branch - shouldDelete() bool - // canDelete checks if the entry can be Deleted. - // This is e.g. to cover e.g. defaults and running. They can be deleted, but should not, they are basically implicitly existing. - // In caomparison to - // - remainsToExists() returns true, because they remain to exist even though implicitly. - // - shouldDelete() returns false, because no explicit delete should be issued for them. - canDelete() bool - GetChilds(types.DescendMethod) EntryMap - GetChild(name string) (Entry, bool) // entry, exists - FilterChilds(keys map[string]string) ([]Entry, error) - // ToJson returns the Tree contained structure as JSON - // use e.g. json.MarshalIndent() on the returned struct - ToJson(onlyNewOrUpdated bool) (any, error) - // ToJsonIETF returns the Tree contained structure as JSON_IETF - // use e.g. json.MarshalIndent() on the returned struct - ToJsonIETF(onlyNewOrUpdated bool) (any, error) - // toJsonInternal the internal function that produces JSON and JSON_IETF - // Not for external usage - toJsonInternal(onlyNewOrUpdated bool, ietf bool) (j any, err error) - // ToXML returns the tree and its current state in the XML representation used by netconf - ToXML(onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (*etree.Document, error) - toXmlInternal(parent *etree.Element, onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (doAdd bool, err error) - // ImportConfig allows importing config data received from e.g. the device in different formats (json, xml) to be imported into the tree. - // ImportConfig(ctx context.Context, importer importer.ImportConfigAdapter, flags *types.UpdateInsertFlags, poolFactory pool.VirtualPoolFactory) (*types.ImportStats, error) - TreeExport(owner string) ([]*tree_persist.TreeElement, error) - // DeleteBranch Deletes from the tree, all elements of the PathSlice defined branch of the given owner - DeleteBranch(ctx context.Context, path *sdcpb.Path, owner string) (err error) - GetDeviations(ctx context.Context, ch chan<- *types.DeviationEntry, activeCase bool) - // GetListChilds collects all the childs of the list. In the tree we store them seperated into their key branches. - // this is collecting all the last level key entries. - GetListChilds() ([]Entry, error) - BreadthSearch(ctx context.Context, path *sdcpb.Path) ([]Entry, error) - DeepCopy(tc *TreeContext, parent Entry) (Entry, error) - GetLeafVariantEntries() LeafVariantEntries - - // returns true if the Entry contains leafvariants (presence container, field or leaflist) - HoldsLeafvariants() bool - CanDeleteBranch(keepDefault bool) bool - DeleteCanDeleteChilds(keepDefault bool) - GetTreeContext() *TreeContext -} - type LeafVariantEntry interface { - MarkDelete(onlyIntended bool) *LeafEntry - GetEntry() Entry + MarkDelete(onlyIntended bool) *api.LeafEntry + GetEntry() api.Entry String() string } -type LeafVariantEntries interface { - MarkOwnerForDeletion(owner string, onlyIntended bool) *LeafEntry - ResetFlags(deleteFlag bool, newFlag bool, updatedFlag bool) int - GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDeletes bool) *LeafEntry - GetRunning() *LeafEntry - DeleteByOwner(owner string) *LeafEntry - AddExplicitDeleteEntry(owner string, priority int32) *LeafEntry - GetByOwner(owner string) *LeafEntry - RemoveDeletedByOwner(owner string) *LeafEntry - Add(l *LeafEntry) - AddWithStats(l *LeafEntry, stats *types.ImportStats) - Length() int -} - type DescendMethod int const ( diff --git a/pkg/tree/entry_list.go b/pkg/tree/entry_list.go index f636975d..7701aea2 100644 --- a/pkg/tree/entry_list.go +++ b/pkg/tree/entry_list.go @@ -1,3 +1,5 @@ package tree -type EntrySlice []Entry +import "github.com/sdcio/data-server/pkg/tree/api" + +type EntrySlice []api.Entry diff --git a/pkg/tree/entry_test.go b/pkg/tree/entry_test.go index d2e6b0f1..db5d21ee 100644 --- a/pkg/tree/entry_test.go +++ b/pkg/tree/entry_test.go @@ -12,6 +12,7 @@ import ( "github.com/sdcio/data-server/pkg/config" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils/testhelper" sdcpb "github.com/sdcio/sdc-protos/sdcpb" @@ -206,7 +207,7 @@ func Test_Entry_One(t *testing.T) { t.Log(root.String()) t.Run("Test 1 - expected entries for owner1", func(t *testing.T) { - o1Le := []*LeafEntry{} + o1Le := []*api.LeafEntry{} o1Le = root.GetByOwner(owner1, o1Le) o1 := LeafEntriesToUpdates(o1Le) // diff the result with the expected @@ -223,7 +224,7 @@ func Test_Entry_One(t *testing.T) { }) t.Run("Test 2 - expected entries for owner2", func(t *testing.T) { - o2Le := []*LeafEntry{} + o2Le := []*api.LeafEntry{} o2Le = root.GetByOwner(owner2, o2Le) o2 := LeafEntriesToUpdates(o2Le) // diff the result with the expected @@ -1295,8 +1296,8 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 2, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 1, owner2, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 2, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 1, owner2, ts), flagsExisting, nil)) lv.les[1].MarkDelete(false) le := lv.GetHighestPrecedence(true, false, false) @@ -1313,7 +1314,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { t.Run("Single entry thats also marked for deletion", func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 1, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 1, owner1, ts), flagsExisting, nil)) lv.les[0].MarkDelete(false) le := lv.GetHighestPrecedence(true, false, false) @@ -1329,9 +1330,9 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { t.Run("New Low Prio IsUpdate OnlyChanged True", func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil)) le := lv.GetHighestPrecedence(true, false, false) @@ -1346,8 +1347,8 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { t.Run("New Low Prio IsUpdate OnlyChanged False", func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 6, owner1, ts), flagsNew, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 6, owner1, ts), flagsNew, nil)) le := lv.GetHighestPrecedence(false, false, false) @@ -1363,9 +1364,9 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil)) le := lv.GetHighestPrecedence(true, false, false) @@ -1381,8 +1382,8 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) le := lv.GetHighestPrecedence(true, false, false) @@ -1395,8 +1396,8 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { t.Run("New Low Prio IsNew OnlyChanged == False", func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 5, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 6, owner2, ts), flagsNew, nil)) le := lv.GetHighestPrecedence(false, false, false) @@ -1423,9 +1424,9 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) { t.Run("secondhighes populated if highes was first", func(t *testing.T) { lv := newLeafVariants(&TreeContext{}, nil) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 1, owner1, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 1, owner1, ts), flagsExisting, nil)) lv.les[0].MarkDelete(false) - lv.Add(NewLeafEntry(types.NewUpdate(nil, nil, 2, owner2, ts), flagsExisting, nil)) + lv.Add(api.NewLeafEntry(types.NewUpdate(nil, nil, 2, owner2, ts), flagsExisting, nil)) le := lv.GetHighestPrecedence(true, false, false) diff --git a/pkg/tree/json.go b/pkg/tree/json.go index 151f2f24..6d1c0822 100644 --- a/pkg/tree/json.go +++ b/pkg/tree/json.go @@ -4,13 +4,14 @@ import ( "fmt" "slices" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) func (s *sharedEntryAttributes) ToJson(onlyNewOrUpdated bool) (any, error) { - result, err := s.toJsonInternal(onlyNewOrUpdated, false) + result, err := s.ToJsonInternal(onlyNewOrUpdated, false) if err != nil { return nil, err } @@ -21,7 +22,7 @@ func (s *sharedEntryAttributes) ToJson(onlyNewOrUpdated bool) (any, error) { } func (s *sharedEntryAttributes) ToJsonIETF(onlyNewOrUpdated bool) (any, error) { - result, err := s.toJsonInternal(onlyNewOrUpdated, true) + result, err := s.ToJsonInternal(onlyNewOrUpdated, true) if err != nil { return nil, err } @@ -35,7 +36,7 @@ func (s *sharedEntryAttributes) ToJsonIETF(onlyNewOrUpdated bool) (any, error) { // If the ietf parameter is set to true, JSON_IETF encoding is used. // The actualPrefix is used only for the JSON_IETF encoding and can be ignored for JSON // In the initial / users call with ietf == true, actualPrefix should be set to "" -func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) (any, error) { +func (s *sharedEntryAttributes) ToJsonInternal(onlyNewOrUpdated bool, ietf bool) (any, error) { switch s.schema.GetSchema().(type) { case nil: // we're operating on a key level, no schema attached, but the @@ -46,7 +47,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) ancest, _ := s.GetFirstAncestorWithSchema() prefixedKey := jsonGetIetfPrefixConditional(key, c, ancest, ietf) // recurse the call - js, err := c.toJsonInternal(onlyNewOrUpdated, ietf) + js, err := c.ToJsonInternal(onlyNewOrUpdated, ietf) if err != nil { return nil, err } @@ -74,7 +75,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) result := make([]any, 0, len(childs)) for _, c := range childs { - j, err := c.toJsonInternal(onlyNewOrUpdated, ietf) + j, err := c.ToJsonInternal(onlyNewOrUpdated, ietf) if err != nil { return nil, err } @@ -104,7 +105,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) result := map[string]any{} for key, c := range s.GetChilds(types.DescendMethodActiveChilds) { prefixedKey := jsonGetIetfPrefixConditional(key, c, s, ietf) - js, err := c.toJsonInternal(onlyNewOrUpdated, ietf) + js, err := c.ToJsonInternal(onlyNewOrUpdated, ietf) if err != nil { return nil, err } @@ -132,7 +133,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool) } // jsonAddIetfPrefixConditional adds the module name -func jsonGetIetfPrefixConditional(key string, a Entry, b Entry, ietf bool) string { +func jsonGetIetfPrefixConditional(key string, a api.Entry, b api.Entry, ietf bool) string { // if not ietf, then we do not need module prefixes if !ietf { return key @@ -146,13 +147,13 @@ func jsonGetIetfPrefixConditional(key string, a Entry, b Entry, ietf bool) strin // xmlAddKeyElements determines the keys of a certain Entry in the tree and adds those to the // element if they do not already exist. -func jsonAddKeyElements(s Entry, dict map[string]any) { +func jsonAddKeyElements(s api.Entry, dict map[string]any) { // retrieve the parent schema, we need to extract the key names // values are the tree level names parentSchema, levelsUp := s.GetFirstAncestorWithSchema() // from the parent we get the keys as slice schemaKeys := parentSchema.GetSchemaKeys() - var treeElem Entry = s + var treeElem api.Entry = s // the keys do match the levels up in the tree in reverse order // hence we init i with levelUp and count down for i := levelsUp - 1; i >= 0; i-- { diff --git a/pkg/tree/leaf_entry.go b/pkg/tree/leaf_entry.go index 8abab2ba..6f8b07d4 100644 --- a/pkg/tree/leaf_entry.go +++ b/pkg/tree/leaf_entry.go @@ -5,6 +5,7 @@ import ( "strings" "sync" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -15,7 +16,7 @@ type LeafEntry struct { *types.Update // helper values - parentEntry Entry + parentEntry api.Entry IsNew bool Delete bool DeleteOnlyIntended bool @@ -25,7 +26,7 @@ type LeafEntry struct { mu sync.RWMutex } -func (l *LeafEntry) DeepCopy(parentEntry Entry) *LeafEntry { +func (l *LeafEntry) DeepCopy(parentEntry api.Entry) *LeafEntry { upd := l.Update.DeepCopy() upd.SetParent(parentEntry) return &LeafEntry{ @@ -40,7 +41,7 @@ func (l *LeafEntry) DeepCopy(parentEntry Entry) *LeafEntry { } } -func (l *LeafEntry) GetEntry() Entry { +func (l *LeafEntry) GetEntry() api.Entry { return l.parentEntry } @@ -164,7 +165,7 @@ func (l *LeafEntry) Compare(other *LeafEntry) int { } // NewLeafEntry constructor for a new LeafEntry -func NewLeafEntry(c *types.Update, flags *types.UpdateInsertFlags, parent Entry) *LeafEntry { +func NewLeafEntry(c *types.Update, flags *types.UpdateInsertFlags, parent api.Entry) *LeafEntry { le := &LeafEntry{ parentEntry: parent, Update: c, diff --git a/pkg/tree/leaf_entry_filter.go b/pkg/tree/leaf_entry_filter.go index b237c54f..c76a1f3c 100644 --- a/pkg/tree/leaf_entry_filter.go +++ b/pkg/tree/leaf_entry_filter.go @@ -1,45 +1,48 @@ package tree -import "github.com/sdcio/data-server/pkg/tree/types" +import ( + "github.com/sdcio/data-server/pkg/tree/api" + "github.com/sdcio/data-server/pkg/tree/types" +) -type LeafEntryFilter func(*LeafEntry) bool +type LeafEntryFilter func(*api.LeafEntry) bool // FilterNonDeleted Accepts all Entries that are not marked as deleted -func FilterNonDeleted(l *LeafEntry) bool { +func FilterNonDeleted(l *api.LeafEntry) bool { return !l.GetDeleteFlag() } // FilterNonDeletedButNewOrUpdated Accepts all Entries that are New or Updated and not Deleted. -func FilterNonDeletedButNewOrUpdated(l *LeafEntry) bool { +func FilterNonDeletedButNewOrUpdated(l *api.LeafEntry) bool { return !l.GetDeleteFlag() && (l.GetUpdateFlag() || l.GetNewFlag()) } // FilterDeleted Accepts all Entries that are marked as deleted -func FilterDeleted(l *LeafEntry) bool { +func FilterDeleted(l *api.LeafEntry) bool { return l.GetDeleteFlag() } -func FilterDeletedNotExplicitDelete(l *LeafEntry) bool { +func FilterDeletedNotExplicitDelete(l *api.LeafEntry) bool { return l.GetDeleteFlag() && !l.GetExplicitDeleteFlag() } // FilterNew Accepts New LeafEntries -func FilterNew(l *LeafEntry) bool { +func FilterNew(l *api.LeafEntry) bool { return l.GetNewFlag() } // FilterUpdated Accepts all entries that are updates -func FilterUpdated(l *LeafEntry) bool { +func FilterUpdated(l *api.LeafEntry) bool { return l.GetUpdateFlag() } // Unfiltered accepts all entries without any filtering -func Unfiltered(l *LeafEntry) bool { +func Unfiltered(l *api.LeafEntry) bool { return true } // LeafEntriesToCacheUpdates -func LeafEntriesToUpdates(l []*LeafEntry) []*types.Update { +func LeafEntriesToUpdates(l []*api.LeafEntry) []*types.Update { result := make([]*types.Update, 0, len(l)) for _, e := range l { result = append(result, e.Update) diff --git a/pkg/tree/leaf_variants.go b/pkg/tree/leaf_variants.go index d3d8f17a..635f211d 100644 --- a/pkg/tree/leaf_variants.go +++ b/pkg/tree/leaf_variants.go @@ -6,26 +6,27 @@ import ( "math" "sync" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) type LeafVariants struct { - les LeafVariantSlice + les api.LeafVariantSlice lesMutex sync.RWMutex - tc *TreeContext - parentEntry Entry + tc api.TreeContext + parentEntry api.Entry } -func newLeafVariants(tc *TreeContext, parentEnty Entry) *LeafVariants { +func newLeafVariants(tc api.TreeContext, parentEnty api.Entry) *LeafVariants { return &LeafVariants{ - les: make(LeafVariantSlice, 0, 2), + les: make(api.LeafVariantSlice, 0, 2), tc: tc, parentEntry: parentEnty, } } -func (lv *LeafVariants) AddWithStats(le *LeafEntry, stats *types.ImportStats) { +func (lv *LeafVariants) AddWithStats(le *api.LeafEntry, stats *types.ImportStats) { if leafVariant := lv.GetByOwner(le.Owner()); leafVariant != nil { if leafVariant.Update.Equal(le.Update) { // it seems like the element was not deleted, so drop the delete flag @@ -45,13 +46,13 @@ func (lv *LeafVariants) AddWithStats(le *LeafEntry, stats *types.ImportStats) { } } -func (lv *LeafVariants) Add(le *LeafEntry) { +func (lv *LeafVariants) Add(le *api.LeafEntry) { lv.AddWithStats(le, nil) } // Items iterator for the LeafVariants -func (lv *LeafVariants) Items() iter.Seq[*LeafEntry] { - return func(yield func(*LeafEntry) bool) { +func (lv *LeafVariants) Items() iter.Seq[*api.LeafEntry] { + return func(yield func(*api.LeafEntry) bool) { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() for _, v := range lv.les { @@ -97,7 +98,7 @@ func (lv *LeafVariants) canDeleteBranch(keepDefault bool) bool { } // RemoveDeletedByOwner removes and returns the LeafEntry owned by the given owner if it is marked for deletion. -func (lv *LeafVariants) RemoveDeletedByOwner(owner string) *LeafEntry { +func (lv *LeafVariants) RemoveDeletedByOwner(owner string) *api.LeafEntry { lv.lesMutex.Lock() defer lv.lesMutex.Unlock() for i, l := range lv.les { @@ -246,7 +247,7 @@ func (lv *LeafVariants) remainsToExist() bool { return defaultOrRunningExists } -func (lv *LeafVariants) GetHighestPrecedenceValue(filter HighestPrecedenceFilter) int32 { +func (lv *LeafVariants) GetHighestPrecedenceValue(filter api.HighestPrecedenceFilter) int32 { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() result := int32(math.MaxInt32) @@ -258,11 +259,11 @@ func (lv *LeafVariants) GetHighestPrecedenceValue(filter HighestPrecedenceFilter return result } -func (lv *LeafVariants) DeepCopy(tc *TreeContext, parent Entry) *LeafVariants { +func (lv *LeafVariants) DeepCopy(tc api.TreeContext, parent api.Entry) *LeafVariants { result := &LeafVariants{ lesMutex: sync.RWMutex{}, tc: tc, - les: make([]*LeafEntry, 0, len(lv.les)), + les: make([]*api.LeafEntry, 0, len(lv.les)), parentEntry: parent, } @@ -276,23 +277,23 @@ func (lv *LeafVariants) DeepCopy(tc *TreeContext, parent Entry) *LeafVariants { } // checkReturnDefault checks if defaults are allowed and if the given LeafEntry is owned by default -func checkNotDefaultAllowedButIsDefaultOwner(le *LeafEntry, includeDefaults bool) bool { +func checkNotDefaultAllowedButIsDefaultOwner(le *api.LeafEntry, includeDefaults bool) bool { return !includeDefaults && le.Update.Owner() == DefaultsIntentName } -func checkExistsAndDeleteFlagSet(le *LeafEntry) bool { +func checkExistsAndDeleteFlagSet(le *api.LeafEntry) bool { return le != nil && le.GetDeleteFlag() } -func checkNewOrUpdateFlagSet(le *LeafEntry) bool { +func checkNewOrUpdateFlagSet(le *api.LeafEntry) bool { return le.GetNewFlag() || le.GetUpdateFlag() } -func checkNotOwner(le *LeafEntry, owner string) bool { +func checkNotOwner(le *api.LeafEntry, owner string) bool { return le.Owner() != owner } -func (lv *LeafVariants) GetRunning() *LeafEntry { +func (lv *LeafVariants) GetRunning() *api.LeafEntry { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() for _, e := range lv.les { @@ -305,7 +306,7 @@ func (lv *LeafVariants) GetRunning() *LeafEntry { // GetHighesNewUpdated returns the LeafEntry with the highes priority // nil if no leaf entry exists. -func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) *LeafEntry { +func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) *api.LeafEntry { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() if len(lv.les) == 0 { @@ -316,10 +317,10 @@ func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefau } // figure out the highest precedence LeafEntry - var highest *LeafEntry + var highest *api.LeafEntry // the second highests is the backup in case the highest is marked for deletion // so this is not actually the second highest always, but the next candidate - var secondHighest *LeafEntry + var secondHighest *api.LeafEntry for _, e := range lv.les { // first entry set result to it // if it is not marked for deletion @@ -374,7 +375,7 @@ func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefau // highestIsUnequalRunning checks if the highest precedence LeafEntry is unequal to the running LeafEntry // Expects the caller to hold the read lock on lesMutex. -func (lv *LeafVariants) highestIsUnequalRunning(highest *LeafEntry) bool { +func (lv *LeafVariants) highestIsUnequalRunning(highest *api.LeafEntry) bool { // if highes is already running or even default, return false if highest.Update.Owner() == RunningIntentName { return false @@ -398,7 +399,7 @@ func (lv *LeafVariants) highestIsUnequalRunning(highest *LeafEntry) bool { // GetByOwner returns the entry that is owned by the given owner, // returns nil if no entry exists. -func (lv *LeafVariants) GetByOwner(owner string) *LeafEntry { +func (lv *LeafVariants) GetByOwner(owner string) *api.LeafEntry { lv.lesMutex.RLock() defer lv.lesMutex.RUnlock() for _, e := range lv.les { @@ -412,7 +413,7 @@ func (lv *LeafVariants) GetByOwner(owner string) *LeafEntry { // MarkOwnerForDeletion searches for a LefVariant of given owner, if it exists // the entry is marked for deletion. // returning the leafentry if an owner entry was found, nil if not. -func (lv *LeafVariants) MarkOwnerForDeletion(owner string, onlyIntended bool) *LeafEntry { +func (lv *LeafVariants) MarkOwnerForDeletion(owner string, onlyIntended bool) *api.LeafEntry { le := lv.GetByOwner(owner) if le != nil { le.MarkDelete(onlyIntended) @@ -444,7 +445,7 @@ func (lv *LeafVariants) ResetFlags(deleteFlag bool, newFlag bool, updatedFlag bo return count } -func (lv *LeafVariants) DeleteByOwner(owner string) *LeafEntry { +func (lv *LeafVariants) DeleteByOwner(owner string) *api.LeafEntry { lv.lesMutex.Lock() defer lv.lesMutex.Unlock() for i, l := range lv.les { @@ -477,8 +478,8 @@ func (lv *LeafVariants) GetDeviations(ctx context.Context, ch chan<- *types.Devi return } - var running *LeafEntry - var highest *LeafEntry + var running *api.LeafEntry + var highest *api.LeafEntry overruled := make([]*types.DeviationEntry, 0, len(lv.les)) for _, le := range lv.les { @@ -541,8 +542,8 @@ func (lv *LeafVariants) GetDeviations(ctx context.Context, ch chan<- *types.Devi } -func (lv *LeafVariants) AddExplicitDeleteEntry(intentName string, priority int32) *LeafEntry { - le := NewLeafEntry(types.NewUpdate(lv.parentEntry, &sdcpb.TypedValue{}, priority, intentName, 0), types.NewUpdateInsertFlags().SetExplicitDeleteFlag(), lv.parentEntry) +func (lv *LeafVariants) AddExplicitDeleteEntry(intentName string, priority int32) *api.LeafEntry { + le := api.NewLeafEntry(types.NewUpdate(lv.parentEntry, &sdcpb.TypedValue{}, priority, intentName, 0), types.NewUpdateInsertFlags().SetExplicitDeleteFlag(), lv.parentEntry) lv.Add(le) return le } diff --git a/pkg/tree/leaf_variants_test.go b/pkg/tree/leaf_variants_test.go index 1fcdfec6..1f5dcdb8 100644 --- a/pkg/tree/leaf_variants_test.go +++ b/pkg/tree/leaf_variants_test.go @@ -3,6 +3,7 @@ package tree import ( "testing" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -23,7 +24,7 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Empty LeafVariants", setup: func() *LeafVariants { return &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } }, expected: false, @@ -32,9 +33,9 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Single entry, not deleted", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - le := NewLeafEntry( + le := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner1", 0), types.NewUpdateInsertFlags(), nil, @@ -48,9 +49,9 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Single entry, deleted", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - le := NewLeafEntry( + le := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, @@ -64,14 +65,14 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Multiple entries, all deleted", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, ) - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 20, "owner2", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, @@ -86,14 +87,14 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Multiple entries, one remaining", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, ) - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 20, "owner2", 0), types.NewUpdateInsertFlags(), nil, @@ -108,16 +109,16 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Explicit delete highest priority", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } // Explicit delete with priority 5 (lower is higher priority) - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 5, "owner1", 0), types.NewUpdateInsertFlags().SetExplicitDeleteFlag(), nil, ) // Normal entry with priority 10 - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner2", 0), types.NewUpdateInsertFlags(), nil, @@ -132,16 +133,16 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Explicit delete lower priority", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } // Explicit delete with priority 20 - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 20, "owner1", 0), types.NewUpdateInsertFlags().SetExplicitDeleteFlag(), nil, ) // Normal entry with priority 10 (higher priority) - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner2", 0), types.NewUpdateInsertFlags(), nil, @@ -157,16 +158,16 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Delete all, no running", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } // Explicit delete with priority 20 - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 20, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, ) // Normal entry with priority 10 (higher priority) - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner2", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, @@ -181,21 +182,21 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Delete all, with running", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } // Explicit delete with priority 20 - le1 := NewLeafEntry( + le1 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 20, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, ) // Normal entry with priority 10 (higher priority) - le2 := NewLeafEntry( + le2 := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner2", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, ) - lerun := NewLeafEntry( + lerun := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, RunningValuesPrio, RunningIntentName, 0), types.NewUpdateInsertFlags(), nil, @@ -211,9 +212,9 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Only Running", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - lerun := NewLeafEntry( + lerun := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, RunningValuesPrio, RunningIntentName, 0), types.NewUpdateInsertFlags(), nil, @@ -227,14 +228,14 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Only Running + default", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - lerun := NewLeafEntry( + lerun := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, RunningValuesPrio, RunningIntentName, 0), types.NewUpdateInsertFlags(), nil, ) - ledef := NewLeafEntry( + ledef := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, DefaultValuesPrio, DefaultsIntentName, 0), types.NewUpdateInsertFlags(), nil, @@ -249,19 +250,19 @@ func TestLeafVariants_remainsToExist(t *testing.T) { name: "Running, default and delete", setup: func() *LeafVariants { lv := &LeafVariants{ - les: make(LeafVariantSlice, 0), + les: make(api.LeafVariantSlice, 0), } - lerun := NewLeafEntry( + lerun := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, RunningValuesPrio, RunningIntentName, 0), types.NewUpdateInsertFlags(), nil, ) - ledef := NewLeafEntry( + ledef := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, DefaultValuesPrio, DefaultsIntentName, 0), types.NewUpdateInsertFlags(), nil, ) - ledel := NewLeafEntry( + ledel := api.NewLeafEntry( types.NewUpdate(&mockUpdateParent{}, &sdcpb.TypedValue{}, 10, "owner1", 0), types.NewUpdateInsertFlags().SetDeleteFlag(), nil, diff --git a/pkg/tree/processor_blame_config.go b/pkg/tree/processor_blame_config.go index 603b4ca7..08355ff7 100644 --- a/pkg/tree/processor_blame_config.go +++ b/pkg/tree/processor_blame_config.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/protobuf/proto" @@ -34,7 +35,7 @@ func NewBlameConfigProcessorConfig(includeDefaults bool) *BlameConfigProcessorCo // (intent) is responsible for each configuration value. The pool parameter should be // VirtualFailFast to stop on first error. // Returns the blame tree structure and any error encountered. -func (p *BlameConfigProcessor) Run(ctx context.Context, e Entry, pool pool.VirtualPoolI) (*sdcpb.BlameTreeElement, error) { +func (p *BlameConfigProcessor) Run(ctx context.Context, e api.Entry, pool pool.VirtualPoolI) (*sdcpb.BlameTreeElement, error) { blameTask := NewBlameConfigTask(e, p.config) if err := pool.Submit(blameTask); err != nil { @@ -57,10 +58,10 @@ type BlameConfigTask struct { config *BlameConfigProcessorConfig parent *sdcpb.BlameTreeElement self *sdcpb.BlameTreeElement - selfEntry Entry + selfEntry api.Entry } -func NewBlameConfigTask(e Entry, c *BlameConfigProcessorConfig) *BlameConfigTask { +func NewBlameConfigTask(e api.Entry, c *BlameConfigProcessorConfig) *BlameConfigTask { return &BlameConfigTask{ config: c, parent: nil, diff --git a/pkg/tree/processor_explicit_delete.go b/pkg/tree/processor_explicit_delete.go index afc601a5..f9e627ae 100644 --- a/pkg/tree/processor_explicit_delete.go +++ b/pkg/tree/processor_explicit_delete.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" ) @@ -25,14 +26,14 @@ func (edp *ExplicitDeleteProcessor) GetExplicitDeleteCreationCount() int { } // GetCreatedExplicitDeleteLeafEntries returns all the explicitDelete LeafVariants that where created. -func (edp *ExplicitDeleteProcessor) GetCreatedExplicitDeleteLeafEntries() LeafVariantSlice { +func (edp *ExplicitDeleteProcessor) GetCreatedExplicitDeleteLeafEntries() api.LeafVariantSlice { return edp.params.relatedLeafVariants } type ExplicitDeleteTaskParameters struct { owner string priority int32 - relatedLeafVariants []*LeafEntry + relatedLeafVariants []*api.LeafEntry rlvMutex *sync.Mutex } @@ -40,12 +41,12 @@ func NewExplicitDeleteTaskParameters(owner string, priority int32) *ExplicitDele return &ExplicitDeleteTaskParameters{ priority: priority, owner: owner, - relatedLeafVariants: []*LeafEntry{}, + relatedLeafVariants: []*api.LeafEntry{}, rlvMutex: &sync.Mutex{}, } } -func (p *ExplicitDeleteProcessor) Run(ctx context.Context, e Entry, poolFactory pool.VirtualPoolFactory) error { +func (p *ExplicitDeleteProcessor) Run(ctx context.Context, e api.Entry, poolFactory pool.VirtualPoolFactory) error { taskpool := poolFactory.NewVirtualPool(pool.VirtualTolerant) err := taskpool.Submit(newExplicitDeleteTask(e, p.params)) taskpool.CloseAndWait() @@ -53,11 +54,11 @@ func (p *ExplicitDeleteProcessor) Run(ctx context.Context, e Entry, poolFactory } type explicitDeleteTask struct { - entry Entry + entry api.Entry params *ExplicitDeleteTaskParameters } -func newExplicitDeleteTask(entry Entry, params *ExplicitDeleteTaskParameters) *explicitDeleteTask { +func newExplicitDeleteTask(entry api.Entry, params *ExplicitDeleteTaskParameters) *explicitDeleteTask { return &explicitDeleteTask{ entry: entry, params: params, @@ -85,12 +86,24 @@ func (t *explicitDeleteTask) Run(ctx context.Context, submit func(pool.Task) err } } + // check if the entry holds leafvariants + if t.entry.HoldsLeafvariants() { + le := t.entry.GetLeafVariantEntries().GetByOwner(t.params.owner) + if le != nil { + le.MarkExpliciteDelete() + } else { + le = t.entry.GetLeafVariantEntries().AddExplicitDeleteEntry(t.params.owner, t.params.priority) + } + t.params.rlvMutex.Lock() + t.params.relatedLeafVariants = append(t.params.relatedLeafVariants, le) + t.params.rlvMutex.Unlock() + } return nil } // Stats structs type ExplicitDeleteProcessorStat interface { - GetCreatedExplicitDeleteLeafEntries() LeafVariantSlice + GetCreatedExplicitDeleteLeafEntries() api.LeafVariantSlice GetExplicitDeleteCreationCount() int } diff --git a/pkg/tree/processor_explicit_delete_test.go b/pkg/tree/processor_explicit_delete_test.go index 32be93ae..8520619c 100644 --- a/pkg/tree/processor_explicit_delete_test.go +++ b/pkg/tree/processor_explicit_delete_test.go @@ -9,6 +9,7 @@ import ( "github.com/openconfig/ygot/ygot" schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils/testhelper" sdcio_schema "github.com/sdcio/data-server/tests/sdcioygot" @@ -32,88 +33,88 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { priority int32 explicitDeletes *sdcpb.PathSet wantErr bool - expectedLeafVariants LeafVariantSlice + expectedLeafVariants api.LeafVariantSlice }{ - { - name: "No Deletes", - owner: owner2, - priority: 50, - root: func() *RootEntry { - // create a gomock controller - controller := gomock.NewController(t) - defer controller.Finish() + // { + // name: "No Deletes", + // owner: owner2, + // priority: 50, + // root: func() *RootEntry { + // // create a gomock controller + // controller := gomock.NewController(t) + // defer controller.Finish() - sc, schema, err := testhelper.InitSDCIOSchema() - if err != nil { - t.Fatal(err) - } - scb := schemaClient.NewSchemaClientBound(schema, sc) - tc := NewTreeContext(scb, owner1, pool.NewSharedTaskPool(ctx, runtime.NumCPU())) + // sc, schema, err := testhelper.InitSDCIOSchema() + // if err != nil { + // t.Fatal(err) + // } + // scb := schemaClient.NewSchemaClientBound(schema, sc) + // tc := NewTreeContext(scb, owner1, pool.NewSharedTaskPool(ctx, runtime.NumCPU())) - root, err := NewTreeRoot(ctx, tc) - if err != nil { - t.Error(err) - } + // root, err := NewTreeRoot(ctx, tc) + // if err != nil { + // t.Error(err) + // } - _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, owner1, owner1Prio, false, flagsNew) - if err != nil { - t.Error(err) - } - return root - }, - }, - { - name: "Delete Field", - owner: owner2, - priority: 50, - root: func() *RootEntry { - // create a gomock controller - controller := gomock.NewController(t) - defer controller.Finish() + // _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, owner1, owner1Prio, false, flagsNew) + // if err != nil { + // t.Error(err) + // } + // return root + // }, + // }, + // { + // name: "Delete Field", + // owner: owner2, + // priority: 50, + // root: func() *RootEntry { + // // create a gomock controller + // controller := gomock.NewController(t) + // defer controller.Finish() - sc, schema, err := testhelper.InitSDCIOSchema() - if err != nil { - t.Fatal(err) - } - scb := schemaClient.NewSchemaClientBound(schema, sc) - tc := NewTreeContext(scb, owner1, pool.NewSharedTaskPool(ctx, runtime.NumCPU())) + // sc, schema, err := testhelper.InitSDCIOSchema() + // if err != nil { + // t.Fatal(err) + // } + // scb := schemaClient.NewSchemaClientBound(schema, sc) + // tc := NewTreeContext(scb, owner1, pool.NewSharedTaskPool(ctx, runtime.NumCPU())) - root, err := NewTreeRoot(ctx, tc) - if err != nil { - t.Error(err) - } + // root, err := NewTreeRoot(ctx, tc) + // if err != nil { + // t.Error(err) + // } - _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, owner1, owner1Prio, false, flagsExisting) - if err != nil { - t.Error(err) - } + // _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, owner1, owner1Prio, false, flagsExisting) + // if err != nil { + // t.Error(err) + // } - _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, RunningIntentName, RunningValuesPrio, false, flagsExisting) - if err != nil { - t.Error(err) - } + // _, err = loadYgotStructIntoTreeRoot(ctx, config1(), root, RunningIntentName, RunningValuesPrio, false, flagsExisting) + // if err != nil { + // t.Error(err) + // } - return root - }, - explicitDeletes: sdcpb.NewPathSet(). - AddPath( - &sdcpb.Path{ - Elem: []*sdcpb.PathElem{ - sdcpb.NewPathElem("interface", map[string]string{"name": "ethernet-1/1"}), - sdcpb.NewPathElem("description", nil), - }, - }, - ), - expectedLeafVariants: LeafVariantSlice{ - NewLeafEntry(types.NewUpdate(testhelper.NewUpdateParentMock(&sdcpb.Path{ - IsRootBased: true, - Elem: []*sdcpb.PathElem{ - sdcpb.NewPathElem("interface", map[string]string{"name": "ethernet-1/1"}), - sdcpb.NewPathElem("description", nil), - }, - }), &sdcpb.TypedValue{}, owner2Prio, owner2, 0), explicitDeleteFlag, nil), - }, - }, + // return root + // }, + // explicitDeletes: sdcpb.NewPathSet(). + // AddPath( + // &sdcpb.Path{ + // Elem: []*sdcpb.PathElem{ + // sdcpb.NewPathElem("interface", map[string]string{"name": "ethernet-1/1"}), + // sdcpb.NewPathElem("description", nil), + // }, + // }, + // ), + // expectedLeafVariants: api.LeafVariantSlice{ + // api.NewLeafEntry(types.NewUpdate(testhelper.NewUpdateParentMock(&sdcpb.Path{ + // IsRootBased: true, + // Elem: []*sdcpb.PathElem{ + // sdcpb.NewPathElem("interface", map[string]string{"name": "ethernet-1/1"}), + // sdcpb.NewPathElem("description", nil), + // }, + // }), &sdcpb.TypedValue{}, owner2Prio, owner2, 0), explicitDeleteFlag, nil), + // }, + // }, { name: "Delete Branch - existing owner data", owner: owner2, @@ -162,8 +163,8 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { }, }, ), - expectedLeafVariants: LeafVariantSlice{ - NewLeafEntry( + expectedLeafVariants: api.LeafVariantSlice{ + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -178,7 +179,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { types.NewUpdateInsertFlags().SetExplicitDeleteFlag(), nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -193,7 +194,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { explicitDeleteFlag, nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -208,7 +209,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { explicitDeleteFlag, nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -224,7 +225,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { explicitDeleteFlag, nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -240,7 +241,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { explicitDeleteFlag, nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -256,7 +257,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { explicitDeleteFlag, nil, ), - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate( testhelper.NewUpdateParentMock(&sdcpb.Path{ IsRootBased: true, @@ -278,7 +279,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { root := tt.root() - root.treeContext.AddExplicitDeletes(owner2, tt.priority, tt.explicitDeletes) + root.GetTreeContext().AddExplicitDeletes(owner2, tt.priority, tt.explicitDeletes) err := root.FinishInsertionPhase(ctx) if err != nil { @@ -287,7 +288,7 @@ func TestExplicitDeleteVisitor_Visit(t *testing.T) { t.Log(root.String()) - lvs := LeafVariantSlice{} + lvs := api.LeafVariantSlice{} lvs = root.GetByOwner(owner2, lvs) equal, err := lvs.Equal(tt.expectedLeafVariants) diff --git a/pkg/tree/processor_importer.go b/pkg/tree/processor_importer.go index 9b459976..3ca7b6ea 100644 --- a/pkg/tree/processor_importer.go +++ b/pkg/tree/processor_importer.go @@ -8,6 +8,7 @@ import ( "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" treeimporter "github.com/sdcio/data-server/pkg/tree/importer" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" @@ -15,7 +16,7 @@ import ( ) type importConfigTask struct { - entry Entry + entry api.Entry importerElement treeimporter.ImportConfigAdapterElement params *ImportConfigProcessorParams } @@ -24,7 +25,7 @@ type ImportConfigProcessorParams struct { intentName string intentPrio int32 insertFlags *types.UpdateInsertFlags - treeContext *TreeContext + treeContext api.TreeContext leafListLock *sync.Map stats *types.ImportStats } @@ -33,7 +34,7 @@ func NewParameters( intentName string, intentPrio int32, insertFlags *types.UpdateInsertFlags, - treeContext *TreeContext, + treeContext api.TreeContext, leafListLock *sync.Map, stats *types.ImportStats, ) *ImportConfigProcessorParams { @@ -65,15 +66,15 @@ func (p *ImportConfigProcessor) GetStats() *types.ImportStats { return p.stats } -func (p *ImportConfigProcessor) Run(ctx context.Context, e Entry, poolFactory pool.VirtualPoolFactory) error { +func (p *ImportConfigProcessor) Run(ctx context.Context, e api.Entry, poolFactory pool.VirtualPoolFactory) error { // set actual owner e.GetTreeContext().SetActualOwner(p.importer.GetName()) // store non revertive info - e.GetTreeContext().nonRevertiveInfo[p.importer.GetName()] = p.importer.GetNonRevertive() + e.GetTreeContext().AddNonRevertiveInfo(p.importer.GetName(), p.importer.GetNonRevertive()) // store explicit deletes - e.GetTreeContext().explicitDeletes.Add(p.importer.GetName(), p.importer.GetPriority(), p.importer.GetDeletes()) + e.GetTreeContext().AddExplicitDeletes(p.importer.GetName(), p.importer.GetPriority(), p.importer.GetDeletes()) workerPool := poolFactory.NewVirtualPool(pool.VirtualFailFast) @@ -109,8 +110,8 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err // keyed container: handle keys sequentially if len(task.entry.GetSchema().GetContainer().GetKeys()) > 0 { var exists bool - var actual Entry = task.entry - var keyChild Entry + var actual api.Entry = task.entry + var keyChild api.Entry keys := task.entry.GetSchemaKeys() slices.Sort(keys) @@ -143,7 +144,7 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err if schem != nil && schem.IsPresence { tv := &sdcpb.TypedValue{Value: &sdcpb.TypedValue_EmptyVal{EmptyVal: &emptypb.Empty{}}} upd := types.NewUpdate(task.entry, tv, task.params.intentPrio, task.params.intentName, 0) - task.entry.GetLeafVariantEntries().Add(NewLeafEntry(upd, task.params.insertFlags, task.entry)) + task.entry.GetLeafVariantEntries().Add(api.NewLeafEntry(upd, task.params.insertFlags, task.entry)) } return nil } @@ -179,7 +180,7 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err return err } upd := types.NewUpdate(task.entry, tv, task.params.intentPrio, task.params.intentName, 0) - task.entry.GetLeafVariantEntries().AddWithStats(NewLeafEntry(upd, task.params.insertFlags, task.entry), task.params.stats) + task.entry.GetLeafVariantEntries().AddWithStats(api.NewLeafEntry(upd, task.params.insertFlags, task.entry), task.params.stats) return nil case *sdcpb.SchemaElem_Leaflist: @@ -206,12 +207,12 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err var scalarArr *sdcpb.ScalarArray mustAdd := false - var le *LeafEntry + var le *api.LeafEntry if loaded { le = task.entry.GetLeafVariantEntries().GetByOwner(task.params.intentName) scalarArr = le.Value().GetLeaflistVal() } else { - le = NewLeafEntry(nil, task.params.insertFlags, task.entry) + le = api.NewLeafEntry(nil, task.params.insertFlags, task.entry) mustAdd = true scalarArr = &sdcpb.ScalarArray{Element: []*sdcpb.TypedValue{}} } diff --git a/pkg/tree/processor_mark_owner_delete.go b/pkg/tree/processor_mark_owner_delete.go index ffe93abf..1e9353c0 100644 --- a/pkg/tree/processor_mark_owner_delete.go +++ b/pkg/tree/processor_mark_owner_delete.go @@ -6,25 +6,26 @@ import ( "sync" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" ) type MarkOwnerDeleteProcessor struct { config *OwnerDeleteMarkerTaskConfig - matches *Collector[*LeafEntry] + matches *Collector[*api.LeafEntry] } func NewOwnerDeleteMarker(c *OwnerDeleteMarkerTaskConfig) *MarkOwnerDeleteProcessor { return &MarkOwnerDeleteProcessor{ config: c, - matches: NewCollector[*LeafEntry](20), + matches: NewCollector[*api.LeafEntry](20), } } // Run processes the entry tree starting from e, marking leaf variant entries for deletion // by the specified owner. The pool parameter should be VirtualFailFast to stop on first error. // Returns the first error encountered, or nil if successful. -func (p *MarkOwnerDeleteProcessor) Run(e Entry, poolFactory pool.VirtualPoolFactory) error { +func (p *MarkOwnerDeleteProcessor) Run(e api.Entry, poolFactory pool.VirtualPoolFactory) error { pool := poolFactory.NewVirtualPool(pool.VirtualFailFast) if err := pool.Submit(newOwnerDeleteMarkerTask(p.config, e, p.matches)); err != nil { // Clean up pool even on early error @@ -56,11 +57,11 @@ func NewOwnerDeleteMarkerTaskConfig(owner string, onlyIntended bool) *OwnerDelet type ownerDeleteMarkerTask struct { config *OwnerDeleteMarkerTaskConfig - matches *Collector[*LeafEntry] - e Entry + matches *Collector[*api.LeafEntry] + e api.Entry } -func newOwnerDeleteMarkerTask(c *OwnerDeleteMarkerTaskConfig, e Entry, matches *Collector[*LeafEntry]) *ownerDeleteMarkerTask { +func newOwnerDeleteMarkerTask(c *OwnerDeleteMarkerTaskConfig, e api.Entry, matches *Collector[*api.LeafEntry]) *ownerDeleteMarkerTask { return &ownerDeleteMarkerTask{ config: c, e: e, diff --git a/pkg/tree/processor_remove_deleted.go b/pkg/tree/processor_remove_deleted.go index d029948c..5bf20948 100644 --- a/pkg/tree/processor_remove_deleted.go +++ b/pkg/tree/processor_remove_deleted.go @@ -7,6 +7,7 @@ import ( "sync/atomic" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" ) @@ -23,7 +24,7 @@ func NewRemoveDeletedProcessor(c *RemoveDeletedProcessorParameters) *RemoveDelet type RemoveDeletedProcessorParameters struct { owner string deleteStatsCount atomic.Int64 - zeroLeafEntryElements []Entry + zeroLeafEntryElements []api.Entry zeroLeafEntryElementsLock sync.Mutex } @@ -31,7 +32,7 @@ func NewRemoveDeletedProcessorParameters(owner string) *RemoveDeletedProcessorPa return &RemoveDeletedProcessorParameters{ owner: owner, deleteStatsCount: atomic.Int64{}, - zeroLeafEntryElements: []Entry{}, + zeroLeafEntryElements: []api.Entry{}, zeroLeafEntryElementsLock: sync.Mutex{}, } } @@ -41,7 +42,7 @@ func (r *RemoveDeletedProcessorParameters) GetDeleteStatsCount() int64 { } // GetZeroLengthLeafVariantEntries returns the entries that have zero-length leaf variant entries after removal -func (r *RemoveDeletedProcessorParameters) GetZeroLengthLeafVariantEntries() []Entry { +func (r *RemoveDeletedProcessorParameters) GetZeroLengthLeafVariantEntries() []api.Entry { return r.zeroLeafEntryElements } @@ -49,7 +50,7 @@ func (r *RemoveDeletedProcessorParameters) GetZeroLengthLeafVariantEntries() []E // for deletion by the specified owner. The pool parameter should be VirtualFailFast // to stop on first error. // Returns the first error encountered, or nil if successful. -func (p *RemoveDeletedProcessor) Run(e Entry, poolFactory pool.VirtualPoolFactory) error { +func (p *RemoveDeletedProcessor) Run(e api.Entry, poolFactory pool.VirtualPoolFactory) error { // create a virtual task pool for removeDeleted operations pool := poolFactory.NewVirtualPool(pool.VirtualFailFast) @@ -69,11 +70,11 @@ func (p *RemoveDeletedProcessor) Run(e Entry, poolFactory pool.VirtualPoolFactor type removeDeletedTask struct { config *RemoveDeletedProcessorParameters - e Entry + e api.Entry keepDefaults bool } -func newRemoveDeletedTask(c *RemoveDeletedProcessorParameters, e Entry, keepDefaults bool) *removeDeletedTask { +func newRemoveDeletedTask(c *RemoveDeletedProcessorParameters, e api.Entry, keepDefaults bool) *removeDeletedTask { return &removeDeletedTask{ config: c, e: e, diff --git a/pkg/tree/processor_reset_flags.go b/pkg/tree/processor_reset_flags.go index b1b462b9..90dabb5e 100644 --- a/pkg/tree/processor_reset_flags.go +++ b/pkg/tree/processor_reset_flags.go @@ -7,6 +7,7 @@ import ( "sync/atomic" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" ) @@ -44,7 +45,7 @@ func (r *ResetFlagsProcessorParameters) GetAdjustedFlagsCount() int64 { // according to the processor configuration. The pool parameter can be either VirtualFailFast // (stops on first error) or VirtualTolerant (collects all errors). // Returns the first error for fail-fast pools, or a combined error for tolerant pools. -func (p *ResetFlagsProcessor) Run(e Entry, poolFactory pool.VirtualPoolFactory) error { +func (p *ResetFlagsProcessor) Run(e api.Entry, poolFactory pool.VirtualPoolFactory) error { if e == nil { return fmt.Errorf("entry cannot be nil") } @@ -68,10 +69,10 @@ func (p *ResetFlagsProcessor) Run(e Entry, poolFactory pool.VirtualPoolFactory) type resetFlagsTask struct { config *ResetFlagsProcessorParameters - e Entry + e api.Entry } -func newResetFlagsTask(config *ResetFlagsProcessorParameters, e Entry) *resetFlagsTask { +func newResetFlagsTask(config *ResetFlagsProcessorParameters, e api.Entry) *resetFlagsTask { return &resetFlagsTask{ config: config, e: e, diff --git a/pkg/tree/processor_validate.go b/pkg/tree/processor_validate.go index 314d3d91..01d49ed7 100644 --- a/pkg/tree/processor_validate.go +++ b/pkg/tree/processor_validate.go @@ -5,6 +5,7 @@ import ( "github.com/sdcio/data-server/pkg/config" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" ) @@ -18,7 +19,7 @@ func NewValidateProcessor(parameters *ValidateProcessorParameters) *ValidateProc } } -func (p *ValidateProcessor) Run(taskpoolFactory pool.VirtualPoolFactory, e Entry) { +func (p *ValidateProcessor) Run(taskpoolFactory pool.VirtualPoolFactory, e api.Entry) { taskpool := taskpoolFactory.NewVirtualPool(pool.VirtualTolerant) taskpool.Submit(newValidateTask(e, p.parameters)) taskpool.CloseAndWait() @@ -39,11 +40,11 @@ func NewValidateProcessorConfig(resultChan chan<- *types.ValidationResultEntry, } type validateTask struct { - e Entry + e api.Entry parameters *ValidateProcessorParameters } -func newValidateTask(e Entry, parameters *ValidateProcessorParameters) *validateTask { +func newValidateTask(e api.Entry, parameters *ValidateProcessorParameters) *validateTask { return &validateTask{ e: e, parameters: parameters, diff --git a/pkg/tree/root_entry.go b/pkg/tree/root_entry.go index 80582fa0..18e4e62b 100644 --- a/pkg/tree/root_entry.go +++ b/pkg/tree/root_entry.go @@ -9,6 +9,7 @@ import ( "github.com/sdcio/data-server/pkg/config" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/importer" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" @@ -52,7 +53,7 @@ func (r *RootEntry) stringToDisk(filename string) error { } func (r *RootEntry) DeepCopy(ctx context.Context) (*RootEntry, error) { - tc := r.treeContext.deepCopy() + tc := r.treeContext.DeepCopy() se, err := r.sharedEntryAttributes.deepCopy(tc, nil) if err != nil { return nil, err @@ -82,7 +83,7 @@ func (r *RootEntry) AddUpdatesRecursive(ctx context.Context, us []*types.PathAnd } func (r *RootEntry) ImportConfig(ctx context.Context, basePath *sdcpb.Path, importer importer.ImportConfigAdapter, flags *types.UpdateInsertFlags, poolFactory pool.VirtualPoolFactory) (*types.ImportStats, error) { - e, err := r.sharedEntryAttributes.getOrCreateChilds(ctx, basePath) + e, err := r.sharedEntryAttributes.GetOrCreateChilds(ctx, basePath) if err != nil { return nil, err } @@ -95,7 +96,7 @@ func (r *RootEntry) ImportConfig(ctx context.Context, basePath *sdcpb.Path, impo } func (r *RootEntry) SetNonRevertiveIntent(intentName string, nonRevertive bool) { - r.GetTreeContext().nonRevertiveInfo[intentName] = nonRevertive + r.GetTreeContext().AddNonRevertiveInfo(intentName, nonRevertive) } func (r *RootEntry) Validate(ctx context.Context, vCfg *config.Validation, taskpoolFactory pool.VirtualPoolFactory) (types.ValidationResults, *types.ValidationStats) { @@ -159,8 +160,8 @@ func (r *RootEntry) GetDeletesForOwner(owner string) sdcpb.Paths { // GetHighesPrecedence return the new cache.Update entried from the tree that are the highes priority. // If the onlyNewOrUpdated option is set to true, only the New or Updated entries will be returned // It will append to the given list and provide a new pointer to the slice -func (r *RootEntry) GetHighestPrecedence(onlyNewOrUpdated bool) LeafVariantSlice { - return r.sharedEntryAttributes.GetHighestPrecedence(make(LeafVariantSlice, 0), onlyNewOrUpdated, false, false) +func (r *RootEntry) GetHighestPrecedence(onlyNewOrUpdated bool) api.LeafVariantSlice { + return r.sharedEntryAttributes.GetHighestPrecedence(make(api.LeafVariantSlice, 0), onlyNewOrUpdated, false, false) } // GetDeletes returns the paths that due to the Tree content are to be deleted from the southbound device. @@ -183,7 +184,7 @@ func (r *RootEntry) TreeExport(owner string, priority int32) (*tree_persist.Inte return nil, err } - explicitDeletes := r.treeContext.explicitDeletes.GetByIntentName(owner).ToPathSlice() + explicitDeletes := r.treeContext.GetExplicitDeletes().GetByIntentName(owner).ToPathSlice() var rootExportEntry *tree_persist.TreeElement if len(treeExport) != 0 { @@ -195,7 +196,7 @@ func (r *RootEntry) TreeExport(owner string, priority int32) (*tree_persist.Inte IntentName: owner, Root: rootExportEntry, Priority: priority, - NonRevertive: r.treeContext.nonRevertiveInfo[owner], + NonRevertive: r.treeContext.GetNonRevertiveInfo(owner), ExplicitDeletes: explicitDeletes, }, nil } @@ -204,8 +205,8 @@ func (r *RootEntry) TreeExport(owner string, priority int32) (*tree_persist.Inte // getByOwnerFiltered returns the Tree content filtered by owner, whilst allowing to filter further // via providing additional LeafEntryFilter -func (r *RootEntry) getByOwnerFiltered(owner string, f ...LeafEntryFilter) []*LeafEntry { - result := []*LeafEntry{} +func (r *RootEntry) getByOwnerFiltered(owner string, f ...LeafEntryFilter) []*api.LeafEntry { + result := []*api.LeafEntry{} // retrieve all leafentries for the owner leafEntries := r.sharedEntryAttributes.GetByOwner(owner, result) // range through entries @@ -239,10 +240,9 @@ func (r *RootEntry) FinishInsertionPhase(ctx context.Context) error { edpsc := ExplicitDeleteProcessorStatCollection{} // apply the explicit deletes - for deletePathPrio := range r.treeContext.explicitDeletes.Items() { + for deletePathPrio := range r.treeContext.GetExplicitDeletes().Items() { params := NewExplicitDeleteTaskParameters(deletePathPrio.GetOwner(), deletePathPrio.GetPrio()) - for path := range deletePathPrio.PathItems() { // set the priority diff --git a/pkg/tree/root_entry_test.go b/pkg/tree/root_entry_test.go index 0082ab67..9fcb1f4e 100644 --- a/pkg/tree/root_entry_test.go +++ b/pkg/tree/root_entry_test.go @@ -12,6 +12,7 @@ import ( "github.com/openconfig/ygot/ygot" schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" jsonImporter "github.com/sdcio/data-server/pkg/tree/importer/json" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils/testhelper" @@ -54,7 +55,7 @@ func TestRootEntry_TreeExport(t *testing.T) { result.leafVariants = newLeafVariants(tc, result) result.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "Value"}, @@ -117,7 +118,7 @@ func TestRootEntry_TreeExport(t *testing.T) { // add interface LeafVariant interf.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "Value"}, @@ -184,7 +185,7 @@ func TestRootEntry_TreeExport(t *testing.T) { // add interface LeafVariant interf.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "Value"}, @@ -194,7 +195,7 @@ func TestRootEntry_TreeExport(t *testing.T) { ) // add interface LeafVariant interf.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "OtherValue"}, @@ -218,7 +219,7 @@ func TestRootEntry_TreeExport(t *testing.T) { // add interface LeafVariant interf.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "Value"}, @@ -285,7 +286,7 @@ func TestRootEntry_TreeExport(t *testing.T) { // add interface LeafVariant interf.leafVariants.Add( - NewLeafEntry( + api.NewLeafEntry( types.NewUpdate(nil, &sdcpb.TypedValue{ Value: &sdcpb.TypedValue_StringVal{StringVal: "Value"}, diff --git a/pkg/tree/sharedEntryAttributes.go b/pkg/tree/sharedEntryAttributes.go index 6f8e68bb..473211de 100644 --- a/pkg/tree/sharedEntryAttributes.go +++ b/pkg/tree/sharedEntryAttributes.go @@ -14,6 +14,7 @@ import ( "unicode/utf8" "github.com/sdcio/data-server/pkg/config" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" logf "github.com/sdcio/logger" @@ -29,7 +30,7 @@ var ( // sharedEntryAttributes contains the attributes shared by Entry and RootEntry type sharedEntryAttributes struct { // parent entry, nil for the root Entry - parent Entry + parent api.Entry // pathElemName the path elements name the entry represents pathElemName string // childs mutual exclusive with LeafVariants @@ -44,7 +45,7 @@ type sharedEntryAttributes struct { choicesResolvers choiceResolvers - treeContext *TreeContext + treeContext api.TreeContext // state cache cacheMutex sync.Mutex @@ -55,7 +56,7 @@ type sharedEntryAttributes struct { level *int } -func (s *sharedEntryAttributes) deepCopy(tc *TreeContext, parent Entry) (*sharedEntryAttributes, error) { +func (s *sharedEntryAttributes) deepCopy(tc api.TreeContext, parent api.Entry) (*sharedEntryAttributes, error) { result := &sharedEntryAttributes{ parent: parent, pathElemName: s.pathElemName, @@ -84,11 +85,11 @@ func (s *sharedEntryAttributes) deepCopy(tc *TreeContext, parent Entry) (*shared return result, nil } -func (s *sharedEntryAttributes) DeepCopy(tc *TreeContext, parent Entry) (Entry, error) { +func (s *sharedEntryAttributes) DeepCopy(tc api.TreeContext, parent api.Entry) (api.Entry, error) { return s.deepCopy(tc, parent) } -func newSharedEntryAttributes(ctx context.Context, parent Entry, pathElemName string, tc *TreeContext) (*sharedEntryAttributes, error) { +func newSharedEntryAttributes(ctx context.Context, parent api.Entry, pathElemName string, tc api.TreeContext) (*sharedEntryAttributes, error) { s := &sharedEntryAttributes{ parent: parent, pathElemName: pathElemName, @@ -115,14 +116,14 @@ func newSharedEntryAttributes(ctx context.Context, parent Entry, pathElemName st return s, nil } -func (s *sharedEntryAttributes) GetRoot() Entry { +func (s *sharedEntryAttributes) GetRoot() api.Entry { if s.IsRoot() { return s } return s.parent.GetRoot() } -func (s *sharedEntryAttributes) GetTreeContext() *TreeContext { +func (s *sharedEntryAttributes) GetTreeContext() api.TreeContext { return s.treeContext } @@ -230,7 +231,7 @@ func (s *sharedEntryAttributes) checkAndCreateKeysAsLeafs(ctx context.Context, i }) // iterate through the keys - var item Entry = s + var item api.Entry = s // construct the key path // doing so outside the loop to reuse @@ -243,7 +244,7 @@ func (s *sharedEntryAttributes) checkAndCreateKeysAsLeafs(ctx context.Context, i // if the key Leaf exists continue with next key if entryExists { // if it exists, we need to check that the entry for the owner exists. - var result []*LeafEntry + var result []*api.LeafEntry lvs := child.GetByOwner(intentName, result) if len(lvs) > 0 { lvs[0].RemoveDeleteFlag() @@ -314,7 +315,7 @@ func (s *sharedEntryAttributes) populateSchema(ctx context.Context) error { if getSchema { // trieve if the getSchema var is still true - schemaResp, err := s.treeContext.schemaClient.GetSchemaSdcpbPath(ctx, path) + schemaResp, err := s.GetTreeContext().GetSchemaClient().GetSchemaSdcpbPath(ctx, path) if err != nil { return err } @@ -334,13 +335,13 @@ func (s *sharedEntryAttributes) GetSchema() *sdcpb.SchemaElem { } // GetChildren returns the children Map of the Entry -func (s *sharedEntryAttributes) getChildren() map[string]Entry { +func (s *sharedEntryAttributes) getChildren() map[string]api.Entry { return s.childs.GetAll() } // getListChilds collects all the childs of the list. In the tree we store them seperated into their key branches. // this is collecting all the last level key entries. -func (s *sharedEntryAttributes) GetListChilds() ([]Entry, error) { +func (s *sharedEntryAttributes) GetListChilds() ([]api.Entry, error) { if s.schema == nil { return nil, fmt.Errorf("error GetListChilds() non schema level %s", s.SdcpbPath().ToXPath(false)) } @@ -351,8 +352,8 @@ func (s *sharedEntryAttributes) GetListChilds() ([]Entry, error) { if len(keys) == 0 { return nil, fmt.Errorf("error GetListChilds() not a List Container %s", s.SdcpbPath().ToXPath(false)) } - actualEntries := []Entry{s} - var newEntries []Entry + actualEntries := []api.Entry{s} + var newEntries []api.Entry for level := 0; level < len(keys); level++ { for _, e := range actualEntries { @@ -362,7 +363,7 @@ func (s *sharedEntryAttributes) GetListChilds() ([]Entry, error) { } } actualEntries = newEntries - newEntries = []Entry{} + newEntries = []api.Entry{} } return actualEntries, nil @@ -371,14 +372,14 @@ func (s *sharedEntryAttributes) GetListChilds() ([]Entry, error) { // FilterChilds returns the child entries (skipping the key entries in the tree) that // match the given keys. The keys do not need to match all levels of keys, in which case the // key level is considered a wildcard match (*) -func (s *sharedEntryAttributes) FilterChilds(keys map[string]string) ([]Entry, error) { +func (s *sharedEntryAttributes) FilterChilds(keys map[string]string) ([]api.Entry, error) { if s.schema == nil { return nil, fmt.Errorf("error non schema level %s", s.SdcpbPath().ToXPath(false)) } - result := []Entry{} + result := []api.Entry{} // init the processEntries with s - processEntries := []Entry{s} + processEntries := []api.Entry{s} // retrieve the schema keys schemaKeys := s.GetSchemaKeys() @@ -403,7 +404,7 @@ func (s *sharedEntryAttributes) FilterChilds(keys map[string]string) ([]Entry, e } } else { // this is basically the wildcard case, so go through all childs and add them - result = []Entry{} + result = []api.Entry{} for _, entry := range processEntries { childs := entry.GetChilds(types.DescendMethodAll) for _, v := range childs { @@ -419,7 +420,7 @@ func (s *sharedEntryAttributes) FilterChilds(keys map[string]string) ([]Entry, e } // GetParent returns the parent entry -func (s *sharedEntryAttributes) GetParent() Entry { +func (s *sharedEntryAttributes) GetParent() api.Entry { return s.parent } @@ -495,7 +496,7 @@ func (s *sharedEntryAttributes) getAggregatedDeletes(deletes []types.DeleteEntry for _, n := range keys { c, exists := s.childs.GetEntry(n) // these keys should aways exist, so for now we do not catch the non existing key case - if exists && !c.shouldDelete() { + if exists && !c.ShouldDelete() { // if not all the keys are marked for deletion, we need to revert to regular deletion doAggregateDelete = false break @@ -524,7 +525,7 @@ func (s *sharedEntryAttributes) getAggregatedDeletes(deletes []types.DeleteEntry // In caomparison to // - remainsToExists() returns true, because they remain to exist even though implicitly. // - shouldDelete() returns false, because no explicit delete should be issued for them. -func (s *sharedEntryAttributes) canDelete() bool { +func (s *sharedEntryAttributes) CanDelete() bool { s.cacheMutex.Lock() defer s.cacheMutex.Unlock() if s.cacheCanDelete != nil { @@ -539,7 +540,7 @@ func (s *sharedEntryAttributes) canDelete() bool { // handle containers for _, c := range s.GetChilds(types.DescendMethodActiveChilds) { - canDelete := c.canDelete() + canDelete := c.CanDelete() if !canDelete { s.cacheCanDelete = utils.BoolPtr(false) return *s.cacheCanDelete @@ -570,7 +571,7 @@ func (s *sharedEntryAttributes) CanDeleteBranch(keepDefault bool) bool { } // shouldDelete checks if a container or Leaf(List) is to be explicitly deleted. -func (s *sharedEntryAttributes) shouldDelete() bool { +func (s *sharedEntryAttributes) ShouldDelete() bool { // see if we have the value cached s.cacheMutex.Lock() defer s.cacheMutex.Unlock() @@ -595,7 +596,7 @@ func (s *sharedEntryAttributes) shouldDelete() bool { // iterate through the active childs for _, c := range activeChilds { // check if the child can be deleted - canDelete = c.canDelete() + canDelete = c.CanDelete() // if it can explicitly not be deleted, then the result is clear, we should not delete if !canDelete { break @@ -603,7 +604,7 @@ func (s *sharedEntryAttributes) shouldDelete() bool { // if it can be deleted we need to check if there is a contibuting entry that // requires deletion only if there is a contributing shouldDelete() == true then we must issue // a real delete - shouldDelete = shouldDelete || c.shouldDelete() + shouldDelete = shouldDelete || c.ShouldDelete() } // the overall result is @@ -650,7 +651,7 @@ func (s *sharedEntryAttributes) RemainsToExist() bool { func (s *sharedEntryAttributes) getRegularDeletes(deletes []types.DeleteEntry, aggregate bool) ([]types.DeleteEntry, error) { var err error - if s.shouldDelete() && !s.IsRoot() && len(s.GetSchemaKeys()) == 0 { + if s.ShouldDelete() && !s.IsRoot() && len(s.GetSchemaKeys()) == 0 { return append(deletes, s), nil } @@ -683,7 +684,7 @@ func (s *sharedEntryAttributes) GetDeletes(deletes []types.DeleteEntry, aggregat // GetAncestorSchema returns the schema of the parent node if the schema is set. // if the parent has no schema (is a key element in the tree) it will recurs the call to the parents parent. // the level of recursion is indicated via the levelUp attribute -func (s *sharedEntryAttributes) GetFirstAncestorWithSchema() (Entry, int) { +func (s *sharedEntryAttributes) GetFirstAncestorWithSchema() (api.Entry, int) { // if root node is reached if s.IsRoot() { return nil, 0 @@ -701,7 +702,7 @@ func (s *sharedEntryAttributes) GetFirstAncestorWithSchema() (Entry, int) { } // GetByOwner returns all the LeafEntries that belong to a certain owner. -func (s *sharedEntryAttributes) GetByOwner(owner string, result []*LeafEntry) LeafVariantSlice { +func (s *sharedEntryAttributes) GetByOwner(owner string, result []*api.LeafEntry) api.LeafVariantSlice { lv := s.leafVariants.GetByOwner(owner) if lv != nil { result = append(result, lv) @@ -725,7 +726,7 @@ func (s *sharedEntryAttributes) String() string { } // AddChild add an entry to the list of child entries for the entry. -func (s *sharedEntryAttributes) AddChild(ctx context.Context, e Entry) error { +func (s *sharedEntryAttributes) AddChild(ctx context.Context, e api.Entry) error { // make sure Entry should not only hold LeafEntries if s.leafVariants.Length() > 0 { // An exception are presence containers @@ -738,7 +739,7 @@ func (s *sharedEntryAttributes) AddChild(ctx context.Context, e Entry) error { return nil } -func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdcpb.Path) (Entry, error) { +func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdcpb.Path) (api.Entry, error) { pathElems := path.GetElem() var err error if len(pathElems) == 0 { @@ -753,7 +754,7 @@ func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdc case ".": s.NavigateSdcpbPath(ctx, path.CopyAndRemoveFirstPathElem()) case "..": - var entry Entry + var entry api.Entry entry = s.parent // we need to skip key levels in the tree // if the next path element is again .. we need to skip key values that are present in the tree @@ -790,8 +791,8 @@ func (s *sharedEntryAttributes) NavigateSdcpbPath(ctx context.Context, path *sdc return nil, fmt.Errorf("navigating tree, reached %v but child %v does not exist", s.SdcpbPath().ToXPath(false), pathElems) } -func (s *sharedEntryAttributes) tryLoadingDefault(ctx context.Context, path *sdcpb.Path) (Entry, error) { - schema, err := s.treeContext.schemaClient.GetSchemaSdcpbPath(ctx, path) +func (s *sharedEntryAttributes) tryLoadingDefault(ctx context.Context, path *sdcpb.Path) (api.Entry, error) { + schema, err := s.treeContext.GetSchemaClient().GetSchemaSdcpbPath(ctx, path) if err != nil { return nil, fmt.Errorf("error trying to load defaults for %s: %v", path.ToXPath(false), err) } @@ -812,7 +813,7 @@ func (s *sharedEntryAttributes) tryLoadingDefault(ctx context.Context, path *sdc } func (s *sharedEntryAttributes) DeleteBranch(ctx context.Context, path *sdcpb.Path, owner string) error { - var entry Entry + var entry api.Entry var err error if path == nil { @@ -883,7 +884,7 @@ func (s *sharedEntryAttributes) deleteBranchInternal(ctx context.Context, owner // GetHighestPrecedence goes through the whole branch and returns the new and updated cache.Updates. // These are the updated that will be send to the device. -func (s *sharedEntryAttributes) GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) LeafVariantSlice { +func (s *sharedEntryAttributes) GetHighestPrecedence(result api.LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) api.LeafVariantSlice { // get the highes precedence LeafeVariant and add it to the list lv := s.leafVariants.GetHighestPrecedence(onlyNewOrUpdated, includeDefaults, includeExplicitDelete) if lv != nil { @@ -897,7 +898,7 @@ func (s *sharedEntryAttributes) GetHighestPrecedence(result LeafVariantSlice, on return result } -func (s *sharedEntryAttributes) getHighestPrecedenceLeafValue(ctx context.Context) (*LeafEntry, error) { +func (s *sharedEntryAttributes) GetHighestPrecedenceLeafValue(ctx context.Context) (*api.LeafEntry, error) { for _, x := range []string{"existing", "default"} { lv := s.leafVariants.GetHighestPrecedence(false, true, false) if lv != nil { @@ -913,10 +914,10 @@ func (s *sharedEntryAttributes) getHighestPrecedenceLeafValue(ctx context.Contex return nil, fmt.Errorf("error no value present for %s", s.SdcpbPath().ToXPath(false)) } -func (s *sharedEntryAttributes) GetRootBasedEntryChain() []Entry { +func (s *sharedEntryAttributes) GetRootBasedEntryChain() []api.Entry { // Build the chain from root to this entry without recursion - var chain []Entry - var current Entry = s + var chain []api.Entry + var current api.Entry = s for current != nil && !current.IsRoot() { chain = append(chain, current) current = current.GetParent() @@ -930,24 +931,12 @@ func (s *sharedEntryAttributes) GetRootBasedEntryChain() []Entry { return chain } -type HighestPrecedenceFilter func(le *LeafEntry) bool - -func HighestPrecedenceFilterAll(le *LeafEntry) bool { - return true -} -func HighestPrecedenceFilterWithoutNew(le *LeafEntry) bool { - return !le.IsNew -} -func HighestPrecedenceFilterWithoutDeleted(le *LeafEntry) bool { - return !le.Delete -} - // getHighestPrecedenceValueOfBranch goes through all the child branches to find the highest // precedence value (lowest priority value) for the entire branch and returns it. -func (s *sharedEntryAttributes) getHighestPrecedenceValueOfBranch(filter HighestPrecedenceFilter) int32 { +func (s *sharedEntryAttributes) GetHighestPrecedenceValueOfBranch(filter api.HighestPrecedenceFilter) int32 { result := int32(math.MaxInt32) for _, e := range s.childs.GetAll() { - if val := e.getHighestPrecedenceValueOfBranch(filter); val < result { + if val := e.GetHighestPrecedenceValueOfBranch(filter); val < result { result = val } } @@ -965,35 +954,35 @@ func (s *sharedEntryAttributes) ValidateLevel(ctx context.Context, resultChan ch if s.RemainsToExist() { // TODO: Validate Enums if !vCfg.DisabledValidators.Mandatory { - s.validateMandatory(ctx, resultChan, stats) + s.ValidateMandatory(ctx, resultChan, stats) } if !vCfg.DisabledValidators.Leafref { - s.validateLeafRefs(ctx, resultChan, stats) + s.ValidateLeafRefs(ctx, resultChan, stats) } if !vCfg.DisabledValidators.LeafrefMinMaxAttributes { - s.validateLeafListMinMaxAttributes(resultChan, stats) + s.ValidateLeafListMinMaxAttributes(resultChan, stats) } if !vCfg.DisabledValidators.Pattern { - s.validatePattern(resultChan, stats) + s.ValidatePattern(resultChan, stats) } if !vCfg.DisabledValidators.MustStatement { - s.validateMustStatements(ctx, resultChan, stats) + s.ValidateMustStatements(ctx, resultChan, stats) } if !vCfg.DisabledValidators.Length { - s.validateLength(resultChan, stats) + s.ValidateLength(resultChan, stats) } if !vCfg.DisabledValidators.Range { - s.validateRange(resultChan, stats) + s.ValidateRange(resultChan, stats) } if !vCfg.DisabledValidators.MaxElements { - s.validateMinMaxElements(resultChan, stats) + s.ValidateMinMaxElements(resultChan, stats) } } } // validateRange int and uint types (Leaf and Leaflist) define ranges which configured values must lay in. // validateRange does check this condition. -func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateRange(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { // if no schema present or Field and LeafList Types do not contain any ranges, return there is nothing to check if s.GetSchema() == nil || (len(s.GetSchema().GetField().GetType().GetRange()) == 0 && len(s.GetSchema().GetLeaflist().GetType().GetRange()) == 0) { @@ -1070,7 +1059,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio } } -func (s *sharedEntryAttributes) validateMinMaxElements(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateMinMaxElements(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { var contSchema *sdcpb.ContainerSchema if contSchema = s.GetSchema().GetContainer(); contSchema == nil { // if it is not a container, return @@ -1129,7 +1118,7 @@ func (s *sharedEntryAttributes) validateMinMaxElements(resultChan chan<- *types. } // validateLeafListMinMaxAttributes validates the Min-, and Max-Elements attribute of the Entry if it is a Leaflists. -func (s *sharedEntryAttributes) validateLeafListMinMaxAttributes(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateLeafListMinMaxAttributes(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { if schema := s.schema.GetLeaflist(); schema != nil { if schema.GetMinElements() > 0 || schema.GetMaxElements() < math.MaxUint64 { if lv := s.leafVariants.GetHighestPrecedence(false, true, false); lv != nil { @@ -1151,7 +1140,7 @@ func (s *sharedEntryAttributes) validateLeafListMinMaxAttributes(resultChan chan } } -func (s *sharedEntryAttributes) validateLength(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateLength(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { if schema := s.schema.GetField(); schema != nil { if len(schema.GetType().GetLength()) == 0 { @@ -1182,7 +1171,7 @@ func (s *sharedEntryAttributes) validateLength(resultChan chan<- *types.Validati } } -func (s *sharedEntryAttributes) validatePattern(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidatePattern(resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { if schema := s.schema.GetField(); schema != nil { if len(schema.Type.Patterns) == 0 { return @@ -1212,7 +1201,7 @@ func (s *sharedEntryAttributes) validatePattern(resultChan chan<- *types.Validat // validateMandatory validates that all the mandatory attributes, // defined by the schema are present either in the tree or in the index. -func (s *sharedEntryAttributes) validateMandatory(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateMandatory(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { log := logf.FromContext(ctx) if !s.RemainsToExist() { return @@ -1256,7 +1245,7 @@ func (s *sharedEntryAttributes) validateMandatory(ctx context.Context, resultCha log.Error(ValidationError, "mandatory attribute could not be found as child, field or choice", "path", s.SdcpbPath().ToXPath(false), "attribute", c.Name) } - s.validateMandatoryWithKeys(ctx, len(containerSchema.GetKeys()), attributes, choiceName, resultChan) + s.ValidateMandatoryWithKeys(ctx, len(s.GetSchema().GetContainer().GetKeys()), attributes, choiceName, resultChan) } stats.Add(types.StatTypeMandatory, uint32(len(containerSchema.GetMandatoryChildrenConfig()))) } @@ -1266,14 +1255,14 @@ func (s *sharedEntryAttributes) validateMandatory(ctx context.Context, resultCha // validateMandatoryWithKeys steps down the tree, passing the key levels and checking the existence of the mandatory. // attributes is a string slice, it will be checked that at least of the the given attributes is defined // !Not checking all of these are defined (call multiple times with single entry in attributes for that matter)! -func (s *sharedEntryAttributes) validateMandatoryWithKeys(ctx context.Context, level int, attributes []string, choiceName string, resultChan chan<- *types.ValidationResultEntry) { - if s.shouldDelete() { +func (s *sharedEntryAttributes) ValidateMandatoryWithKeys(ctx context.Context, level int, attributes []string, choiceName string, resultChan chan<- *types.ValidationResultEntry) { + if s.ShouldDelete() { return } if level == 0 { success := false existsInTree := false - var v Entry + var v api.Entry // iterate over the attributes make sure any of these exists for _, attr := range attributes { // first check if the mandatory value is set via the intent, e.g. part of the tree already @@ -1301,7 +1290,7 @@ func (s *sharedEntryAttributes) validateMandatoryWithKeys(ctx context.Context, l } for _, c := range s.GetChilds(types.DescendMethodActiveChilds) { - c.validateMandatoryWithKeys(ctx, level-1, attributes, choiceName, resultChan) + c.ValidateMandatoryWithKeys(ctx, level-1, attributes, choiceName, resultChan) } } @@ -1391,19 +1380,19 @@ func (s *sharedEntryAttributes) populateChoiceCaseResolvers(_ context.Context) e child, childExists := s.childs.GetEntry(elem) // set the value from the tree as well if childExists { - valWDeleted := child.getHighestPrecedenceValueOfBranch(HighestPrecedenceFilterAll) + valWDeleted := child.GetHighestPrecedenceValueOfBranch(api.HighestPrecedenceFilterAll) if valWDeleted <= highestWDeleted { highestWDeleted = valWDeleted - if child.canDelete() { + if child.CanDelete() { isDeleted = true } } - valWODeleted := child.getHighestPrecedenceValueOfBranch(HighestPrecedenceFilterWithoutDeleted) + valWODeleted := child.GetHighestPrecedenceValueOfBranch(api.HighestPrecedenceFilterWithoutDeleted) if valWODeleted <= highestWODeleted { highestWODeleted = valWODeleted } - valWONew := child.getHighestPrecedenceValueOfBranch(HighestPrecedenceFilterWithoutNew) + valWONew := child.GetHighestPrecedenceValueOfBranch(api.HighestPrecedenceFilterWithoutNew) if valWONew <= highestWONew { highestWONew = valWONew } @@ -1415,11 +1404,11 @@ func (s *sharedEntryAttributes) populateChoiceCaseResolvers(_ context.Context) e return nil } -func (s *sharedEntryAttributes) GetChild(name string) (Entry, bool) { +func (s *sharedEntryAttributes) GetChild(name string) (api.Entry, bool) { return s.childs.GetEntry(name) } -func (s *sharedEntryAttributes) GetChilds(d types.DescendMethod) EntryMap { +func (s *sharedEntryAttributes) GetChilds(d types.DescendMethod) api.EntryMap { if s.schema == nil { return s.childs.GetAll() } @@ -1434,7 +1423,7 @@ func (s *sharedEntryAttributes) GetChilds(d types.DescendMethod) EntryMap { if len(skipAttributesList) == 0 { return s.childs.GetAll() } - result := map[string]Entry{} + result := map[string]api.Entry{} // optimization option: sort the slices and forward in parallel, lifts extra burden that the contains call holds. for childName, child := range s.childs.GetAll() { if slices.Contains(skipAttributesList, childName) { @@ -1561,12 +1550,12 @@ func (s *sharedEntryAttributes) TreeExport(owner string) ([]*tree_persist.TreeEl return nil, nil } -func (s *sharedEntryAttributes) getOrCreateChilds(ctx context.Context, path *sdcpb.Path) (Entry, error) { +func (s *sharedEntryAttributes) GetOrCreateChilds(ctx context.Context, path *sdcpb.Path) (api.Entry, error) { if path == nil || len(path.Elem) == 0 { return s, nil } - var current Entry = s + var current api.Entry = s for i, pe := range path.Elem { // Step 1: Find or create the child for the path element name newCurrent, exists := current.GetChilds(types.DescendMethodAll)[pe.Name] @@ -1618,7 +1607,7 @@ func (s *sharedEntryAttributes) getOrCreateChilds(ctx context.Context, path *sdc // AddUpdateRecursive recursively adds the given cache.Update to the tree. Thereby creating all the entries along the path. // if the entries along th path already exist, the existing entries are called to add the Update. -func (s *sharedEntryAttributes) AddUpdateRecursive(ctx context.Context, path *sdcpb.Path, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) { +func (s *sharedEntryAttributes) AddUpdateRecursive(ctx context.Context, path *sdcpb.Path, u *types.Update, flags *types.UpdateInsertFlags) (api.Entry, error) { var err error relPath := path @@ -1629,9 +1618,9 @@ func (s *sharedEntryAttributes) AddUpdateRecursive(ctx context.Context, path *sd return nil, err } } - return s.addUpdateRecursiveInternal(ctx, relPath, 0, u, flags) + return s.AddUpdateRecursiveInternal(ctx, relPath, 0, u, flags) } -func (s *sharedEntryAttributes) addUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (Entry, error) { +func (s *sharedEntryAttributes) AddUpdateRecursiveInternal(ctx context.Context, path *sdcpb.Path, idx int, u *types.Update, flags *types.UpdateInsertFlags) (api.Entry, error) { // make sure all the keys are also present as leafs err := s.checkAndCreateKeysAsLeafs(ctx, u.Owner(), u.Priority(), flags) @@ -1642,12 +1631,12 @@ func (s *sharedEntryAttributes) addUpdateRecursiveInternal(ctx context.Context, // continue with recursive add otherwise if path == nil || len(path.GetElem()) == 0 || idx >= len(path.GetElem()) { // delegate update handling to leafVariants - s.leafVariants.Add(NewLeafEntry(u, flags, s)) + s.leafVariants.Add(api.NewLeafEntry(u, flags, s)) return s, nil } - var e Entry - var x Entry = s + var e api.Entry + var x api.Entry = s var exists bool for name := range path.GetElem()[idx].PathElemNames() { if e, exists = x.GetChilds(types.DescendMethodAll)[name]; !exists { @@ -1664,7 +1653,7 @@ func (s *sharedEntryAttributes) addUpdateRecursiveInternal(ctx context.Context, x = e } - return x.addUpdateRecursiveInternal(ctx, path, idx+1, u, flags) + return x.AddUpdateRecursiveInternal(ctx, path, idx+1, u, flags) } // containsOnlyDefaults checks for presence containers, if only default values are present, @@ -1690,7 +1679,7 @@ func (s *sharedEntryAttributes) containsOnlyDefaults() bool { return false } // check if the value is the default value - le, err := v.getHighestPrecedenceLeafValue(context.TODO()) + le, err := v.GetHighestPrecedenceLeafValue(context.TODO()) if err != nil { return false } @@ -1703,6 +1692,6 @@ func (s *sharedEntryAttributes) containsOnlyDefaults() bool { return true } -func (s *sharedEntryAttributes) GetLeafVariantEntries() LeafVariantEntries { +func (s *sharedEntryAttributes) GetLeafVariantEntries() api.LeafVariantEntries { return s.leafVariants } diff --git a/pkg/tree/sharedEntryAttributes_test.go b/pkg/tree/sharedEntryAttributes_test.go index d2f22349..5fe489e8 100644 --- a/pkg/tree/sharedEntryAttributes_test.go +++ b/pkg/tree/sharedEntryAttributes_test.go @@ -15,6 +15,7 @@ import ( "github.com/sdcio/data-server/pkg/config" schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" jsonImporter "github.com/sdcio/data-server/pkg/tree/importer/json" "github.com/sdcio/data-server/pkg/tree/importer/proto" "github.com/sdcio/data-server/pkg/tree/types" @@ -288,7 +289,7 @@ func Test_sharedEntryAttributes_DeleteSubtree(t *testing.T) { t.Error(err) return } - les := []*LeafEntry{} + les := []*api.LeafEntry{} result := e.GetByOwner(tt.args.owner, les) if len(result) > 0 { t.Errorf("expected all elements under %s to be deleted for owner %s but got %d elements", tt.args.relativePath.ToXPath(false), tt.args.owner, len(result)) @@ -873,7 +874,7 @@ func Test_sharedEntryAttributes_getOrCreateChilds(t *testing.T) { t.Fatal(err) } - x, err := root.getOrCreateChilds(ctx, tt.path) + x, err := root.GetOrCreateChilds(ctx, tt.path) if (err != nil) != tt.wantErr { t.Errorf("sharedEntryAttributes.getOrCreateChilds() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/pkg/tree/sorter.go b/pkg/tree/sorter.go index 54a6433d..06fc9fde 100644 --- a/pkg/tree/sorter.go +++ b/pkg/tree/sorter.go @@ -1,10 +1,13 @@ package tree -import "github.com/sdcio/data-server/pkg/tree/types" +import ( + "github.com/sdcio/data-server/pkg/tree/api" + "github.com/sdcio/data-server/pkg/tree/types" +) -func getListEntrySortFunc(parent Entry) func(a, b Entry) int { +func getListEntrySortFunc(parent api.Entry) func(a, b api.Entry) int { // return the comparison function - return func(a, b Entry) int { + return func(a, b api.Entry) int { keys := parent.GetSchemaKeys() var cmpResult int for _, v := range keys { @@ -16,8 +19,8 @@ func getListEntrySortFunc(parent Entry) func(a, b Entry) int { if !exists { return 0 } - aLvSlice := achild.GetHighestPrecedence(LeafVariantSlice{}, false, true, true) - bLvSlice := bchild.GetHighestPrecedence(LeafVariantSlice{}, false, true, true) + aLvSlice := achild.GetHighestPrecedence(api.LeafVariantSlice{}, false, true, true) + bLvSlice := bchild.GetHighestPrecedence(api.LeafVariantSlice{}, false, true, true) aEntry := aLvSlice[0] bEntry := bLvSlice[0] diff --git a/pkg/tree/tree_context.go b/pkg/tree/tree_context.go index 9da8ab59..72cb3c9e 100644 --- a/pkg/tree/tree_context.go +++ b/pkg/tree/tree_context.go @@ -5,15 +5,16 @@ import ( schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" "github.com/sdcio/data-server/pkg/pool" + "github.com/sdcio/data-server/pkg/tree/api" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) type TreeContext struct { - root Entry // the trees root element + root api.Entry // the trees root element schemaClient schemaClient.SchemaClientBound actualOwner string nonRevertiveInfo map[string]bool - explicitDeletes *DeletePathSet + explicitDeletes *api.DeletePathSet poolFactory pool.VirtualPoolFactory } @@ -22,13 +23,13 @@ func NewTreeContext(sc schemaClient.SchemaClientBound, actualOwner string, poolF schemaClient: sc, actualOwner: actualOwner, nonRevertiveInfo: map[string]bool{}, - explicitDeletes: NewDeletePaths(), + explicitDeletes: api.NewDeletePaths(), poolFactory: poolFactory, } } -// deepCopy root is required to be set manually -func (t *TreeContext) deepCopy() *TreeContext { +// DeepCopy root is required to be set manually +func (t *TreeContext) DeepCopy() api.TreeContext { tc := &TreeContext{ schemaClient: t.schemaClient, poolFactory: t.poolFactory, @@ -56,16 +57,24 @@ func (t *TreeContext) RemoveExplicitDeletes(intentName string) *sdcpb.PathSet { return t.explicitDeletes.RemoveIntentDeletes(intentName) } +func (t *TreeContext) GetExplicitDeletes() *api.DeletePathSet { + return t.explicitDeletes +} + func (t *TreeContext) AddNonRevertiveInfo(intent string, nonRevertive bool) { t.nonRevertiveInfo[intent] = nonRevertive } +func (t *TreeContext) GetNonRevertiveInfo(intent string) bool { + return t.nonRevertiveInfo[intent] +} + // IsNonRevertiveIntent returns the non-revertive flag per intent. False is also returned the intent does not exist. func (t *TreeContext) IsNonRevertiveIntent(intent string) bool { return t.nonRevertiveInfo[intent] } -func (t *TreeContext) SetRoot(e Entry) error { +func (t *TreeContext) SetRoot(e api.Entry) error { if t.root != nil { return fmt.Errorf("trying to set treecontexts root, although it is already set") } @@ -80,3 +89,7 @@ func (t *TreeContext) GetActualOwner() string { func (t *TreeContext) SetActualOwner(owner string) { t.actualOwner = owner } + +func (t *TreeContext) GetSchemaClient() schemaClient.SchemaClientBound { + return t.schemaClient +} diff --git a/pkg/tree/validation_entry_leafref.go b/pkg/tree/validation_entry_leafref.go index 25a63c91..664bc497 100644 --- a/pkg/tree/validation_entry_leafref.go +++ b/pkg/tree/validation_entry_leafref.go @@ -5,23 +5,24 @@ import ( "fmt" "strings" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) -func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sdcpb.Path) ([]Entry, error) { +func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sdcpb.Path) ([]api.Entry, error) { var err error - var resultEntries []Entry - var processEntries []Entry + var resultEntries []api.Entry + var processEntries []api.Entry sdcpbPath.StripPathElemPrefixPath() lrefPath := types.NewLrefPath(sdcpbPath) if sdcpbPath.GetIsRootBased() { - processEntries = []Entry{s.GetRoot()} + processEntries = []api.Entry{s.GetRoot()} } else { - var entry Entry = s + var entry api.Entry = s dotdotcount := 0 sdcpbUp := []*sdcpb.PathElem{} // process the .. instructions @@ -39,7 +40,7 @@ func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sd if err != nil { return nil, err } - processEntries = []Entry{entry} + processEntries = []api.Entry{entry} lrefPath = lrefPath[dotdotcount:] } @@ -47,7 +48,7 @@ func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sd // forward the path by a single element for _, elem := range lrefPath { - resultEntries = []Entry{} + resultEntries = []api.Entry{} err := s.resolve_leafref_key_path(ctx, elem.Keys) if err != nil { return nil, err @@ -70,7 +71,7 @@ func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sd resultEntries = append(resultEntries, entry) continue } - var childs []Entry + var childs []api.Entry // if the entry is a list with keys, try filtering the entries based on the keys if len(entry.GetSchemaKeys()) > 0 { // filter the keys @@ -92,7 +93,7 @@ func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, sdcpbPath *sd } // NavigateLeafRef -func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]Entry, error) { +func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]api.Entry, error) { // leafref path takes as an argument a string that MUST refer to a leaf or leaf-list node. // e.g. @@ -133,10 +134,10 @@ func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]Entry, e return nil, err } - var resultEntries []Entry + var resultEntries []api.Entry for _, e := range foundEntries { - r, err := e.getHighestPrecedenceLeafValue(ctx) + r, err := e.GetHighestPrecedenceLeafValue(ctx) if err != nil { return nil, err } @@ -188,7 +189,7 @@ func (s *sharedEntryAttributes) resolve_leafref_key_path(ctx context.Context, ke return err } - lvs := keyValue.GetHighestPrecedence(LeafVariantSlice{}, false, false, false) + lvs := keyValue.GetHighestPrecedence(api.LeafVariantSlice{}, false, false, false) if lvs == nil { return fmt.Errorf("no leafentry found") } @@ -199,8 +200,8 @@ func (s *sharedEntryAttributes) resolve_leafref_key_path(ctx context.Context, ke return nil } -func (s *sharedEntryAttributes) validateLeafRefs(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { - if s.shouldDelete() { +func (s *sharedEntryAttributes) ValidateLeafRefs(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { + if s.ShouldDelete() { return } @@ -230,7 +231,7 @@ func (s *sharedEntryAttributes) validateLeafRefs(ctx context.Context, resultChan } // Only if the value remains, even after the SetIntent made it through, the LeafRef can be considered resolved. - if entry[0].shouldDelete() { + if entry[0].ShouldDelete() { lv := s.leafVariants.GetHighestPrecedence(false, true, false) if lv == nil { return @@ -248,8 +249,8 @@ func (s *sharedEntryAttributes) validateLeafRefs(ctx context.Context, resultChan stats.Add(types.StatTypeLeafRef, 1) } -func generateOptionalWarning(ctx context.Context, s Entry, lref string, resultChan chan<- *types.ValidationResultEntry) { - lrefval, err := s.getHighestPrecedenceLeafValue(ctx) +func generateOptionalWarning(ctx context.Context, s api.Entry, lref string, resultChan chan<- *types.ValidationResultEntry) { + lrefval, err := s.GetHighestPrecedenceLeafValue(ctx) if err != nil { resultChan <- types.NewValidationResultEntry(lrefval.Owner(), err, types.ValidationResultEntryTypeError) return diff --git a/pkg/tree/validation_entry_leafref_test.go b/pkg/tree/validation_entry_leafref_test.go index 5c8fc947..0e8079eb 100644 --- a/pkg/tree/validation_entry_leafref_test.go +++ b/pkg/tree/validation_entry_leafref_test.go @@ -268,7 +268,7 @@ func Test_sharedEntryAttributes_validateLeafRefs(t *testing.T) { resultChan := make(chan<- *types.ValidationResultEntry, 20) stats := types.NewValidationStats() - s.validateLeafRefs(ctx, resultChan, stats) + s.ValidateLeafRefs(ctx, resultChan, stats) if len(resultChan) != tt.expectedResultLen { t.Fatalf("expected %d, got %d errors on leafref validation", tt.expectedResultLen, len(resultChan)) diff --git a/pkg/tree/validation_entry_must.go b/pkg/tree/validation_entry_must.go index 17c83568..c13af77a 100644 --- a/pkg/tree/validation_entry_must.go +++ b/pkg/tree/validation_entry_must.go @@ -12,7 +12,7 @@ import ( "github.com/sdcio/yang-parser/xpath/grammars/expr" ) -func (s *sharedEntryAttributes) validateMustStatements(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { +func (s *sharedEntryAttributes) ValidateMustStatements(ctx context.Context, resultChan chan<- *types.ValidationResultEntry, stats *types.ValidationStats) { log := logf.FromContext(ctx) // if no schema, then there is nothing to be done, return diff --git a/pkg/tree/xml.go b/pkg/tree/xml.go index e568a8b8..d3f359c0 100644 --- a/pkg/tree/xml.go +++ b/pkg/tree/xml.go @@ -7,6 +7,7 @@ import ( "sort" "github.com/beevik/etree" + "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" sdcpb "github.com/sdcio/sdc-protos/sdcpb" @@ -18,19 +19,19 @@ import ( // If useOperationRemove is set, the remove operation will be used for deletes, instead of the delete operation. func (s *sharedEntryAttributes) ToXML(onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove bool) (*etree.Document, error) { doc := etree.NewDocument() - _, err := s.toXmlInternal(&doc.Element, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) + _, err := s.ToXmlInternal(&doc.Element, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) if err != nil { return nil, err } return doc, nil } -func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (doAdd bool, err error) { +func (s *sharedEntryAttributes) ToXmlInternal(parent *etree.Element, onlyNewOrUpdated bool, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) (doAdd bool, err error) { switch s.schema.GetSchema().(type) { case nil: // This case represents a key level element. So no schema present. all child attributes need to be adedd directly to the parent element, since the key levels are not visible in the resulting xml. - if s.shouldDelete() { + if s.ShouldDelete() { // If the element is to be deleted // add the delete operation to the parent element utils.AddXMLOperation(parent, utils.XMLOperationDelete, operationWithNamespace, useOperationRemove) @@ -76,7 +77,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp for _, k := range keys { // recurse the call // no additional element is created, since we're on a key level, so add to parent element - doAdd, err := childs[k].toXmlInternal(parent, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) + doAdd, err := childs[k].ToXmlInternal(parent, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) if err != nil { return false, err } @@ -107,7 +108,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp // process the honorNamespace instruction xmlAddNamespaceConditional(s, s.parent, newElem, honorNamespace) // recurse the call - doAdd, err := child.toXmlInternal(newElem, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) + doAdd, err := child.ToXmlInternal(newElem, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) if err != nil { return false, err } @@ -130,7 +131,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp } } return overallDoAdd, nil - case s.shouldDelete(): + case s.ShouldDelete(): // s is meant to be removed // if delete, create the element as child of parent newElem := parent.CreateElement(s.pathElemName) @@ -191,7 +192,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp return false, fmt.Errorf("child %s does not exist for %s", k, s.SdcpbPath().ToXPath(false)) } // TODO: Do we also need to xmlAddAllChildValues here too? - doAdd, err := child.toXmlInternal(newElem, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) + doAdd, err := child.ToXmlInternal(newElem, onlyNewOrUpdated, honorNamespace, operationWithNamespace, useOperationRemove) if err != nil { return false, err } @@ -210,7 +211,7 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp case *sdcpb.SchemaElem_Leaflist, *sdcpb.SchemaElem_Field: // check if the element remains to exist - if s.shouldDelete() { + if s.ShouldDelete() { // if not, add the remove / delete op utils.AddXMLOperation(parent.CreateElement(s.pathElemName), utils.XMLOperationDelete, operationWithNamespace, useOperationRemove) // see case nil for an explanation of this, it is basically the same @@ -239,10 +240,10 @@ func (s *sharedEntryAttributes) toXmlInternal(parent *etree.Element, onlyNewOrUp // namespaceIsEqual takes the two given Entries, gets the namespace // and reports if both belong to the same namespace -func namespaceIsEqual(a Entry, b Entry) bool { +func namespaceIsEqual(a api.Entry, b api.Entry) bool { // store for the calculated namespaces namespaces := make([]string, 0, 2) - for _, e := range []Entry{a, b} { + for _, e := range []api.Entry{a, b} { // get schemas for a and b schema := e.GetSchema() @@ -261,7 +262,7 @@ func namespaceIsEqual(a Entry, b Entry) bool { } // xmlAddNamespaceConditional adds the namespace of a to elem if namespaces of a and b are different -func xmlAddNamespaceConditional(a Entry, b Entry, elem *etree.Element, honorNamespace bool) { +func xmlAddNamespaceConditional(a api.Entry, b api.Entry, elem *etree.Element, honorNamespace bool) { if honorNamespace && (b == nil || !namespaceIsEqual(a, b)) { elem.CreateAttr("xmlns", utils.GetNamespaceFromGetSchema(a.GetSchema())) } @@ -269,7 +270,7 @@ func xmlAddNamespaceConditional(a Entry, b Entry, elem *etree.Element, honorName // xmlAddKeyElements determines the keys of a certain Entry in the tree and adds those to the // element if they do not already exist. -func xmlAddKeyElements(s Entry, parent *etree.Element) { +func xmlAddKeyElements(s api.Entry, parent *etree.Element) { // retrieve the parent schema, we need to extract the key names // values are the tree level names parentSchema, levelsUp := s.GetFirstAncestorWithSchema() @@ -279,7 +280,7 @@ func xmlAddKeyElements(s Entry, parent *etree.Element) { //issue #364: sort the slice sort.Strings(schemaKeys) - var treeElem Entry = s + var treeElem api.Entry = s // the keys do match the levels up in the tree in reverse order // hence we init i with levelUp and count down for i := levelsUp - 1; i >= 0; i-- { @@ -295,9 +296,9 @@ func xmlAddKeyElements(s Entry, parent *etree.Element) { } } -func xmlAddAllChildValues(s Entry, parent *etree.Element, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) error { +func xmlAddAllChildValues(s api.Entry, parent *etree.Element, honorNamespace bool, operationWithNamespace bool, useOperationRemove bool) error { parent.Child = make([]etree.Token, 0) - _, err := s.toXmlInternal(parent, false, honorNamespace, operationWithNamespace, useOperationRemove) + _, err := s.ToXmlInternal(parent, false, honorNamespace, operationWithNamespace, useOperationRemove) if err != nil { return err } diff --git a/pkg/tree/yang-parser-adapter.go b/pkg/tree/yang-parser-adapter.go index 3268d37c..aa4d78f3 100644 --- a/pkg/tree/yang-parser-adapter.go +++ b/pkg/tree/yang-parser-adapter.go @@ -4,17 +4,18 @@ import ( "context" "fmt" + "github.com/sdcio/data-server/pkg/tree/api" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "github.com/sdcio/yang-parser/xpath" "github.com/sdcio/yang-parser/xpath/xutils" ) type yangParserEntryAdapter struct { - e Entry + e api.Entry ctx context.Context } -func newYangParserEntryAdapter(ctx context.Context, e Entry) *yangParserEntryAdapter { +func newYangParserEntryAdapter(ctx context.Context, e api.Entry) *yangParserEntryAdapter { return &yangParserEntryAdapter{ e: e, ctx: ctx, @@ -73,7 +74,7 @@ func (y *yangParserEntryAdapter) GetValue() (xpath.Datum, error) { } // if y.e is anything else then a container - lv, _ := y.e.getHighestPrecedenceLeafValue(y.ctx) + lv, _ := y.e.GetHighestPrecedenceLeafValue(y.ctx) if lv == nil { return xpath.NewNodesetDatum([]xutils.XpathNode{}), nil } From 8a755ecfea277cfba06e9153db110db7612fae52 Mon Sep 17 00:00:00 2001 From: steiler Date: Tue, 3 Feb 2026 16:02:52 +0100 Subject: [PATCH 6/6] update --- pkg/tree/{ => processors/importer}/processor_importer.go | 6 +++--- pkg/tree/root_entry.go | 3 ++- pkg/tree/root_entry_test.go | 3 ++- pkg/tree/utils.go | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) rename pkg/tree/{ => processors/importer}/processor_importer.go (97%) diff --git a/pkg/tree/processor_importer.go b/pkg/tree/processors/importer/processor_importer.go similarity index 97% rename from pkg/tree/processor_importer.go rename to pkg/tree/processors/importer/processor_importer.go index 3ca7b6ea..1e5f545c 100644 --- a/pkg/tree/processor_importer.go +++ b/pkg/tree/processors/importer/processor_importer.go @@ -1,4 +1,4 @@ -package tree +package importer import ( "context" @@ -125,7 +125,7 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err return err } if keyChild, exists = actual.GetChild(kv); !exists { - keyChild, err = NewEntry(ctx, actual, kv, task.params.treeContext) + keyChild, err = actual.GetOrCreateChilds(ctx, &sdcpb.Path{Elem: []*sdcpb.PathElem{{Name: kv}}}) if err != nil { return err } @@ -154,7 +154,7 @@ func (task importConfigTask) Run(ctx context.Context, submit func(pool.Task) err child, exists := task.entry.GetChild(childElt.GetName()) if !exists { var err error - child, err = NewEntry(ctx, task.entry, childElt.GetName(), task.params.treeContext) + child, err = task.entry.GetOrCreateChilds(ctx, &sdcpb.Path{Elem: []*sdcpb.PathElem{{Name: childElt.GetName()}}}) if err != nil { return fmt.Errorf("error inserting %s at %s: %w", childElt.GetName(), task.entry.SdcpbPath().ToXPath(false), err) } diff --git a/pkg/tree/root_entry.go b/pkg/tree/root_entry.go index 18e4e62b..f9d44650 100644 --- a/pkg/tree/root_entry.go +++ b/pkg/tree/root_entry.go @@ -11,6 +11,7 @@ import ( "github.com/sdcio/data-server/pkg/pool" "github.com/sdcio/data-server/pkg/tree/api" "github.com/sdcio/data-server/pkg/tree/importer" + procImporter "github.com/sdcio/data-server/pkg/tree/processors/importer" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils" logf "github.com/sdcio/logger" @@ -87,7 +88,7 @@ func (r *RootEntry) ImportConfig(ctx context.Context, basePath *sdcpb.Path, impo if err != nil { return nil, err } - ImportConfigProcessor := NewImportConfigProcessor(importer, flags) + ImportConfigProcessor := procImporter.NewImportConfigProcessor(importer, flags) err = ImportConfigProcessor.Run(ctx, e, poolFactory) if err != nil { return nil, err diff --git a/pkg/tree/root_entry_test.go b/pkg/tree/root_entry_test.go index 9fcb1f4e..2a91d3d0 100644 --- a/pkg/tree/root_entry_test.go +++ b/pkg/tree/root_entry_test.go @@ -14,6 +14,7 @@ import ( "github.com/sdcio/data-server/pkg/pool" "github.com/sdcio/data-server/pkg/tree/api" jsonImporter "github.com/sdcio/data-server/pkg/tree/importer/json" + procImporter "github.com/sdcio/data-server/pkg/tree/processors/importer" "github.com/sdcio/data-server/pkg/tree/types" "github.com/sdcio/data-server/pkg/utils/testhelper" sdcio_schema "github.com/sdcio/data-server/tests/sdcioygot" @@ -523,7 +524,7 @@ func TestRootEntry_AddUpdatesRecursive(t *testing.T) { } vpf := pool.NewSharedTaskPool(ctx, runtime.NumCPU()) - ImportConfigProcessor := NewImportConfigProcessor(jsonImporter.NewJsonTreeImporter(jsonAny, "owner1", 5, false), types.NewUpdateInsertFlags()) + ImportConfigProcessor := procImporter.NewImportConfigProcessor(jsonImporter.NewJsonTreeImporter(jsonAny, "owner1", 5, false), types.NewUpdateInsertFlags()) err = ImportConfigProcessor.Run(ctx, s, vpf) if err != nil { t.Fatal(err) diff --git a/pkg/tree/utils.go b/pkg/tree/utils.go index ce938649..7eb8ca48 100644 --- a/pkg/tree/utils.go +++ b/pkg/tree/utils.go @@ -10,6 +10,7 @@ import ( "github.com/sdcio/data-server/pkg/tree/importer" jsonImporter "github.com/sdcio/data-server/pkg/tree/importer/json" + procImporter "github.com/sdcio/data-server/pkg/tree/processors/importer" "github.com/sdcio/data-server/pkg/tree/types" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -35,7 +36,7 @@ func loadYgotStructIntoTreeRoot(ctx context.Context, gs ygot.GoStruct, root *Roo stp := pool.NewSharedTaskPool(ctx, runtime.NumCPU()) - importProcessor := NewImportConfigProcessor(jsonImporter.NewJsonTreeImporter(jsonConfAny, owner, prio, nonRevertive), flags) + importProcessor := procImporter.NewImportConfigProcessor(jsonImporter.NewJsonTreeImporter(jsonConfAny, owner, prio, nonRevertive), flags) err = importProcessor.Run(ctx, root.sharedEntryAttributes, stp) if err != nil {