diff --git a/VERSION b/VERSION
index f805d9f..0d3ad67 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.10-dev
+2.2.10
diff --git a/pkg/db/model/backend.go b/pkg/db/backend.go
similarity index 78%
rename from pkg/db/model/backend.go
rename to pkg/db/backend.go
index f5ead88..c319d99 100644
--- a/pkg/db/model/backend.go
+++ b/pkg/db/backend.go
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package model
+package db
 
 import (
 	"errors"
@@ -23,13 +23,8 @@
 	"github.com/opencord/voltha-lib-go/v2/pkg/log"
 	"strconv"
 	"sync"
-	"time"
 )
 
-//TODO: missing cache stuff
-//TODO: missing retry stuff
-//TODO: missing proper logging
-
 // Backend structure holds details for accessing the kv store
 type Backend struct {
 	sync.RWMutex
@@ -82,53 +77,47 @@
 }
 
 // List retrieves one or more items that match the specified key
-func (b *Backend) List(key string, lock ...bool) (map[string]*kvstore.KVPair, error) {
+func (b *Backend) List(key string) (map[string]*kvstore.KVPair, error) {
 	b.Lock()
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugw("listing-key", log.Fields{"key": key, "path": formattedPath, "lock": lock})
+	log.Debugw("listing-key", log.Fields{"key": key, "path": formattedPath})
 
-	return b.Client.List(formattedPath, b.Timeout, lock...)
+	return b.Client.List(formattedPath, b.Timeout)
 }
 
 // Get retrieves an item that matches the specified key
-func (b *Backend) Get(key string, lock ...bool) (*kvstore.KVPair, error) {
+func (b *Backend) Get(key string) (*kvstore.KVPair, error) {
 	b.Lock()
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugw("getting-key", log.Fields{"key": key, "path": formattedPath, "lock": lock})
+	log.Debugw("getting-key", log.Fields{"key": key, "path": formattedPath})
 
-	start := time.Now()
-	err, pair := b.Client.Get(formattedPath, b.Timeout, lock...)
-	stop := time.Now()
-
-	GetProfiling().AddToDatabaseRetrieveTime(stop.Sub(start).Seconds())
-
-	return err, pair
+	return b.Client.Get(formattedPath, b.Timeout)
 }
 
 // Put stores an item value under the specifed key
-func (b *Backend) Put(key string, value interface{}, lock ...bool) error {
+func (b *Backend) Put(key string, value interface{}) error {
 	b.Lock()
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugw("putting-key", log.Fields{"key": key, "value": string(value.([]byte)), "path": formattedPath, "lock": lock})
+	log.Debugw("putting-key", log.Fields{"key": key, "value": string(value.([]byte)), "path": formattedPath})
 
-	return b.Client.Put(formattedPath, value, b.Timeout, lock...)
+	return b.Client.Put(formattedPath, value, b.Timeout)
 }
 
 // Delete removes an item under the specified key
-func (b *Backend) Delete(key string, lock ...bool) error {
+func (b *Backend) Delete(key string) error {
 	b.Lock()
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugw("deleting-key", log.Fields{"key": key, "path": formattedPath, "lock": lock})
+	log.Debugw("deleting-key", log.Fields{"key": key, "path": formattedPath})
 
-	return b.Client.Delete(formattedPath, b.Timeout, lock...)
+	return b.Client.Delete(formattedPath, b.Timeout)
 }
 
 // CreateWatch starts watching events for the specified key
diff --git a/pkg/db/kvstore/client.go b/pkg/db/kvstore/client.go
index c0ebe5f..97fbec9 100644
--- a/pkg/db/kvstore/client.go
+++ b/pkg/db/kvstore/client.go
@@ -79,10 +79,10 @@
 
 // Client represents the set of APIs a KV Client must implement
 type Client interface {
-	List(key string, timeout int, lock ...bool) (map[string]*KVPair, error)
-	Get(key string, timeout int, lock ...bool) (*KVPair, error)
-	Put(key string, value interface{}, timeout int, lock ...bool) error
-	Delete(key string, timeout int, lock ...bool) error
+	List(key string, timeout int) (map[string]*KVPair, error)
+	Get(key string, timeout int) (*KVPair, error)
+	Put(key string, value interface{}, timeout int) error
+	Delete(key string, timeout int) error
 	Reserve(key string, value interface{}, ttl int64) (interface{}, error)
 	ReleaseReservation(key string) error
 	ReleaseAllReservations() error
diff --git a/pkg/db/kvstore/consulclient.go b/pkg/db/kvstore/consulclient.go
index e0e8550..a94de4d 100644
--- a/pkg/db/kvstore/consulclient.go
+++ b/pkg/db/kvstore/consulclient.go
@@ -71,7 +71,7 @@
 
 // List returns an array of key-value pairs with key as a prefix.  Timeout defines how long the function will
 // wait for a response
-func (c *ConsulClient) List(key string, timeout int, lock ...bool) (map[string]*KVPair, error) {
+func (c *ConsulClient) List(key string, timeout int) (map[string]*KVPair, error) {
 	duration := GetDuration(timeout)
 
 	kv := c.consul.KV()
@@ -92,7 +92,7 @@
 
 // Get returns a key-value pair for a given key. Timeout defines how long the function will
 // wait for a response
-func (c *ConsulClient) Get(key string, timeout int, lock ...bool) (*KVPair, error) {
+func (c *ConsulClient) Get(key string, timeout int) (*KVPair, error) {
 
 	duration := GetDuration(timeout)
 
@@ -115,7 +115,7 @@
 // Put writes a key-value pair to the KV store.  Value can only be a string or []byte since the consul API
 // accepts only a []byte as a value for a put operation. Timeout defines how long the function will
 // wait for a response
-func (c *ConsulClient) Put(key string, value interface{}, timeout int, lock ...bool) error {
+func (c *ConsulClient) Put(key string, value interface{}, timeout int) error {
 
 	// Validate that we can create a byte array from the value as consul API expects a byte array
 	var val []byte
@@ -141,7 +141,7 @@
 
 // Delete removes a key from the KV store. Timeout defines how long the function will
 // wait for a response
-func (c *ConsulClient) Delete(key string, timeout int, lock ...bool) error {
+func (c *ConsulClient) Delete(key string, timeout int) error {
 	kv := c.consul.KV()
 	var writeOptions consulapi.WriteOptions
 	c.writeLock.Lock()
diff --git a/pkg/db/kvstore/etcdclient.go b/pkg/db/kvstore/etcdclient.go
index 8db047c..e8bc92c 100644
--- a/pkg/db/kvstore/etcdclient.go
+++ b/pkg/db/kvstore/etcdclient.go
@@ -71,7 +71,7 @@
 
 // List returns an array of key-value pairs with key as a prefix.  Timeout defines how long the function will
 // wait for a response
-func (c *EtcdClient) List(key string, timeout int, lock ...bool) (map[string]*KVPair, error) {
+func (c *EtcdClient) List(key string, timeout int) (map[string]*KVPair, error) {
 	duration := GetDuration(timeout)
 
 	ctx, cancel := context.WithTimeout(context.Background(), duration)
@@ -91,7 +91,7 @@
 
 // Get returns a key-value pair for a given key. Timeout defines how long the function will
 // wait for a response
-func (c *EtcdClient) Get(key string, timeout int, lock ...bool) (*KVPair, error) {
+func (c *EtcdClient) Get(key string, timeout int) (*KVPair, error) {
 	duration := GetDuration(timeout)
 
 	ctx, cancel := context.WithTimeout(context.Background(), duration)
@@ -112,7 +112,7 @@
 // Put writes a key-value pair to the KV store.  Value can only be a string or []byte since the etcd API
 // accepts only a string as a value for a put operation. Timeout defines how long the function will
 // wait for a response
-func (c *EtcdClient) Put(key string, value interface{}, timeout int, lock ...bool) error {
+func (c *EtcdClient) Put(key string, value interface{}, timeout int) error {
 
 	// Validate that we can convert value to a string as etcd API expects a string
 	var val string
@@ -155,7 +155,7 @@
 
 // Delete removes a key from the KV store. Timeout defines how long the function will
 // wait for a response
-func (c *EtcdClient) Delete(key string, timeout int, lock ...bool) error {
+func (c *EtcdClient) Delete(key string, timeout int) error {
 
 	duration := GetDuration(timeout)
 
@@ -233,7 +233,7 @@
 		}
 	} else {
 		// Read the Key to ensure this is our Key
-		m, err := c.Get(key, defaultKVGetTimeout, false)
+		m, err := c.Get(key, defaultKVGetTimeout)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/db/model/base_test.go b/pkg/db/model/base_test.go
deleted file mode 100644
index 34e6426..0000000
--- a/pkg/db/model/base_test.go
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"runtime/debug"
-	"sync"
-)
-
-type ModelTestConfig struct {
-	Root      *root
-	Backend   *Backend
-	RootProxy *Proxy
-	DbPrefix  string
-	DbType    string
-	DbHost    string
-	DbPort    int
-	DbTimeout int
-}
-
-var callbackMutex sync.Mutex
-
-func commonChanCallback(args ...interface{}) interface{} {
-	log.Infof("Running common callback - arg count: %d", len(args))
-
-	//for i := 0; i < len(args); i++ {
-	//	log.Infof("ARG %d : %+v", i, args[i])
-	//}
-
-	callbackMutex.Lock()
-	defer callbackMutex.Unlock()
-
-	execDoneChan := args[1].(*chan struct{})
-
-	// Inform the caller that the callback was executed
-	if *execDoneChan != nil {
-		log.Infof("Sending completion indication - stack:%s", string(debug.Stack()))
-		close(*execDoneChan)
-		*execDoneChan = nil
-	}
-
-	return nil
-}
-
-func commonCallback2(args ...interface{}) interface{} {
-	log.Infof("Running common2 callback - arg count: %d %+v", len(args), args)
-
-	return nil
-}
-
-func commonCallbackFunc(args ...interface{}) interface{} {
-	log.Infof("Running common callback - arg count: %d", len(args))
-
-	for i := 0; i < len(args); i++ {
-		log.Infof("ARG %d : %+v", i, args[i])
-	}
-	execStatusFunc := args[1].(func(bool))
-
-	// Inform the caller that the callback was executed
-	execStatusFunc(true)
-
-	return nil
-}
-
-func firstCallback(args ...interface{}) interface{} {
-	name := args[0]
-	id := args[1]
-	log.Infof("Running first callback - name: %s, id: %s\n", name, id)
-	return nil
-}
-
-func secondCallback(args ...interface{}) interface{} {
-	name := args[0].(map[string]string)
-	id := args[1]
-	log.Infof("Running second callback - name: %s, id: %f\n", name["name"], id)
-	// FIXME: the panic call seem to interfere with the logging mechanism
-	//panic("Generating a panic in second callback")
-	return nil
-}
-
-func thirdCallback(args ...interface{}) interface{} {
-	name := args[0]
-	id := args[1].(*voltha.Device)
-	log.Infof("Running third callback - name: %+v, id: %s\n", name, id.Id)
-	return nil
-}
diff --git a/pkg/db/model/branch.go b/pkg/db/model/branch.go
deleted file mode 100644
index 957e0ca..0000000
--- a/pkg/db/model/branch.go
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"sync"
-)
-
-// TODO: implement weak references or something equivalent
-// TODO: missing proper logging
-
-// Branch structure is used to classify a collection of transaction based revisions
-type Branch struct {
-	mutex      sync.RWMutex
-	Node       *node
-	Txid       string
-	Origin     Revision
-	Revisions  map[string]Revision
-	LatestLock sync.RWMutex
-	Latest     Revision
-}
-
-// NewBranch creates a new instance of the Branch structure
-func NewBranch(node *node, txid string, origin Revision, autoPrune bool) *Branch {
-	b := &Branch{}
-	b.Node = node
-	b.Txid = txid
-	b.Origin = origin
-	b.Revisions = make(map[string]Revision)
-	b.Latest = origin
-
-	return b
-}
-
-// Utility function to extract all children names for a given revision (mostly for debugging purposes)
-func (b *Branch) retrieveChildrenNames(revision Revision) []string {
-	var childrenNames []string
-
-	for _, child := range revision.GetChildren("devices") {
-		childrenNames = append(childrenNames, child.GetName())
-	}
-
-	return childrenNames
-}
-
-// Utility function to compare children names and report the missing ones (mostly for debugging purposes)
-func (b *Branch) findMissingChildrenNames(previousNames, latestNames []string) []string {
-	var missingNames []string
-
-	for _, previousName := range previousNames {
-		found := false
-
-		if len(latestNames) == 0 {
-			break
-		}
-
-		for _, latestName := range latestNames {
-			if previousName == latestName {
-				found = true
-				break
-			}
-		}
-		if !found {
-			missingNames = append(missingNames, previousName)
-		}
-	}
-
-	return missingNames
-}
-
-// SetLatest assigns the latest revision for this branch
-func (b *Branch) SetLatest(latest Revision) {
-	b.mutex.Lock()
-	defer b.mutex.Unlock()
-
-	if b.Latest != nil {
-		log.Debugw("updating-latest-revision", log.Fields{"current": b.Latest.GetHash(), "new": latest.GetHash()})
-
-		// Go through list of children names in current revision and new revision
-		// and then compare the resulting outputs to ensure that we have not lost any entries.
-
-		if level, _ := log.GetPackageLogLevel(); level == log.DebugLevel {
-			var previousNames, latestNames, missingNames []string
-
-			if previousNames = b.retrieveChildrenNames(b.Latest); len(previousNames) > 0 {
-				log.Debugw("children-of-previous-revision", log.Fields{"hash": b.Latest.GetHash(), "names": previousNames})
-			}
-
-			if latestNames = b.retrieveChildrenNames(b.Latest); len(latestNames) > 0 {
-				log.Debugw("children-of-latest-revision", log.Fields{"hash": latest.GetHash(), "names": latestNames})
-			}
-
-			if missingNames = b.findMissingChildrenNames(previousNames, latestNames); len(missingNames) > 0 {
-				log.Debugw("children-missing-in-latest-revision", log.Fields{"hash": latest.GetHash(), "names": missingNames})
-			}
-		}
-
-	} else {
-		log.Debugw("setting-latest-revision", log.Fields{"new": latest.GetHash()})
-	}
-
-	b.Latest = latest
-}
-
-// GetLatest retrieves the latest revision of the branch
-func (b *Branch) GetLatest() Revision {
-	b.mutex.RLock()
-	defer b.mutex.RUnlock()
-
-	return b.Latest
-}
-
-// GetOrigin retrieves the original revision of the branch
-func (b *Branch) GetOrigin() Revision {
-	b.mutex.RLock()
-	defer b.mutex.RUnlock()
-
-	return b.Origin
-}
-
-// AddRevision inserts a new revision to the branch
-func (b *Branch) AddRevision(revision Revision) {
-	if revision != nil && b.GetRevision(revision.GetHash()) == nil {
-		b.SetRevision(revision.GetHash(), revision)
-	}
-}
-
-// GetRevision pulls a revision entry at the specified hash
-func (b *Branch) GetRevision(hash string) Revision {
-	b.mutex.RLock()
-	defer b.mutex.RUnlock()
-
-	if revision, ok := b.Revisions[hash]; ok {
-		return revision
-	}
-
-	return nil
-}
-
-// SetRevision updates a revision entry at the specified hash
-func (b *Branch) SetRevision(hash string, revision Revision) {
-	b.mutex.Lock()
-	defer b.mutex.Unlock()
-
-	b.Revisions[hash] = revision
-}
-
-// DeleteRevision removes a revision with the specified hash
-func (b *Branch) DeleteRevision(hash string) {
-	b.mutex.Lock()
-	defer b.mutex.Unlock()
-
-	if _, ok := b.Revisions[hash]; ok {
-		delete(b.Revisions, hash)
-	}
-}
diff --git a/pkg/db/model/branch_test.go b/pkg/db/model/branch_test.go
deleted file mode 100644
index cf8406c..0000000
--- a/pkg/db/model/branch_test.go
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"crypto/md5"
-	"fmt"
-	"testing"
-)
-
-var (
-	TestBranch_BRANCH *Branch
-	TestBranch_HASH   string
-)
-
-// Create a new branch and ensure that fields are populated
-func TestBranch_NewBranch(t *testing.T) {
-	node := &node{}
-	hash := fmt.Sprintf("%x", md5.Sum([]byte("origin_hash")))
-	origin := &NonPersistedRevision{
-		Config:   &DataRevision{},
-		Children: make(map[string][]Revision),
-		Hash:     hash,
-		Branch:   &Branch{},
-	}
-	txid := fmt.Sprintf("%x", md5.Sum([]byte("branch_transaction_id")))
-
-	TestBranch_BRANCH = NewBranch(node, txid, origin, true)
-	t.Logf("New Branch(txid:%s) created: %+v\n", txid, TestBranch_BRANCH)
-
-	if TestBranch_BRANCH.Latest == nil {
-		t.Errorf("Branch latest pointer is nil")
-	} else if TestBranch_BRANCH.Origin == nil {
-		t.Errorf("Branch origin pointer is nil")
-	} else if TestBranch_BRANCH.Node == nil {
-		t.Errorf("Branch node pointer is nil")
-	} else if TestBranch_BRANCH.Revisions == nil {
-		t.Errorf("Branch revisions map is nil")
-	} else if TestBranch_BRANCH.Txid == "" {
-		t.Errorf("Branch transaction id is empty")
-	}
-}
-
-// Add a new revision to the branch
-func TestBranch_AddRevision(t *testing.T) {
-	TestBranch_HASH = fmt.Sprintf("%x", md5.Sum([]byte("revision_hash")))
-	rev := &NonPersistedRevision{
-		Config:   &DataRevision{},
-		Children: make(map[string][]Revision),
-		Hash:     TestBranch_HASH,
-		Branch:   &Branch{},
-	}
-
-	TestBranch_BRANCH.AddRevision(rev)
-	t.Logf("Added revision: %+v\n", rev)
-
-	if len(TestBranch_BRANCH.Revisions) == 0 {
-		t.Errorf("Branch revisions map is empty")
-	}
-}
-
-// Ensure that the added revision can be retrieved
-func TestBranch_GetRevision(t *testing.T) {
-	if rev := TestBranch_BRANCH.GetRevision(TestBranch_HASH); rev == nil {
-		t.Errorf("Unable to retrieve revision for hash:%s", TestBranch_HASH)
-	} else {
-		t.Logf("Got revision for hash:%s rev:%+v\n", TestBranch_HASH, rev)
-	}
-}
-
-// Set the added revision as the latest
-func TestBranch_LatestRevision(t *testing.T) {
-	addedRevision := TestBranch_BRANCH.GetRevision(TestBranch_HASH)
-	TestBranch_BRANCH.SetLatest(addedRevision)
-
-	rev := TestBranch_BRANCH.GetLatest()
-	t.Logf("Retrieved latest revision :%+v", rev)
-
-	if rev == nil {
-		t.Error("Unable to retrieve latest revision")
-	} else if rev.GetHash() != TestBranch_HASH {
-		t.Errorf("Latest revision does not match hash: %s", TestBranch_HASH)
-	}
-}
-
-// Ensure that the origin revision remains and differs from subsequent revisions
-func TestBranch_OriginRevision(t *testing.T) {
-	rev := TestBranch_BRANCH.Origin
-	t.Logf("Retrieved origin revision :%+v", rev)
-
-	if rev == nil {
-		t.Error("Unable to retrieve origin revision")
-	} else if rev.GetHash() == TestBranch_HASH {
-		t.Errorf("Origin revision should differ from added revision: %s", TestBranch_HASH)
-	}
-}
diff --git a/pkg/db/model/callback_type.go b/pkg/db/model/callback_type.go
deleted file mode 100644
index b530dee..0000000
--- a/pkg/db/model/callback_type.go
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-// CallbackType is an enumerated value to express when a callback should be executed
-type CallbackType uint8
-
-// Enumerated list of callback types
-const (
-	GET CallbackType = iota
-	PRE_UPDATE
-	POST_UPDATE
-	PRE_ADD
-	POST_ADD
-	PRE_REMOVE
-	POST_REMOVE
-	POST_LISTCHANGE
-)
-
-var enumCallbackTypes = []string{
-	"GET",
-	"PRE_UPDATE",
-	"POST_UPDATE",
-	"PRE_ADD",
-	"POST_ADD",
-	"PRE_REMOVE",
-	"POST_REMOVE",
-	"POST_LISTCHANGE",
-}
-
-func (t CallbackType) String() string {
-	return enumCallbackTypes[t]
-}
diff --git a/pkg/db/model/child_type.go b/pkg/db/model/child_type.go
deleted file mode 100644
index 5928192..0000000
--- a/pkg/db/model/child_type.go
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	desc "github.com/golang/protobuf/descriptor"
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"github.com/opencord/voltha-protos/v2/go/common"
-	"reflect"
-	"strconv"
-	"sync"
-)
-
-type childTypesSingleton struct {
-	mutex sync.RWMutex
-	Cache map[interface{}]map[string]*ChildType
-}
-
-var instanceChildTypes *childTypesSingleton
-var onceChildTypes sync.Once
-
-func getChildTypes() *childTypesSingleton {
-	onceChildTypes.Do(func() {
-		instanceChildTypes = &childTypesSingleton{}
-	})
-	return instanceChildTypes
-}
-
-func (s *childTypesSingleton) GetCache() map[interface{}]map[string]*ChildType {
-	s.mutex.RLock()
-	defer s.mutex.RUnlock()
-	return s.Cache
-}
-
-func (s *childTypesSingleton) SetCache(cache map[interface{}]map[string]*ChildType) {
-	s.mutex.Lock()
-	defer s.mutex.Unlock()
-	s.Cache = cache
-}
-
-func (s *childTypesSingleton) GetCacheEntry(key interface{}) (map[string]*ChildType, bool) {
-	s.mutex.RLock()
-	defer s.mutex.RUnlock()
-	childTypeMap, exists := s.Cache[key]
-	return childTypeMap, exists
-}
-
-func (s *childTypesSingleton) SetCacheEntry(key interface{}, value map[string]*ChildType) {
-	s.mutex.Lock()
-	defer s.mutex.Unlock()
-	s.Cache[key] = value
-}
-
-func (s *childTypesSingleton) ResetCache() {
-	s.mutex.Lock()
-	defer s.mutex.Unlock()
-	s.Cache = make(map[interface{}]map[string]*ChildType)
-}
-
-// ChildType structure contains construct details of an object
-type ChildType struct {
-	ClassModule string
-	ClassType   reflect.Type
-	IsContainer bool
-	Key         string
-	KeyFromStr  func(s string) interface{}
-}
-
-// ChildrenFields retrieves list of child objects associated to a given interface
-func ChildrenFields(cls interface{}) map[string]*ChildType {
-	if cls == nil {
-		return nil
-	}
-	var names map[string]*ChildType
-	var namesExist bool
-
-	if getChildTypes().Cache == nil {
-		getChildTypes().Cache = make(map[interface{}]map[string]*ChildType)
-	}
-
-	msgType := reflect.TypeOf(cls)
-	inst := getChildTypes()
-
-	if names, namesExist = inst.Cache[msgType.String()]; !namesExist {
-		names = make(map[string]*ChildType)
-
-		_, md := desc.ForMessage(cls.(desc.Message))
-
-		// TODO: Do we need to validate MD for nil, panic or exception?
-		for _, field := range md.Field {
-			if options := field.GetOptions(); options != nil {
-				if proto.HasExtension(options, common.E_ChildNode) {
-					isContainer := *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
-					meta, _ := proto.GetExtension(options, common.E_ChildNode)
-
-					var keyFromStr func(string) interface{}
-					var ct ChildType
-
-					parentType := FindOwnerType(reflect.ValueOf(cls), field.GetName(), 0, false)
-					if meta.(*common.ChildNode).GetKey() != "" {
-						keyType := FindKeyOwner(reflect.New(parentType).Elem().Interface(), meta.(*common.ChildNode).GetKey(), 0)
-
-						switch keyType.(reflect.Type).Name() {
-						case "string":
-							keyFromStr = func(s string) interface{} {
-								return s
-							}
-						case "int32":
-							keyFromStr = func(s string) interface{} {
-								i, _ := strconv.Atoi(s)
-								return int32(i)
-							}
-						case "int64":
-							keyFromStr = func(s string) interface{} {
-								i, _ := strconv.Atoi(s)
-								return int64(i)
-							}
-						case "uint32":
-							keyFromStr = func(s string) interface{} {
-								i, _ := strconv.Atoi(s)
-								return uint32(i)
-							}
-						case "uint64":
-							keyFromStr = func(s string) interface{} {
-								i, _ := strconv.Atoi(s)
-								return uint64(i)
-							}
-						default:
-							log.Errorf("Key type not implemented - type: %s\n", keyType.(reflect.Type))
-						}
-					}
-
-					ct = ChildType{
-						ClassModule: parentType.String(),
-						ClassType:   parentType,
-						IsContainer: isContainer,
-						Key:         meta.(*common.ChildNode).GetKey(),
-						KeyFromStr:  keyFromStr,
-					}
-
-					names[field.GetName()] = &ct
-				}
-			}
-		}
-
-		getChildTypes().Cache[msgType.String()] = names
-	} else {
-		entry, _ := inst.GetCacheEntry(msgType.String())
-		log.Debugf("Cache entry for %s: %+v", msgType.String(), entry)
-	}
-
-	return names
-}
diff --git a/pkg/db/model/child_type_test.go b/pkg/db/model/child_type_test.go
deleted file mode 100644
index 3836858..0000000
--- a/pkg/db/model/child_type_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"reflect"
-	"testing"
-)
-
-// Dissect a proto message by extracting all the children fields
-func TestChildType_01_Device_Proto_ChildrenFields(t *testing.T) {
-	var cls *voltha.Device
-
-	t.Logf("Extracting children fields from proto type: %s", reflect.TypeOf(cls))
-	names := ChildrenFields(cls)
-	t.Logf("Extracting children field names: %+v", names)
-
-	expectedKeys := []string{"ports", "flows", "flow_groups", "image_downloads", "pm_configs"}
-	for _, key := range expectedKeys {
-		if _, exists := names[key]; !exists {
-			t.Errorf("Missing key:%s from class type:%s", key, reflect.TypeOf(cls))
-		}
-	}
-}
-
-// Verify that the cache contains an entry for types on which ChildrenFields was performed
-func TestChildType_02_Cache_Keys(t *testing.T) {
-	if _, exists := getChildTypes().Cache[reflect.TypeOf(&voltha.Device{}).String()]; !exists {
-		t.Errorf("getChildTypeCache().Cache should have an entry of type: %+v\n", reflect.TypeOf(&voltha.Device{}).String())
-	}
-	for k := range getChildTypes().Cache {
-		t.Logf("getChildTypeCache().Cache Key:%+v\n", k)
-	}
-}
diff --git a/pkg/db/model/data_revision.go b/pkg/db/model/data_revision.go
deleted file mode 100644
index 35f5958..0000000
--- a/pkg/db/model/data_revision.go
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"bytes"
-	"crypto/md5"
-	"encoding/json"
-	"fmt"
-	"github.com/golang/protobuf/proto"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-)
-
-// DataRevision stores the data associated to a revision along with its calculated checksum hash value
-type DataRevision struct {
-	Data interface{}
-	Hash string
-}
-
-// NewDataRevision creates a new instance of a DataRevision structure
-func NewDataRevision(root *root, data interface{}) *DataRevision {
-	dr := DataRevision{}
-	dr.Data = data
-	dr.Hash = dr.hashData(root, data)
-
-	return &dr
-}
-
-func (dr *DataRevision) hashData(root *root, data interface{}) string {
-	var buffer bytes.Buffer
-
-	if IsProtoMessage(data) {
-		if pbdata, err := proto.Marshal(data.(proto.Message)); err != nil {
-			log.Debugf("problem to marshal protobuf data --> err: %s", err.Error())
-		} else {
-			buffer.Write(pbdata)
-			// To ensure uniqueness in case data is nil, also include data type
-			buffer.Write([]byte(reflect.TypeOf(data).String()))
-		}
-
-	} else if reflect.ValueOf(data).IsValid() {
-		dataObj := reflect.New(reflect.TypeOf(data).Elem())
-		if json, err := json.Marshal(dataObj.Interface()); err != nil {
-			log.Debugf("problem to marshal data --> err: %s", err.Error())
-		} else {
-			buffer.Write(json)
-		}
-	} else {
-		dataObj := reflect.New(reflect.TypeOf(data).Elem())
-		buffer.Write(dataObj.Bytes())
-	}
-
-	// Add the root pointer that owns the current data for extra uniqueness
-	rootPtr := fmt.Sprintf("%p", root)
-	buffer.Write([]byte(rootPtr))
-
-	return fmt.Sprintf("%x", md5.Sum(buffer.Bytes()))[:12]
-}
diff --git a/pkg/db/model/event_bus.go b/pkg/db/model/event_bus.go
deleted file mode 100644
index d0a21f1..0000000
--- a/pkg/db/model/event_bus.go
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"encoding/json"
-	"github.com/golang/protobuf/proto"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-)
-
-// EventBus contains the details required to communicate with the event bus mechanism
-type EventBus struct {
-	client *EventBusClient
-	topic  string
-}
-
-// ignoredCallbacks keeps a list of callbacks that should not be advertised on the event bus
-var (
-	ignoredCallbacks = map[CallbackType]struct{}{
-		PRE_ADD:         {},
-		GET:             {},
-		POST_LISTCHANGE: {},
-		PRE_REMOVE:      {},
-		PRE_UPDATE:      {},
-	}
-)
-
-// NewEventBus creates a new instance of the EventBus structure
-func NewEventBus() *EventBus {
-	bus := &EventBus{
-		client: NewEventBusClient(),
-		topic:  "model-change-events",
-	}
-	return bus
-}
-
-// Advertise will publish the provided information to the event bus
-func (bus *EventBus) Advertise(args ...interface{}) interface{} {
-	eventType := args[0].(CallbackType)
-	hash := args[1].(string)
-	data := args[2:]
-
-	if _, ok := ignoredCallbacks[eventType]; ok {
-		log.Debugf("ignoring event - type:%s, data:%+v", eventType, data)
-	}
-	var kind voltha.ConfigEventType_ConfigEventType
-	switch eventType {
-	case POST_ADD:
-		kind = voltha.ConfigEventType_add
-	case POST_REMOVE:
-		kind = voltha.ConfigEventType_remove
-	default:
-		kind = voltha.ConfigEventType_update
-	}
-
-	var msg []byte
-	var err error
-	if IsProtoMessage(data) {
-		if msg, err = proto.Marshal(data[0].(proto.Message)); err != nil {
-			log.Debugf("problem marshalling proto data: %+v, err:%s", data[0], err.Error())
-		}
-	} else if data[0] != nil {
-		if msg, err = json.Marshal(data[0]); err != nil {
-			log.Debugf("problem marshalling json data: %+v, err:%s", data[0], err.Error())
-		}
-	} else {
-		log.Debugf("no data to advertise : %+v", data[0])
-	}
-
-	event := voltha.ConfigEvent{
-		Type: kind,
-		Hash: hash,
-		Data: string(msg),
-	}
-
-	bus.client.Publish(bus.topic, event)
-
-	return nil
-}
diff --git a/pkg/db/model/event_bus_client.go b/pkg/db/model/event_bus_client.go
deleted file mode 100644
index d9a8d49..0000000
--- a/pkg/db/model/event_bus_client.go
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-)
-
-// EventBusClient is an abstraction layer structure to communicate with an event bus mechanism
-type EventBusClient struct {
-}
-
-// NewEventBusClient creates a new EventBusClient instance
-func NewEventBusClient() *EventBusClient {
-	return &EventBusClient{}
-}
-
-// Publish sends a event to the bus
-func (ebc *EventBusClient) Publish(topic string, event voltha.ConfigEvent) {
-	log.Debugf("publishing event:%+v, topic:%s\n", event, topic)
-}
diff --git a/pkg/db/model/merge.go b/pkg/db/model/merge.go
deleted file mode 100644
index 07ae9b9..0000000
--- a/pkg/db/model/merge.go
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-)
-
-func revisionsAreEqual(a, b []Revision) bool {
-	// If one is nil, the other must also be nil.
-	if (a == nil) != (b == nil) {
-		return false
-	}
-
-	if len(a) != len(b) {
-		return false
-	}
-
-	for i := range a {
-		if a[i] != b[i] {
-			return false
-		}
-	}
-
-	return true
-}
-
-type changeAnalysis struct {
-	KeyMap1     map[string]int
-	KeyMap2     map[string]int
-	AddedKeys   map[string]struct{}
-	RemovedKeys map[string]struct{}
-	ChangedKeys map[string]struct{}
-}
-
-func newChangeAnalysis(lst1, lst2 []Revision, keyName string) *changeAnalysis {
-	changes := &changeAnalysis{}
-
-	changes.KeyMap1 = make(map[string]int)
-	changes.KeyMap2 = make(map[string]int)
-
-	changes.AddedKeys = make(map[string]struct{})
-	changes.RemovedKeys = make(map[string]struct{})
-	changes.ChangedKeys = make(map[string]struct{})
-
-	for i, rev := range lst1 {
-		_, v := GetAttributeValue(rev.GetData(), keyName, 0)
-		changes.KeyMap1[v.String()] = i
-	}
-	for i, rev := range lst2 {
-		_, v := GetAttributeValue(rev.GetData(), keyName, 0)
-		changes.KeyMap2[v.String()] = i
-	}
-	for v := range changes.KeyMap2 {
-		if _, ok := changes.KeyMap1[v]; !ok {
-			changes.AddedKeys[v] = struct{}{}
-		}
-	}
-	for v := range changes.KeyMap1 {
-		if _, ok := changes.KeyMap2[v]; !ok {
-			changes.RemovedKeys[v] = struct{}{}
-		}
-	}
-	for v := range changes.KeyMap1 {
-		if _, ok := changes.KeyMap2[v]; ok && lst1[changes.KeyMap1[v]].GetHash() != lst2[changes.KeyMap2[v]].GetHash() {
-			changes.ChangedKeys[v] = struct{}{}
-		}
-	}
-
-	return changes
-}
-
-// Merge3Way takes care of combining the revision contents of the same data set
-func Merge3Way(
-	forkRev, srcRev, dstRev Revision,
-	mergeChildFunc func(Revision) Revision,
-	dryRun bool) (rev Revision, changes []ChangeTuple) {
-
-	log.Debugw("3-way-merge-request", log.Fields{"dryRun": dryRun})
-
-	var configChanged bool
-	var revsToDiscard []Revision
-
-	if dstRev.GetConfig() == forkRev.GetConfig() {
-		configChanged = dstRev.GetConfig() != srcRev.GetConfig()
-	} else {
-		if dstRev.GetConfig().Hash != srcRev.GetConfig().Hash {
-			log.Error("config-collision")
-		}
-		configChanged = true
-	}
-
-	//newChildren := reflect.ValueOf(dstRev.GetAllChildren()).Interface().(map[string][]Revision)
-	newChildren := make(map[string][]Revision)
-	for entryName, childrenEntry := range dstRev.GetAllChildren() {
-		//newRev.Children[entryName] = append(newRev.Children[entryName], childrenEntry...)
-		newChildren[entryName] = make([]Revision, len(childrenEntry))
-		copy(newChildren[entryName], childrenEntry)
-	}
-
-	childrenFields := ChildrenFields(forkRev.GetData())
-
-	for fieldName, field := range childrenFields {
-		forkList := forkRev.GetChildren(fieldName)
-		srcList := srcRev.GetChildren(fieldName)
-		dstList := dstRev.GetChildren(fieldName)
-
-		if revisionsAreEqual(dstList, srcList) {
-			for _, rev := range srcList {
-				mergeChildFunc(rev)
-			}
-			continue
-		}
-
-		if field.Key == "" {
-			if revisionsAreEqual(dstList, forkList) {
-				if !revisionsAreEqual(srcList, forkList) {
-					log.Error("we should not be here")
-				} else {
-					for _, rev := range srcList {
-						newChildren[fieldName] = append(newChildren[fieldName], mergeChildFunc(rev))
-					}
-					if field.IsContainer {
-						changes = append(
-							changes, ChangeTuple{POST_LISTCHANGE,
-								NewOperationContext("", nil, fieldName, ""), nil},
-						)
-					}
-				}
-			} else {
-				if !revisionsAreEqual(srcList, forkList) {
-					log.Error("cannot merge - single child node or un-keyed children list has changed")
-				}
-			}
-		} else {
-			if revisionsAreEqual(dstList, forkList) {
-				src := newChangeAnalysis(forkList, srcList, field.Key)
-
-				newList := make([]Revision, len(srcList))
-				copy(newList, srcList)
-
-				for key := range src.AddedKeys {
-					idx := src.KeyMap2[key]
-					newRev := mergeChildFunc(newList[idx])
-
-					// FIXME: newRev may come back as nil... exclude those entries for now
-					if newRev != nil {
-						newList[idx] = newRev
-						changes = append(changes, ChangeTuple{POST_ADD, newList[idx].GetData(), newRev.GetData()})
-					}
-				}
-				for key := range src.RemovedKeys {
-					oldRev := forkList[src.KeyMap1[key]]
-					revsToDiscard = append(revsToDiscard, oldRev)
-					changes = append(changes, ChangeTuple{POST_REMOVE, oldRev.GetData(), nil})
-				}
-				for key := range src.ChangedKeys {
-					idx := src.KeyMap2[key]
-					newRev := mergeChildFunc(newList[idx])
-
-					// FIXME: newRev may come back as nil... exclude those entries for now
-					if newRev != nil {
-						newList[idx] = newRev
-					}
-				}
-
-				if !dryRun {
-					newChildren[fieldName] = newList
-				}
-			} else {
-				src := newChangeAnalysis(forkList, srcList, field.Key)
-				dst := newChangeAnalysis(forkList, dstList, field.Key)
-
-				newList := make([]Revision, len(dstList))
-				copy(newList, dstList)
-
-				for key := range src.AddedKeys {
-					if _, exists := dst.AddedKeys[key]; exists {
-						childDstRev := dstList[dst.KeyMap2[key]]
-						childSrcRev := srcList[src.KeyMap2[key]]
-						if childDstRev.GetHash() == childSrcRev.GetHash() {
-							mergeChildFunc(childDstRev)
-						} else {
-							log.Error("conflict error - revision has been added is different")
-						}
-					} else {
-						newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
-						newList = append(newList, newRev)
-						changes = append(changes, ChangeTuple{POST_ADD, srcList[src.KeyMap2[key]], newRev.GetData()})
-					}
-				}
-				for key := range src.ChangedKeys {
-					if _, removed := dst.RemovedKeys[key]; removed {
-						log.Error("conflict error - revision has been removed")
-					} else if _, changed := dst.ChangedKeys[key]; changed {
-						childDstRev := dstList[dst.KeyMap2[key]]
-						childSrcRev := srcList[src.KeyMap2[key]]
-						if childDstRev.GetHash() == childSrcRev.GetHash() {
-							mergeChildFunc(childSrcRev)
-						} else if childDstRev.GetConfig().Hash != childSrcRev.GetConfig().Hash {
-							log.Error("conflict error - revision has been changed and is different")
-						} else {
-							newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
-							newList[dst.KeyMap2[key]] = newRev
-						}
-					} else {
-						newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
-						newList[dst.KeyMap2[key]] = newRev
-					}
-				}
-
-				// TODO: how do i sort this map in reverse order?
-				for key := range src.RemovedKeys {
-					if _, changed := dst.ChangedKeys[key]; changed {
-						log.Error("conflict error - revision has changed")
-					}
-					if _, removed := dst.RemovedKeys[key]; !removed {
-						dstIdx := dst.KeyMap2[key]
-						oldRev := newList[dstIdx]
-						revsToDiscard = append(revsToDiscard, oldRev)
-
-						copy(newList[dstIdx:], newList[dstIdx+1:])
-						newList[len(newList)-1] = nil
-						newList = newList[:len(newList)-1]
-
-						changes = append(changes, ChangeTuple{POST_REMOVE, oldRev.GetData(), nil})
-					}
-				}
-
-				if !dryRun {
-					newChildren[fieldName] = newList
-				}
-			}
-		}
-	}
-
-	if !dryRun && len(newChildren) > 0 {
-		if configChanged {
-			rev = srcRev
-		} else {
-			rev = dstRev
-		}
-
-		for _, discarded := range revsToDiscard {
-			discarded.Drop("", true)
-		}
-
-		// FIXME: Do not discard the latest value for now
-		//dstRev.GetBranch().GetLatest().Drop("", configChanged)
-		rev = rev.UpdateAllChildren(newChildren, dstRev.GetBranch())
-
-		if configChanged {
-			changes = append(changes, ChangeTuple{POST_UPDATE, dstRev.GetBranch().GetLatest().GetData(), rev.GetData()})
-		}
-		return rev, changes
-	}
-
-	return nil, nil
-}
diff --git a/pkg/db/model/model.go b/pkg/db/model/model.go
deleted file mode 100644
index ba4a9b1..0000000
--- a/pkg/db/model/model.go
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-)
-
-func init() {
-	log.AddPackage(log.JSON, log.InfoLevel, log.Fields{"instanceId": "DB_MODEL"})
-	defer log.CleanUp()
-}
-
-const (
-	// period to determine when data requires a refresh (in milliseconds)
-	// TODO: make this configurable?
-	DataRefreshPeriod int64 = 5000
-
-	// Attribute used to store a timestamp in the context object
-	RequestTimestamp = "request-timestamp"
-
-	// Time limit for a KV path reservation (in seconds)
-	ReservationTTL int64 = 180
-)
diff --git a/pkg/db/model/node.go b/pkg/db/model/node.go
deleted file mode 100644
index 264a9dd..0000000
--- a/pkg/db/model/node.go
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-// TODO: proper error handling
-// TODO: proper logging
-
-import (
-	"context"
-	"fmt"
-	"github.com/golang/protobuf/proto"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-	"strings"
-	"sync"
-	"time"
-)
-
-// When a branch has no transaction id, everything gets stored in NONE
-const (
-	NONE string = "none"
-)
-
-// Node interface is an abstraction of the node data structure
-type Node interface {
-	MakeLatest(branch *Branch, revision Revision, changeAnnouncement []ChangeTuple)
-
-	// CRUD functions
-	Add(ctx context.Context, path string, data interface{}, txid string, makeBranch MakeBranchFunction) Revision
-	Get(ctx context.Context, path string, hash string, depth int, deep bool, txid string) interface{}
-	List(ctx context.Context, path string, hash string, depth int, deep bool, txid string) interface{}
-	Update(ctx context.Context, path string, data interface{}, strict bool, txid string, makeBranch MakeBranchFunction) Revision
-	Remove(ctx context.Context, path string, txid string, makeBranch MakeBranchFunction) Revision
-	CreateProxy(ctx context.Context, path string, exclusive bool) *Proxy
-
-	GetProxy() *Proxy
-
-	MakeBranch(txid string) *Branch
-	DeleteBranch(txid string)
-	MergeBranch(txid string, dryRun bool) (Revision, error)
-
-	MakeTxBranch() string
-	DeleteTxBranch(txid string)
-	FoldTxBranch(txid string)
-}
-
-type node struct {
-	mutex     sync.RWMutex
-	Root      *root
-	Type      interface{}
-	Branches  map[string]*Branch
-	Tags      map[string]Revision
-	Proxy     *Proxy
-	EventBus  *EventBus
-	AutoPrune bool
-}
-
-// ChangeTuple holds details of modifications made to a revision
-type ChangeTuple struct {
-	Type         CallbackType
-	PreviousData interface{}
-	LatestData   interface{}
-}
-
-// NewNode creates a new instance of the node data structure
-func NewNode(root *root, initialData interface{}, autoPrune bool, txid string) *node {
-	n := &node{}
-
-	n.Root = root
-	n.Branches = make(map[string]*Branch)
-	n.Tags = make(map[string]Revision)
-	n.Proxy = nil
-	n.EventBus = nil
-	n.AutoPrune = autoPrune
-
-	if IsProtoMessage(initialData) {
-		n.Type = reflect.ValueOf(initialData).Interface()
-		dataCopy := proto.Clone(initialData.(proto.Message))
-		n.initialize(dataCopy, txid)
-	} else if reflect.ValueOf(initialData).IsValid() {
-		// FIXME: this block does not reflect the original implementation
-		// it should be checking if the provided initial_data is already a type!??!
-		// it should be checked before IsProtoMessage
-		n.Type = reflect.ValueOf(initialData).Interface()
-	} else {
-		// not implemented error
-		log.Errorf("cannot process initial data - %+v", initialData)
-	}
-
-	return n
-}
-
-// MakeNode creates a new node in the tree
-func (n *node) MakeNode(data interface{}, txid string) *node {
-	return NewNode(n.Root, data, true, txid)
-}
-
-// MakeRevision create a new revision of the node in the tree
-func (n *node) MakeRevision(branch *Branch, data interface{}, children map[string][]Revision) Revision {
-	return n.GetRoot().MakeRevision(branch, data, children)
-}
-
-// makeLatest will mark the revision of a node as being the latest
-func (n *node) makeLatest(branch *Branch, revision Revision, changeAnnouncement []ChangeTuple) {
-	// Keep a reference to the current revision
-	var previous string
-	if branch.GetLatest() != nil {
-		previous = branch.GetLatest().GetHash()
-	}
-
-	branch.AddRevision(revision)
-
-	// If anything is new, then set the revision as the latest
-	if branch.GetLatest() == nil || revision.GetHash() != branch.GetLatest().GetHash() {
-		if revision.GetName() != "" {
-			log.Debugw("saving-latest-data", log.Fields{"hash": revision.GetHash(), "data": revision.GetData()})
-			// Tag a timestamp to that revision
-			revision.SetLastUpdate()
-			GetRevCache().Set(revision.GetName(), revision)
-		}
-		branch.SetLatest(revision)
-	}
-
-	// Delete the previous revision if anything has changed
-	if previous != "" && previous != branch.GetLatest().GetHash() {
-		branch.DeleteRevision(previous)
-	}
-
-	if changeAnnouncement != nil && branch.Txid == "" {
-		if n.Proxy != nil {
-			for _, change := range changeAnnouncement {
-				log.Debugw("adding-callback",
-					log.Fields{
-						"callbacks":    n.GetProxy().getCallbacks(change.Type),
-						"type":         change.Type,
-						"previousData": change.PreviousData,
-						"latestData":   change.LatestData,
-					})
-				n.Root.AddCallback(
-					n.GetProxy().InvokeCallbacks,
-					change.Type,
-					true,
-					change.PreviousData,
-					change.LatestData)
-			}
-		}
-	}
-}
-
-// Latest returns the latest revision of node with or without the transaction id
-func (n *node) Latest(txid ...string) Revision {
-	var branch *Branch
-
-	if len(txid) > 0 && txid[0] != "" {
-		if branch = n.GetBranch(txid[0]); branch != nil {
-			return branch.GetLatest()
-		}
-	} else if branch = n.GetBranch(NONE); branch != nil {
-		return branch.GetLatest()
-	}
-	return nil
-}
-
-// initialize prepares the content of a node along with its possible ramifications
-func (n *node) initialize(data interface{}, txid string) {
-	children := make(map[string][]Revision)
-	for fieldName, field := range ChildrenFields(n.Type) {
-		_, fieldValue := GetAttributeValue(data, fieldName, 0)
-
-		if fieldValue.IsValid() {
-			if field.IsContainer {
-				if field.Key != "" {
-					for i := 0; i < fieldValue.Len(); i++ {
-						v := fieldValue.Index(i)
-
-						if rev := n.MakeNode(v.Interface(), txid).Latest(txid); rev != nil {
-							children[fieldName] = append(children[fieldName], rev)
-						}
-
-						// TODO: The following logic was ported from v1.0.  Need to verify if it is required
-						//var keysSeen []string
-						//_, key := GetAttributeValue(v.Interface(), field.Key, 0)
-						//for _, k := range keysSeen {
-						//	if k == key.String() {
-						//		//log.Errorf("duplicate key - %s", k)
-						//	}
-						//}
-						//keysSeen = append(keysSeen, key.String())
-					}
-
-				} else {
-					for i := 0; i < fieldValue.Len(); i++ {
-						v := fieldValue.Index(i)
-						if newNodeRev := n.MakeNode(v.Interface(), txid).Latest(); newNodeRev != nil {
-							children[fieldName] = append(children[fieldName], newNodeRev)
-						}
-					}
-				}
-			} else {
-				if newNodeRev := n.MakeNode(fieldValue.Interface(), txid).Latest(); newNodeRev != nil {
-					children[fieldName] = append(children[fieldName], newNodeRev)
-				}
-			}
-		} else {
-			log.Errorf("field is invalid - %+v", fieldValue)
-		}
-	}
-
-	branch := NewBranch(n, "", nil, n.AutoPrune)
-	rev := n.MakeRevision(branch, data, children)
-	n.makeLatest(branch, rev, nil)
-
-	if txid == "" {
-		n.SetBranch(NONE, branch)
-	} else {
-		n.SetBranch(txid, branch)
-	}
-}
-
-// findRevByKey retrieves a specific revision from a node tree
-func (n *node) findRevByKey(revs []Revision, keyName string, value interface{}) (int, Revision) {
-	for i, rev := range revs {
-		dataValue := reflect.ValueOf(rev.GetData())
-		dataStruct := GetAttributeStructure(rev.GetData(), keyName, 0)
-
-		fieldValue := dataValue.Elem().FieldByName(dataStruct.Name)
-
-		a := fmt.Sprintf("%s", fieldValue.Interface())
-		b := fmt.Sprintf("%s", value)
-		if a == b {
-			return i, revs[i]
-		}
-	}
-
-	return -1, nil
-}
-
-// Get retrieves the data from a node tree that resides at the specified path
-func (n *node) List(ctx context.Context, path string, hash string, depth int, deep bool, txid string) interface{} {
-	n.mutex.Lock()
-	defer n.mutex.Unlock()
-
-	log.Debugw("node-list-request", log.Fields{"path": path, "hash": hash, "depth": depth, "deep": deep, "txid": txid})
-	if deep {
-		depth = -1
-	}
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-
-	var branch *Branch
-	var rev Revision
-
-	if branch = n.GetBranch(txid); txid == "" || branch == nil {
-		branch = n.GetBranch(NONE)
-	}
-
-	if hash != "" {
-		rev = branch.GetRevision(hash)
-	} else {
-		rev = branch.GetLatest()
-	}
-
-	var result interface{}
-	var prList []interface{}
-	if pr := rev.LoadFromPersistence(ctx, path, txid, nil); pr != nil {
-		for _, revEntry := range pr {
-			prList = append(prList, revEntry.GetData())
-		}
-		result = prList
-	}
-
-	return result
-}
-
-// Get retrieves the data from a node tree that resides at the specified path
-func (n *node) Get(ctx context.Context, path string, hash string, depth int, reconcile bool, txid string) interface{} {
-	n.mutex.Lock()
-	defer n.mutex.Unlock()
-
-	log.Debugw("node-get-request", log.Fields{"path": path, "hash": hash, "depth": depth, "reconcile": reconcile, "txid": txid})
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-
-	var branch *Branch
-	var rev Revision
-
-	if branch = n.GetBranch(txid); txid == "" || branch == nil {
-		branch = n.GetBranch(NONE)
-	}
-
-	if hash != "" {
-		rev = branch.GetRevision(hash)
-	} else {
-		rev = branch.GetLatest()
-	}
-
-	var result interface{}
-
-	// If there is no request to reconcile, try to get it from memory
-	if !reconcile {
-		// Try to find an entry matching the path value from one of these sources
-		// 1.  Start with the cache which stores revisions by watch names
-		// 2.  Then look in the revision tree, especially if it's a sub-path such as /devices/1234/flows
-		// 3.  Move on to the KV store if that path cannot be found or if the entry has expired
-		if entry, exists := GetRevCache().Get(path); exists && entry.(Revision) != nil {
-			entryAge := time.Now().Sub(entry.(Revision).GetLastUpdate()).Nanoseconds() / int64(time.Millisecond)
-			if entryAge < DataRefreshPeriod {
-				log.Debugw("using-cache-entry", log.Fields{
-					"path": path,
-					"hash": hash,
-					"age":  entryAge,
-				})
-				return proto.Clone(entry.(Revision).GetData().(proto.Message))
-			} else {
-				log.Debugw("cache-entry-expired", log.Fields{"path": path, "hash": hash, "age": entryAge})
-			}
-		} else if result = n.getPath(ctx, rev.GetBranch().GetLatest(), path, depth); result != nil && reflect.ValueOf(result).IsValid() && !reflect.ValueOf(result).IsNil() {
-			log.Debugw("using-rev-tree-entry", log.Fields{"path": path, "hash": hash, "depth": depth, "reconcile": reconcile, "txid": txid})
-			return result
-		} else {
-			log.Debugw("not-using-cache-entry", log.Fields{
-				"path": path,
-				"hash": hash, "depth": depth,
-				"reconcile": reconcile,
-				"txid":      txid,
-			})
-		}
-	} else {
-		log.Debugw("reconcile-requested", log.Fields{
-			"path":      path,
-			"hash":      hash,
-			"reconcile": reconcile,
-		})
-	}
-
-	// If we got to this point, we are either trying to reconcile with the db
-	// or we simply failed at getting information from memory
-	if n.Root.KvStore != nil {
-		if pr := rev.LoadFromPersistence(ctx, path, txid, nil); pr != nil && len(pr) > 0 {
-			// Did we receive a single or multiple revisions?
-			if len(pr) > 1 {
-				var revs []interface{}
-				for _, revEntry := range pr {
-					revs = append(revs, revEntry.GetData())
-				}
-				result = revs
-			} else {
-				result = pr[0].GetData()
-			}
-		}
-	}
-
-	return result
-}
-
-//getPath traverses the specified path and retrieves the data associated to it
-func (n *node) getPath(ctx context.Context, rev Revision, path string, depth int) interface{} {
-	if path == "" {
-		return n.getData(rev, depth)
-	}
-
-	partition := strings.SplitN(path, "/", 2)
-	name := partition[0]
-
-	if len(partition) < 2 {
-		path = ""
-	} else {
-		path = partition[1]
-	}
-
-	names := ChildrenFields(n.Type)
-	field := names[name]
-
-	if field != nil && field.IsContainer {
-		children := make([]Revision, len(rev.GetChildren(name)))
-		copy(children, rev.GetChildren(name))
-
-		if field.Key != "" {
-			if path != "" {
-				partition = strings.SplitN(path, "/", 2)
-				key := partition[0]
-				path = ""
-				keyValue := field.KeyFromStr(key)
-				if _, childRev := n.findRevByKey(children, field.Key, keyValue); childRev == nil {
-					return nil
-				} else {
-					childNode := childRev.GetNode()
-					return childNode.getPath(ctx, childRev, path, depth)
-				}
-			} else {
-				var response []interface{}
-				for _, childRev := range children {
-					childNode := childRev.GetNode()
-					value := childNode.getData(childRev, depth)
-					response = append(response, value)
-				}
-				return response
-			}
-		} else {
-			var response []interface{}
-			if path != "" {
-				// TODO: raise error
-				return response
-			}
-			for _, childRev := range children {
-				childNode := childRev.GetNode()
-				value := childNode.getData(childRev, depth)
-				response = append(response, value)
-			}
-			return response
-		}
-	} else if children := rev.GetChildren(name); children != nil && len(children) > 0 {
-		childRev := children[0]
-		childNode := childRev.GetNode()
-		return childNode.getPath(ctx, childRev, path, depth)
-	}
-
-	return nil
-}
-
-// getData retrieves the data from a node revision
-func (n *node) getData(rev Revision, depth int) interface{} {
-	msg := rev.GetBranch().GetLatest().Get(depth)
-	var modifiedMsg interface{}
-
-	if n.GetProxy() != nil {
-		log.Debugw("invoking-get-callbacks", log.Fields{"data": msg})
-		if modifiedMsg = n.GetProxy().InvokeCallbacks(GET, false, msg); modifiedMsg != nil {
-			msg = modifiedMsg
-		}
-
-	}
-
-	return msg
-}
-
-// Update changes the content of a node at the specified path with the provided data
-func (n *node) Update(ctx context.Context, path string, data interface{}, strict bool, txid string, makeBranch MakeBranchFunction) Revision {
-	n.mutex.Lock()
-	defer n.mutex.Unlock()
-
-	log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid": txid})
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-
-	var branch *Branch
-	if txid == "" {
-		branch = n.GetBranch(NONE)
-	} else if branch = n.GetBranch(txid); branch == nil {
-		branch = makeBranch(n)
-	}
-
-	if branch.GetLatest() != nil {
-		log.Debugf("Branch data : %+v, Passed data: %+v", branch.GetLatest().GetData(), data)
-	}
-	if path == "" {
-		return n.doUpdate(ctx, branch, data, strict)
-	}
-
-	rev := branch.GetLatest()
-
-	partition := strings.SplitN(path, "/", 2)
-	name := partition[0]
-
-	if len(partition) < 2 {
-		path = ""
-	} else {
-		path = partition[1]
-	}
-
-	field := ChildrenFields(n.Type)[name]
-	var children []Revision
-
-	if field == nil {
-		return n.doUpdate(ctx, branch, data, strict)
-	}
-
-	if field.IsContainer {
-		if path == "" {
-			log.Errorf("cannot update a list")
-		} else if field.Key != "" {
-			partition := strings.SplitN(path, "/", 2)
-			key := partition[0]
-			if len(partition) < 2 {
-				path = ""
-			} else {
-				path = partition[1]
-			}
-			keyValue := field.KeyFromStr(key)
-
-			children = make([]Revision, len(rev.GetChildren(name)))
-			copy(children, rev.GetChildren(name))
-
-			idx, childRev := n.findRevByKey(children, field.Key, keyValue)
-
-			if childRev == nil {
-				log.Debugw("child-revision-is-nil", log.Fields{"key": keyValue})
-				return branch.GetLatest()
-			}
-
-			childNode := childRev.GetNode()
-
-			// Save proxy in child node to ensure callbacks are called later on
-			// only assign in cases of non sub-folder proxies, i.e. "/"
-			if childNode.Proxy == nil && n.Proxy != nil && n.GetProxy().getFullPath() == "" {
-				childNode.Proxy = n.Proxy
-			}
-
-			newChildRev := childNode.Update(ctx, path, data, strict, txid, makeBranch)
-
-			if newChildRev.GetHash() == childRev.GetHash() {
-				if newChildRev != childRev {
-					log.Debug("clear-hash - %s %+v", newChildRev.GetHash(), newChildRev)
-					newChildRev.ClearHash()
-				}
-				log.Debugw("child-revisions-have-matching-hash", log.Fields{"hash": childRev.GetHash(), "key": keyValue})
-				return branch.GetLatest()
-			}
-
-			_, newKey := GetAttributeValue(newChildRev.GetData(), field.Key, 0)
-
-			_newKeyType := fmt.Sprintf("%s", newKey)
-			_keyValueType := fmt.Sprintf("%s", keyValue)
-
-			if _newKeyType != _keyValueType {
-				log.Errorf("cannot change key field")
-			}
-
-			// Prefix the hash value with the data type (e.g. devices, logical_devices, adapters)
-			newChildRev.SetName(name + "/" + _keyValueType)
-
-			branch.LatestLock.Lock()
-			defer branch.LatestLock.Unlock()
-
-			if idx >= 0 {
-				children[idx] = newChildRev
-			} else {
-				children = append(children, newChildRev)
-			}
-
-			updatedRev := rev.UpdateChildren(ctx, name, children, branch)
-
-			n.makeLatest(branch, updatedRev, nil)
-			updatedRev.ChildDrop(name, childRev.GetHash())
-
-			return newChildRev
-
-		} else {
-			log.Errorf("cannot index into container with no keys")
-		}
-	} else {
-		childRev := rev.GetChildren(name)[0]
-		childNode := childRev.GetNode()
-		newChildRev := childNode.Update(ctx, path, data, strict, txid, makeBranch)
-
-		branch.LatestLock.Lock()
-		defer branch.LatestLock.Unlock()
-
-		updatedRev := rev.UpdateChildren(ctx, name, []Revision{newChildRev}, branch)
-		n.makeLatest(branch, updatedRev, nil)
-
-		updatedRev.ChildDrop(name, childRev.GetHash())
-
-		return newChildRev
-	}
-
-	return nil
-}
-
-func (n *node) doUpdate(ctx context.Context, branch *Branch, data interface{}, strict bool) Revision {
-	log.Debugw("comparing-types", log.Fields{"expected": reflect.ValueOf(n.Type).Type(), "actual": reflect.TypeOf(data)})
-
-	if reflect.TypeOf(data) != reflect.ValueOf(n.Type).Type() {
-		// TODO raise error
-		log.Errorw("types-do-not-match: %+v", log.Fields{"actual": reflect.TypeOf(data), "expected": n.Type})
-		return nil
-	}
-
-	// TODO: validate that this actually works
-	//if n.hasChildren(data) {
-	//	return nil
-	//}
-
-	if n.GetProxy() != nil {
-		log.Debug("invoking proxy PRE_UPDATE Callbacks")
-		n.GetProxy().InvokeCallbacks(PRE_UPDATE, false, branch.GetLatest(), data)
-	}
-
-	if branch.GetLatest().GetData().(proto.Message).String() != data.(proto.Message).String() {
-		if strict {
-			// TODO: checkAccessViolations(data, Branch.GetLatest.data)
-			log.Debugf("checking access violations")
-		}
-
-		rev := branch.GetLatest().UpdateData(ctx, data, branch)
-		changes := []ChangeTuple{{POST_UPDATE, branch.GetLatest().GetData(), rev.GetData()}}
-		n.makeLatest(branch, rev, changes)
-
-		return rev
-	}
-	return branch.GetLatest()
-}
-
-// Add inserts a new node at the specified path with the provided data
-func (n *node) Add(ctx context.Context, path string, data interface{}, txid string, makeBranch MakeBranchFunction) Revision {
-	n.mutex.Lock()
-	defer n.mutex.Unlock()
-
-	log.Debugw("node-add-request", log.Fields{"path": path, "txid": txid})
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-	if path == "" {
-		// TODO raise error
-		log.Errorf("cannot add for non-container mode")
-		return nil
-	}
-
-	var branch *Branch
-	if txid == "" {
-		branch = n.GetBranch(NONE)
-	} else if branch = n.GetBranch(txid); branch == nil {
-		branch = makeBranch(n)
-	}
-
-	rev := branch.GetLatest()
-
-	partition := strings.SplitN(path, "/", 2)
-	name := partition[0]
-
-	if len(partition) < 2 {
-		path = ""
-	} else {
-		path = partition[1]
-	}
-
-	field := ChildrenFields(n.Type)[name]
-
-	var children []Revision
-
-	if field.IsContainer {
-		if path == "" {
-			if field.Key != "" {
-				if n.GetProxy() != nil {
-					log.Debug("invoking proxy PRE_ADD Callbacks")
-					n.GetProxy().InvokeCallbacks(PRE_ADD, false, data)
-				}
-
-				children = make([]Revision, len(rev.GetChildren(name)))
-				copy(children, rev.GetChildren(name))
-
-				_, key := GetAttributeValue(data, field.Key, 0)
-
-				if _, exists := n.findRevByKey(children, field.Key, key.String()); exists != nil {
-					// TODO raise error
-					log.Warnw("duplicate-key-found", log.Fields{"key": key.String()})
-					return exists
-				}
-				childRev := n.MakeNode(data, "").Latest()
-
-				// Prefix the hash with the data type (e.g. devices, logical_devices, adapters)
-				childRev.SetName(name + "/" + key.String())
-
-				branch.LatestLock.Lock()
-				defer branch.LatestLock.Unlock()
-
-				children = append(children, childRev)
-
-				updatedRev := rev.UpdateChildren(ctx, name, children, branch)
-				changes := []ChangeTuple{{POST_ADD, nil, childRev.GetData()}}
-				childRev.SetupWatch(childRev.GetName())
-
-				n.makeLatest(branch, updatedRev, changes)
-
-				return childRev
-			}
-			log.Errorf("cannot add to non-keyed container")
-
-		} else if field.Key != "" {
-			partition := strings.SplitN(path, "/", 2)
-			key := partition[0]
-			if len(partition) < 2 {
-				path = ""
-			} else {
-				path = partition[1]
-			}
-			keyValue := field.KeyFromStr(key)
-
-			children = make([]Revision, len(rev.GetChildren(name)))
-			copy(children, rev.GetChildren(name))
-
-			idx, childRev := n.findRevByKey(children, field.Key, keyValue)
-
-			if childRev == nil {
-				return branch.GetLatest()
-			}
-
-			childNode := childRev.GetNode()
-			newChildRev := childNode.Add(ctx, path, data, txid, makeBranch)
-
-			// Prefix the hash with the data type (e.g. devices, logical_devices, adapters)
-			newChildRev.SetName(name + "/" + keyValue.(string))
-
-			branch.LatestLock.Lock()
-			defer branch.LatestLock.Unlock()
-
-			if idx >= 0 {
-				children[idx] = newChildRev
-			} else {
-				children = append(children, newChildRev)
-			}
-
-			updatedRev := rev.UpdateChildren(ctx, name, children, branch)
-			n.makeLatest(branch, updatedRev, nil)
-
-			updatedRev.ChildDrop(name, childRev.GetHash())
-
-			return newChildRev
-		} else {
-			log.Errorf("cannot add to non-keyed container")
-		}
-	} else {
-		log.Errorf("cannot add to non-container field")
-	}
-
-	return nil
-}
-
-// Remove eliminates a node at the specified path
-func (n *node) Remove(ctx context.Context, path string, txid string, makeBranch MakeBranchFunction) Revision {
-	n.mutex.Lock()
-	defer n.mutex.Unlock()
-
-	log.Debugw("node-remove-request", log.Fields{"path": path, "txid": txid, "makeBranch": makeBranch})
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-	if path == "" {
-		// TODO raise error
-		log.Errorf("cannot remove for non-container mode")
-	}
-	var branch *Branch
-	if txid == "" {
-		branch = n.GetBranch(NONE)
-	} else if branch = n.GetBranch(txid); branch == nil {
-		branch = makeBranch(n)
-	}
-
-	rev := branch.GetLatest()
-
-	partition := strings.SplitN(path, "/", 2)
-	name := partition[0]
-	if len(partition) < 2 {
-		path = ""
-	} else {
-		path = partition[1]
-	}
-
-	field := ChildrenFields(n.Type)[name]
-	var children []Revision
-	postAnnouncement := []ChangeTuple{}
-
-	if field.IsContainer {
-		if path == "" {
-			log.Errorw("cannot-remove-without-key", log.Fields{"name": name, "key": path})
-		} else if field.Key != "" {
-			partition := strings.SplitN(path, "/", 2)
-			key := partition[0]
-			if len(partition) < 2 {
-				path = ""
-			} else {
-				path = partition[1]
-			}
-
-			keyValue := field.KeyFromStr(key)
-			children = make([]Revision, len(rev.GetChildren(name)))
-			copy(children, rev.GetChildren(name))
-
-			if path != "" {
-				if idx, childRev := n.findRevByKey(children, field.Key, keyValue); childRev != nil {
-					childNode := childRev.GetNode()
-					if childNode.Proxy == nil {
-						childNode.Proxy = n.Proxy
-					}
-					newChildRev := childNode.Remove(ctx, path, txid, makeBranch)
-
-					branch.LatestLock.Lock()
-					defer branch.LatestLock.Unlock()
-
-					if idx >= 0 {
-						children[idx] = newChildRev
-					} else {
-						children = append(children, newChildRev)
-					}
-
-					rev.SetChildren(name, children)
-					branch.GetLatest().Drop(txid, false)
-					n.makeLatest(branch, rev, nil)
-				}
-				return branch.GetLatest()
-			}
-
-			if idx, childRev := n.findRevByKey(children, field.Key, keyValue); childRev != nil && idx >= 0 {
-				if n.GetProxy() != nil {
-					data := childRev.GetData()
-					n.GetProxy().InvokeCallbacks(PRE_REMOVE, false, data)
-					postAnnouncement = append(postAnnouncement, ChangeTuple{POST_REMOVE, data, nil})
-				} else {
-					postAnnouncement = append(postAnnouncement, ChangeTuple{POST_REMOVE, childRev.GetData(), nil})
-				}
-
-				childRev.StorageDrop(txid, true)
-				GetRevCache().Delete(childRev.GetName())
-
-				branch.LatestLock.Lock()
-				defer branch.LatestLock.Unlock()
-
-				children = append(children[:idx], children[idx+1:]...)
-				rev.SetChildren(name, children)
-
-				branch.GetLatest().Drop(txid, false)
-				n.makeLatest(branch, rev, postAnnouncement)
-
-				return rev
-			} else {
-				log.Errorw("failed-to-find-revision", log.Fields{"name": name, "key": keyValue.(string)})
-			}
-		}
-		log.Errorw("cannot-add-to-non-keyed-container", log.Fields{"name": name, "path": path, "fieldKey": field.Key})
-
-	} else {
-		log.Errorw("cannot-add-to-non-container-field", log.Fields{"name": name, "path": path})
-	}
-
-	return nil
-}
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Branching ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-// MakeBranchFunction is a type for function references intented to create a branch
-type MakeBranchFunction func(*node) *Branch
-
-// MakeBranch creates a new branch for the provided transaction id
-func (n *node) MakeBranch(txid string) *Branch {
-	branchPoint := n.GetBranch(NONE).GetLatest()
-	branch := NewBranch(n, txid, branchPoint, true)
-	n.SetBranch(txid, branch)
-	return branch
-}
-
-// DeleteBranch removes a branch with the specified id
-func (n *node) DeleteBranch(txid string) {
-	delete(n.Branches, txid)
-}
-
-func (n *node) mergeChild(txid string, dryRun bool) func(Revision) Revision {
-	f := func(rev Revision) Revision {
-		childBranch := rev.GetBranch()
-
-		if childBranch.Txid == txid {
-			rev, _ = childBranch.Node.MergeBranch(txid, dryRun)
-		}
-
-		return rev
-	}
-	return f
-}
-
-// MergeBranch will integrate the contents of a transaction branch within the latest branch of a given node
-func (n *node) MergeBranch(txid string, dryRun bool) (Revision, error) {
-	srcBranch := n.GetBranch(txid)
-	dstBranch := n.GetBranch(NONE)
-
-	forkRev := srcBranch.Origin
-	srcRev := srcBranch.GetLatest()
-	dstRev := dstBranch.GetLatest()
-
-	rev, changes := Merge3Way(forkRev, srcRev, dstRev, n.mergeChild(txid, dryRun), dryRun)
-
-	if !dryRun {
-		if rev != nil {
-			rev.SetName(dstRev.GetName())
-			n.makeLatest(dstBranch, rev, changes)
-		}
-		n.DeleteBranch(txid)
-	}
-
-	// TODO: return proper error when one occurs
-	return rev, nil
-}
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Diff utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-//func (n *node) diff(hash1, hash2, txid string) {
-//	branch := n.Branches[txid]
-//	rev1 := branch.GetHash(hash1)
-//	rev2 := branch.GetHash(hash2)
-//
-//	if rev1.GetHash() == rev2.GetHash() {
-//		// empty patch
-//	} else {
-//		// translate data to json and generate patch
-//		patch, err := jsonpatch.MakePatch(rev1.GetData(), rev2.GetData())
-//		patch.
-//	}
-//}
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tag utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-// TODO: is tag mgmt used in the python implementation? Need to validate
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Internals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-func (n *node) hasChildren(data interface{}) bool {
-	for fieldName, field := range ChildrenFields(n.Type) {
-		_, fieldValue := GetAttributeValue(data, fieldName, 0)
-
-		if (field.IsContainer && fieldValue.Len() > 0) || !fieldValue.IsNil() {
-			log.Error("cannot update external children")
-			return true
-		}
-	}
-
-	return false
-}
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ node Proxy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-// CreateProxy returns a reference to a sub-tree of the data model
-func (n *node) CreateProxy(ctx context.Context, path string, exclusive bool) *Proxy {
-	return n.createProxy(ctx, path, path, n, exclusive)
-}
-
-func (n *node) createProxy(ctx context.Context, path string, fullPath string, parentNode *node, exclusive bool) *Proxy {
-	log.Debugw("node-create-proxy", log.Fields{
-		"node-type":        reflect.ValueOf(n.Type).Type(),
-		"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-		"path":             path,
-		"fullPath":         fullPath,
-	})
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-	if path == "" {
-		return n.makeProxy(path, fullPath, parentNode, exclusive)
-	}
-
-	rev := n.GetBranch(NONE).GetLatest()
-	partition := strings.SplitN(path, "/", 2)
-	name := partition[0]
-	var nodeType interface{}
-	if len(partition) < 2 {
-		path = ""
-		nodeType = n.Type
-	} else {
-		path = partition[1]
-		nodeType = parentNode.Type
-	}
-
-	field := ChildrenFields(nodeType)[name]
-
-	if field != nil {
-		if field.IsContainer {
-			log.Debugw("container-field", log.Fields{
-				"node-type":        reflect.ValueOf(n.Type).Type(),
-				"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-				"path":             path,
-				"name":             name,
-			})
-			if path == "" {
-				log.Debugw("folder-proxy", log.Fields{
-					"node-type":        reflect.ValueOf(n.Type).Type(),
-					"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-					"fullPath":         fullPath,
-					"name":             name,
-				})
-				newNode := n.MakeNode(reflect.New(field.ClassType.Elem()).Interface(), "")
-				return newNode.makeProxy(path, fullPath, parentNode, exclusive)
-			} else if field.Key != "" {
-				log.Debugw("key-proxy", log.Fields{
-					"node-type":        reflect.ValueOf(n.Type).Type(),
-					"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-					"fullPath":         fullPath,
-					"name":             name,
-				})
-				partition := strings.SplitN(path, "/", 2)
-				key := partition[0]
-				if len(partition) < 2 {
-					path = ""
-				} else {
-					path = partition[1]
-				}
-				keyValue := field.KeyFromStr(key)
-				var children []Revision
-				children = make([]Revision, len(rev.GetChildren(name)))
-				copy(children, rev.GetChildren(name))
-
-				var childRev Revision
-				if _, childRev = n.findRevByKey(children, field.Key, keyValue); childRev != nil {
-					log.Debugw("found-revision-matching-key-in-memory", log.Fields{
-						"node-type":        reflect.ValueOf(n.Type).Type(),
-						"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-						"fullPath":         fullPath,
-						"name":             name,
-					})
-				} else if revs := n.GetBranch(NONE).GetLatest().LoadFromPersistence(ctx, fullPath, "", nil); revs != nil && len(revs) > 0 {
-					log.Debugw("found-revision-matching-key-in-db", log.Fields{
-						"node-type":        reflect.ValueOf(n.Type).Type(),
-						"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-						"fullPath":         fullPath,
-						"name":             name,
-					})
-					childRev = revs[0]
-				} else {
-					log.Debugw("no-revision-matching-key", log.Fields{
-						"node-type":        reflect.ValueOf(n.Type).Type(),
-						"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-						"fullPath":         fullPath,
-						"name":             name,
-					})
-				}
-				if childRev != nil {
-					childNode := childRev.GetNode()
-					return childNode.createProxy(ctx, path, fullPath, n, exclusive)
-				}
-			} else {
-				log.Errorw("cannot-access-index-of-empty-container", log.Fields{
-					"node-type":        reflect.ValueOf(n.Type).Type(),
-					"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-					"path":             path,
-					"name":             name,
-				})
-			}
-		} else {
-			log.Debugw("non-container-field", log.Fields{
-				"node-type":        reflect.ValueOf(n.Type).Type(),
-				"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-				"path":             path,
-				"name":             name,
-			})
-			childRev := rev.GetChildren(name)[0]
-			childNode := childRev.GetNode()
-			return childNode.createProxy(ctx, path, fullPath, n, exclusive)
-		}
-	} else {
-		log.Debugw("field-object-is-nil", log.Fields{
-			"node-type":        reflect.ValueOf(n.Type).Type(),
-			"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-			"fullPath":         fullPath,
-			"name":             name,
-		})
-	}
-
-	log.Warnw("cannot-create-proxy", log.Fields{
-		"node-type":        reflect.ValueOf(n.Type).Type(),
-		"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-		"path":             path,
-		"fullPath":         fullPath,
-		"latest-rev":       rev.GetHash(),
-	})
-	return nil
-}
-
-func (n *node) makeProxy(path string, fullPath string, parentNode *node, exclusive bool) *Proxy {
-	log.Debugw("node-make-proxy", log.Fields{
-		"node-type":        reflect.ValueOf(n.Type).Type(),
-		"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-		"path":             path,
-		"fullPath":         fullPath,
-	})
-
-	r := &root{
-		node:                  n,
-		Callbacks:             n.Root.GetCallbacks(),
-		NotificationCallbacks: n.Root.GetNotificationCallbacks(),
-		DirtyNodes:            n.Root.DirtyNodes,
-		KvStore:               n.Root.KvStore,
-		Loading:               n.Root.Loading,
-		RevisionClass:         n.Root.RevisionClass,
-	}
-
-	if n.Proxy == nil {
-		log.Debugw("constructing-new-proxy", log.Fields{
-			"node-type":        reflect.ValueOf(n.Type).Type(),
-			"parent-node-type": reflect.ValueOf(parentNode.Type).Type(),
-			"path":             path,
-			"fullPath":         fullPath,
-		})
-		n.Proxy = NewProxy(r, n, parentNode, path, fullPath, exclusive)
-	} else {
-		log.Debugw("node-has-existing-proxy", log.Fields{
-			"node-type":        reflect.ValueOf(n.GetProxy().Node.Type).Type(),
-			"parent-node-type": reflect.ValueOf(n.GetProxy().ParentNode.Type).Type(),
-			"path":             n.GetProxy().Path,
-			"fullPath":         n.GetProxy().FullPath,
-		})
-		if n.GetProxy().Exclusive {
-			log.Error("node is already owned exclusively")
-		}
-	}
-
-	return n.Proxy
-}
-
-func (n *node) makeEventBus() *EventBus {
-	if n.EventBus == nil {
-		n.EventBus = NewEventBus()
-	}
-	return n.EventBus
-}
-
-func (n *node) SetProxy(proxy *Proxy) {
-	n.Proxy = proxy
-}
-
-func (n *node) GetProxy() *Proxy {
-	return n.Proxy
-}
-
-func (n *node) GetBranch(key string) *Branch {
-	if n.Branches != nil {
-		if branch, exists := n.Branches[key]; exists {
-			return branch
-		}
-	}
-	return nil
-}
-
-func (n *node) SetBranch(key string, branch *Branch) {
-	n.Branches[key] = branch
-}
-
-func (n *node) GetRoot() *root {
-	return n.Root
-}
-func (n *node) SetRoot(root *root) {
-	n.Root = root
-}
diff --git a/pkg/db/model/node_test.go b/pkg/db/model/node_test.go
deleted file mode 100644
index 7e0a3ce..0000000
--- a/pkg/db/model/node_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"crypto/md5"
-	"fmt"
-	"github.com/golang/protobuf/ptypes/any"
-	"github.com/opencord/voltha-protos/v2/go/common"
-	"github.com/opencord/voltha-protos/v2/go/openflow_13"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"reflect"
-	"testing"
-)
-
-var (
-	TestNode_Port = []*voltha.Port{
-		{
-			PortNo:     123,
-			Label:      "test-etcd_port-0",
-			Type:       voltha.Port_PON_OLT,
-			AdminState: common.AdminState_ENABLED,
-			OperStatus: common.OperStatus_ACTIVE,
-			DeviceId:   "etcd_port-0-device-id",
-			Peers:      []*voltha.Port_PeerPort{},
-		},
-	}
-
-	TestNode_Device = &voltha.Device{
-		Id:              "Config-SomeNode-01-new-test",
-		Type:            "simulated_olt",
-		Root:            true,
-		ParentId:        "",
-		ParentPortNo:    0,
-		Vendor:          "voltha-test",
-		Model:           "GetLatest-voltha-simulated-olt",
-		HardwareVersion: "1.0.0",
-		FirmwareVersion: "1.0.0",
-		Images:          &voltha.Images{},
-		SerialNumber:    "abcdef-123456",
-		VendorId:        "DEADBEEF-INC",
-		Adapter:         "simulated_olt",
-		Vlan:            1234,
-		Address:         &voltha.Device_HostAndPort{HostAndPort: "1.2.3.4:5555"},
-		ExtraArgs:       "",
-		ProxyAddress:    &voltha.Device_ProxyAddress{},
-		AdminState:      voltha.AdminState_PREPROVISIONED,
-		OperStatus:      common.OperStatus_ACTIVE,
-		Reason:          "",
-		ConnectStatus:   common.ConnectStatus_REACHABLE,
-		Custom:          &any.Any{},
-		Ports:           TestNode_Port,
-		Flows:           &openflow_13.Flows{},
-		FlowGroups:      &openflow_13.FlowGroups{},
-		PmConfigs:       &voltha.PmConfigs{},
-		ImageDownloads:  []*voltha.ImageDownload{},
-	}
-
-	TestNode_Data = TestNode_Device
-
-	TestNode_Txid = fmt.Sprintf("%x", md5.Sum([]byte("node_transaction_id")))
-	TestNode_Root = &root{RevisionClass: reflect.TypeOf(NonPersistedRevision{})}
-)
-
-// Exercise node creation code
-// This test will
-func TestNode_01_NewNode(t *testing.T) {
-	node := NewNode(TestNode_Root, TestNode_Data, false, TestNode_Txid)
-
-	if reflect.ValueOf(node.Type).Type() != reflect.TypeOf(TestNode_Data) {
-		t.Errorf("Node type does not match original data type: %+v", reflect.ValueOf(node.Type).Type())
-	} else if node.GetBranch(TestNode_Txid) == nil || node.GetBranch(TestNode_Txid).Latest == nil {
-		t.Errorf("No branch associated to txid: %s", TestNode_Txid)
-	} else if node.GetBranch(TestNode_Txid).Latest == nil {
-		t.Errorf("Branch has no latest revision : %s", TestNode_Txid)
-	} else if node.GetBranch(TestNode_Txid).GetLatest().GetConfig() == nil {
-		t.Errorf("Latest revision has no assigned data: %+v", node.GetBranch(TestNode_Txid).GetLatest())
-	}
-
-	t.Logf("Created new node successfully : %+v\n", node)
-}
diff --git a/pkg/db/model/non_persisted_revision.go b/pkg/db/model/non_persisted_revision.go
deleted file mode 100644
index 384caed..0000000
--- a/pkg/db/model/non_persisted_revision.go
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"bytes"
-	"context"
-	"crypto/md5"
-	"fmt"
-	"github.com/golang/protobuf/proto"
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/kvstore"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-)
-
-// TODO: Cache logic will have to be revisited to cleanup unused entries in memory (disabled for now)
-//
-type revCacheSingleton struct {
-	sync.RWMutex
-	Cache sync.Map
-}
-
-func (s *revCacheSingleton) Get(path string) (interface{}, bool) {
-	return s.Cache.Load(path)
-}
-func (s *revCacheSingleton) Set(path string, value interface{}) {
-	s.Cache.Store(path, value)
-}
-func (s *revCacheSingleton) Delete(path string) {
-	s.Cache.Delete(path)
-}
-
-var revCacheInstance *revCacheSingleton
-var revCacheOnce sync.Once
-
-func GetRevCache() *revCacheSingleton {
-	revCacheOnce.Do(func() {
-		revCacheInstance = &revCacheSingleton{Cache: sync.Map{}}
-	})
-	return revCacheInstance
-}
-
-type NonPersistedRevision struct {
-	mutex        sync.RWMutex
-	Root         *root
-	Config       *DataRevision
-	childrenLock sync.RWMutex
-	Children     map[string][]Revision
-	Hash         string
-	Branch       *Branch
-	WeakRef      string
-	Name         string
-	lastUpdate   time.Time
-}
-
-func NewNonPersistedRevision(root *root, branch *Branch, data interface{}, children map[string][]Revision) Revision {
-	r := &NonPersistedRevision{}
-	r.Root = root
-	r.Branch = branch
-	r.Config = NewDataRevision(root, data)
-	r.Children = children
-	r.Hash = r.hashContent()
-	return r
-}
-
-func (npr *NonPersistedRevision) SetConfig(config *DataRevision) {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	npr.Config = config
-}
-
-func (npr *NonPersistedRevision) GetConfig() *DataRevision {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	return npr.Config
-}
-
-func (npr *NonPersistedRevision) SetAllChildren(children map[string][]Revision) {
-	npr.childrenLock.Lock()
-	defer npr.childrenLock.Unlock()
-	npr.Children = make(map[string][]Revision)
-
-	for key, value := range children {
-		npr.Children[key] = make([]Revision, len(value))
-		copy(npr.Children[key], value)
-	}
-}
-
-func (npr *NonPersistedRevision) SetChildren(name string, children []Revision) {
-	npr.childrenLock.Lock()
-	defer npr.childrenLock.Unlock()
-
-	npr.Children[name] = make([]Revision, len(children))
-	copy(npr.Children[name], children)
-}
-
-func (npr *NonPersistedRevision) GetAllChildren() map[string][]Revision {
-	npr.childrenLock.Lock()
-	defer npr.childrenLock.Unlock()
-
-	return npr.Children
-}
-
-func (npr *NonPersistedRevision) GetChildren(name string) []Revision {
-	npr.childrenLock.Lock()
-	defer npr.childrenLock.Unlock()
-
-	if _, exists := npr.Children[name]; exists {
-		return npr.Children[name]
-	}
-	return nil
-}
-
-func (npr *NonPersistedRevision) SetHash(hash string) {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	npr.Hash = hash
-}
-
-func (npr *NonPersistedRevision) GetHash() string {
-	//npr.mutex.Lock()
-	//defer npr.mutex.Unlock()
-	return npr.Hash
-}
-
-func (npr *NonPersistedRevision) ClearHash() {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	npr.Hash = ""
-}
-
-func (npr *NonPersistedRevision) GetName() string {
-	//npr.mutex.Lock()
-	//defer npr.mutex.Unlock()
-	return npr.Name
-}
-
-func (npr *NonPersistedRevision) SetName(name string) {
-	//npr.mutex.Lock()
-	//defer npr.mutex.Unlock()
-	npr.Name = name
-}
-func (npr *NonPersistedRevision) SetBranch(branch *Branch) {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	npr.Branch = branch
-}
-
-func (npr *NonPersistedRevision) GetBranch() *Branch {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	return npr.Branch
-}
-
-func (npr *NonPersistedRevision) GetData() interface{} {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	if npr.Config == nil {
-		return nil
-	}
-	return npr.Config.Data
-}
-
-func (npr *NonPersistedRevision) GetNode() *node {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-	return npr.Branch.Node
-}
-
-func (npr *NonPersistedRevision) Finalize(skipOnExist bool) {
-	npr.Hash = npr.hashContent()
-}
-
-// hashContent generates a hash string based on the contents of the revision.
-// The string should be unique to avoid conflicts with other revisions
-func (npr *NonPersistedRevision) hashContent() string {
-	var buffer bytes.Buffer
-	var childrenKeys []string
-
-	if npr.Config != nil {
-		buffer.WriteString(npr.Config.Hash)
-	}
-
-	if npr.Name != "" {
-		buffer.WriteString(npr.Name)
-	}
-
-	for key := range npr.Children {
-		childrenKeys = append(childrenKeys, key)
-	}
-
-	sort.Strings(childrenKeys)
-
-	if len(npr.Children) > 0 {
-		// Loop through sorted Children keys
-		for _, key := range childrenKeys {
-			for _, child := range npr.Children[key] {
-				if child != nil && child.GetHash() != "" {
-					buffer.WriteString(child.GetHash())
-				}
-			}
-		}
-	}
-
-	return fmt.Sprintf("%x", md5.Sum(buffer.Bytes()))[:12]
-}
-
-// Get will retrieve the data for the current revision
-func (npr *NonPersistedRevision) Get(depth int) interface{} {
-	// 1. Clone the data to avoid any concurrent access issues
-	// 2. The current rev might still be pointing to an old config
-	//    thus, force the revision to get its latest value
-	latestRev := npr.GetBranch().GetLatest()
-	originalData := proto.Clone(latestRev.GetData().(proto.Message))
-	data := originalData
-
-	if depth != 0 {
-		// FIXME: Traversing the struct through reflection sometimes corrupts the data.
-		// Unlike the original python implementation, golang structs are not lazy loaded.
-		// Keeping this non-critical logic for now, but Get operations should be forced to
-		// depth=0 to avoid going through the following loop.
-		for fieldName, field := range ChildrenFields(latestRev.GetData()) {
-			childDataName, childDataHolder := GetAttributeValue(data, fieldName, 0)
-			if field.IsContainer {
-				for _, rev := range latestRev.GetChildren(fieldName) {
-					childData := rev.Get(depth - 1)
-					foundEntry := false
-					for i := 0; i < childDataHolder.Len(); i++ {
-						cdh_if := childDataHolder.Index(i).Interface()
-						if cdh_if.(proto.Message).String() == childData.(proto.Message).String() {
-							foundEntry = true
-							break
-						}
-					}
-					if !foundEntry {
-						// avoid duplicates by adding it only if the child was not found in the holder
-						childDataHolder = reflect.Append(childDataHolder, reflect.ValueOf(childData))
-					}
-				}
-			} else {
-				if revs := npr.GetBranch().GetLatest().GetChildren(fieldName); revs != nil && len(revs) > 0 {
-					rev := revs[0]
-					if rev != nil {
-						childData := rev.Get(depth - 1)
-						if reflect.TypeOf(childData) == reflect.TypeOf(childDataHolder.Interface()) {
-							childDataHolder = reflect.ValueOf(childData)
-						}
-					}
-				}
-			}
-			// Merge child data with cloned object
-			reflect.ValueOf(data).Elem().FieldByName(childDataName).Set(childDataHolder)
-		}
-	}
-
-	result := data
-
-	if result != nil {
-		// We need to send back a copy of the retrieved object
-		result = proto.Clone(data.(proto.Message))
-	}
-
-	return result
-}
-
-// UpdateData will refresh the data content of the revision
-func (npr *NonPersistedRevision) UpdateData(ctx context.Context, data interface{}, branch *Branch) Revision {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-
-	log.Debugw("update-data", log.Fields{"hash": npr.GetHash(), "current": npr.Config.Data, "provided": data})
-
-	// Do not update the revision if data is the same
-	if npr.Config.Data != nil && npr.Config.hashData(npr.Root, data) == npr.Config.Hash {
-		log.Debugw("stored-data-matches-latest", log.Fields{"stored": npr.Config.Data, "provided": data})
-		return npr
-	}
-
-	// Construct a new revision based on the current one
-	newRev := NonPersistedRevision{}
-	newRev.Config = NewDataRevision(npr.Root, data)
-	newRev.Hash = npr.Hash
-	newRev.Root = npr.Root
-	newRev.Name = npr.Name
-	newRev.Branch = branch
-	newRev.lastUpdate = npr.lastUpdate
-
-	newRev.Children = make(map[string][]Revision)
-	for entryName, childrenEntry := range branch.GetLatest().GetAllChildren() {
-		newRev.Children[entryName] = append(newRev.Children[entryName], childrenEntry...)
-	}
-
-	newRev.Finalize(false)
-
-	log.Debugw("update-data-complete", log.Fields{"updated": newRev.Config.Data, "provided": data})
-
-	return &newRev
-}
-
-// UpdateChildren will refresh the list of children with the provided ones
-// It will carefully go through the list and ensure that no child is lost
-func (npr *NonPersistedRevision) UpdateChildren(ctx context.Context, name string, children []Revision, branch *Branch) Revision {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-
-	// Construct a new revision based on the current one
-	updatedRev := &NonPersistedRevision{}
-	updatedRev.Config = NewDataRevision(npr.Root, npr.Config.Data)
-	updatedRev.Hash = npr.Hash
-	updatedRev.Branch = branch
-	updatedRev.Name = npr.Name
-	updatedRev.lastUpdate = npr.lastUpdate
-
-	updatedRev.Children = make(map[string][]Revision)
-	for entryName, childrenEntry := range branch.GetLatest().GetAllChildren() {
-		updatedRev.Children[entryName] = append(updatedRev.Children[entryName], childrenEntry...)
-	}
-
-	var updatedChildren []Revision
-
-	// Verify if the map contains already contains an entry matching the name value
-	// If so, we need to retain the contents of that entry and merge them with the provided children revision list
-	if existingChildren := branch.GetLatest().GetChildren(name); existingChildren != nil {
-		// Construct a map of unique child names with the respective index value
-		// for the children in the existing revision as well as the new ones
-		existingNames := make(map[string]int)
-		newNames := make(map[string]int)
-
-		for i, newChild := range children {
-			newNames[newChild.GetName()] = i
-		}
-
-		for i, existingChild := range existingChildren {
-			existingNames[existingChild.GetName()] = i
-
-			// If an existing entry is not in the new list, add it to the updated list, so it is not forgotten
-			if _, exists := newNames[existingChild.GetName()]; !exists {
-				updatedChildren = append(updatedChildren, existingChild)
-			}
-		}
-
-		log.Debugw("existing-children-names", log.Fields{"hash": npr.GetHash(), "names": existingNames})
-
-		// Merge existing and new children
-		for _, newChild := range children {
-			nameIndex, nameExists := existingNames[newChild.GetName()]
-
-			// Does the existing list contain a child with that name?
-			if nameExists {
-				// Check if the data has changed or not
-				if existingChildren[nameIndex].GetData().(proto.Message).String() != newChild.GetData().(proto.Message).String() {
-					log.Debugw("replacing-existing-child", log.Fields{
-						"old-hash": existingChildren[nameIndex].GetHash(),
-						"old-data": existingChildren[nameIndex].GetData(),
-						"new-hash": newChild.GetHash(),
-						"new-data": newChild.GetData(),
-					})
-
-					// replace entry
-					newChild.GetNode().SetRoot(existingChildren[nameIndex].GetNode().GetRoot())
-					updatedChildren = append(updatedChildren, newChild)
-				} else {
-					log.Debugw("keeping-existing-child", log.Fields{
-						"old-hash": existingChildren[nameIndex].GetHash(),
-						"old-data": existingChildren[nameIndex].GetData(),
-						"new-hash": newChild.GetHash(),
-						"new-data": newChild.GetData(),
-					})
-
-					// keep existing entry
-					updatedChildren = append(updatedChildren, existingChildren[nameIndex])
-				}
-			} else {
-				log.Debugw("adding-unknown-child", log.Fields{
-					"hash": newChild.GetHash(),
-					"data": newChild.GetData(),
-				})
-
-				// new entry ... just add it
-				updatedChildren = append(updatedChildren, newChild)
-			}
-		}
-
-		// Save children in new revision
-		updatedRev.SetChildren(name, updatedChildren)
-
-		updatedNames := make(map[string]int)
-		for i, updatedChild := range updatedChildren {
-			updatedNames[updatedChild.GetName()] = i
-		}
-
-		log.Debugw("updated-children-names", log.Fields{"hash": npr.GetHash(), "names": updatedNames})
-
-	} else {
-		// There are no children available, just save the provided ones
-		updatedRev.SetChildren(name, children)
-	}
-
-	updatedRev.Finalize(false)
-
-	return updatedRev
-}
-
-// UpdateAllChildren will replace the current list of children with the provided ones
-func (npr *NonPersistedRevision) UpdateAllChildren(children map[string][]Revision, branch *Branch) Revision {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-
-	newRev := npr
-	newRev.Config = npr.Config
-	newRev.Hash = npr.Hash
-	newRev.Branch = branch
-	newRev.Name = npr.Name
-	newRev.lastUpdate = npr.lastUpdate
-
-	newRev.Children = make(map[string][]Revision)
-	for entryName, childrenEntry := range children {
-		newRev.Children[entryName] = append(newRev.Children[entryName], childrenEntry...)
-	}
-	newRev.Finalize(false)
-
-	return newRev
-}
-
-// Drop is used to indicate when a revision is no longer required
-func (npr *NonPersistedRevision) Drop(txid string, includeConfig bool) {
-	log.Debugw("dropping-revision", log.Fields{"hash": npr.GetHash(), "name": npr.GetName()})
-}
-
-// ChildDrop will remove a child entry matching the provided parameters from the current revision
-func (npr *NonPersistedRevision) ChildDrop(childType string, childHash string) {
-	if childType != "" {
-		children := make([]Revision, len(npr.GetChildren(childType)))
-		copy(children, npr.GetChildren(childType))
-		for i, child := range children {
-			if child.GetHash() == childHash {
-				children = append(children[:i], children[i+1:]...)
-				npr.SetChildren(childType, children)
-				break
-			}
-		}
-	}
-}
-
-/// ChildDropByName will remove a child entry matching the type and name
-func (npr *NonPersistedRevision) ChildDropByName(childName string) {
-	// Extract device type
-	parts := strings.SplitN(childName, "/", 2)
-	childType := parts[0]
-
-	if childType != "" {
-		children := make([]Revision, len(npr.GetChildren(childType)))
-		copy(children, npr.GetChildren(childType))
-		for i, child := range children {
-			if child.GetName() == childName {
-				children = append(children[:i], children[i+1:]...)
-				npr.SetChildren(childType, children)
-				break
-			}
-		}
-	}
-}
-
-func (npr *NonPersistedRevision) SetLastUpdate(ts ...time.Time) {
-	npr.mutex.Lock()
-	defer npr.mutex.Unlock()
-
-	if ts != nil && len(ts) > 0 {
-		npr.lastUpdate = ts[0]
-	} else {
-		npr.lastUpdate = time.Now()
-	}
-}
-
-func (npr *NonPersistedRevision) GetLastUpdate() time.Time {
-	npr.mutex.RLock()
-	defer npr.mutex.RUnlock()
-
-	return npr.lastUpdate
-}
-
-func (npr *NonPersistedRevision) LoadFromPersistence(ctx context.Context, path string, txid string, blobs map[string]*kvstore.KVPair) []Revision {
-	// stub... required by interface
-	return nil
-}
-
-func (npr *NonPersistedRevision) SetupWatch(key string) {
-	// stub ... required by interface
-}
-
-func (npr *NonPersistedRevision) StorageDrop(txid string, includeConfig bool) {
-	// stub ... required by interface
-}
-
-func (npr *NonPersistedRevision) getVersion() int64 {
-	return -1
-}
diff --git a/pkg/db/model/persisted_revision.go b/pkg/db/model/persisted_revision.go
deleted file mode 100644
index 53d93b7..0000000
--- a/pkg/db/model/persisted_revision.go
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"bytes"
-	"compress/gzip"
-	"context"
-	"github.com/golang/protobuf/proto"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/kvstore"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-	"strings"
-	"sync"
-)
-
-// PersistedRevision holds information of revision meant to be saved in a persistent storage
-type PersistedRevision struct {
-	Revision
-	Compress bool
-
-	events       chan *kvstore.Event
-	kvStore      *Backend
-	mutex        sync.RWMutex
-	versionMutex sync.RWMutex
-	Version      int64
-	isStored     bool
-	isWatched    bool
-}
-
-type watchCache struct {
-	Cache sync.Map
-}
-
-var watchCacheInstance *watchCache
-var watchCacheOne sync.Once
-
-func Watches() *watchCache {
-	watchCacheOne.Do(func() {
-		watchCacheInstance = &watchCache{Cache: sync.Map{}}
-	})
-	return watchCacheInstance
-}
-
-// NewPersistedRevision creates a new instance of a PersistentRevision structure
-func NewPersistedRevision(branch *Branch, data interface{}, children map[string][]Revision) Revision {
-	pr := &PersistedRevision{}
-	pr.kvStore = branch.Node.GetRoot().KvStore
-	pr.Version = 1
-	pr.Revision = NewNonPersistedRevision(nil, branch, data, children)
-	return pr
-}
-
-func (pr *PersistedRevision) getVersion() int64 {
-	pr.versionMutex.RLock()
-	defer pr.versionMutex.RUnlock()
-	return pr.Version
-}
-
-func (pr *PersistedRevision) setVersion(version int64) {
-	pr.versionMutex.Lock()
-	defer pr.versionMutex.Unlock()
-	pr.Version = version
-}
-
-// Finalize is responsible of saving the revision in the persistent storage
-func (pr *PersistedRevision) Finalize(skipOnExist bool) {
-	pr.store(skipOnExist)
-}
-
-func (pr *PersistedRevision) store(skipOnExist bool) {
-	if pr.GetBranch().Txid != "" {
-		return
-	}
-
-	log.Debugw("ready-to-store-revision", log.Fields{"hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetData()})
-
-	// clone the revision data to avoid any race conditions with processes
-	// accessing the same data
-	cloned := proto.Clone(pr.GetConfig().Data.(proto.Message))
-
-	if blob, err := proto.Marshal(cloned); err != nil {
-		log.Errorw("problem-to-marshal", log.Fields{"error": err, "hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetData()})
-	} else {
-		if pr.Compress {
-			var b bytes.Buffer
-			w := gzip.NewWriter(&b)
-			w.Write(blob)
-			w.Close()
-			blob = b.Bytes()
-		}
-
-		GetRevCache().Set(pr.GetName(), pr)
-		if err := pr.kvStore.Put(pr.GetName(), blob); err != nil {
-			log.Warnw("problem-storing-revision", log.Fields{"error": err, "hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetConfig().Data})
-		} else {
-			log.Debugw("storing-revision", log.Fields{"hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetConfig().Data, "version": pr.getVersion()})
-			pr.isStored = true
-		}
-	}
-}
-
-func (pr *PersistedRevision) SetupWatch(key string) {
-	if key == "" {
-		log.Debugw("ignoring-watch", log.Fields{"key": key, "revision-hash": pr.GetHash()})
-		return
-	}
-
-	if _, exists := Watches().Cache.LoadOrStore(key+"-"+pr.GetHash(), struct{}{}); exists {
-		return
-	}
-
-	if pr.events == nil {
-		pr.events = make(chan *kvstore.Event)
-
-		log.Debugw("setting-watch-channel", log.Fields{"key": key, "revision-hash": pr.GetHash()})
-
-		pr.SetName(key)
-		pr.events = pr.kvStore.CreateWatch(key)
-	}
-
-	if !pr.isWatched {
-		pr.isWatched = true
-
-		log.Debugw("setting-watch-routine", log.Fields{"key": key, "revision-hash": pr.GetHash()})
-
-		// Start watching
-		go pr.startWatching()
-	}
-}
-
-func (pr *PersistedRevision) startWatching() {
-	log.Debugw("starting-watch", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
-
-StopWatchLoop:
-	for {
-		latestRev := pr.GetBranch().GetLatest()
-
-		select {
-		case event, ok := <-pr.events:
-			if !ok {
-				log.Errorw("event-channel-failure: stopping watch loop", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName()})
-				break StopWatchLoop
-			}
-			log.Debugw("received-event", log.Fields{"type": event.EventType, "watch": latestRev.GetName()})
-
-			switch event.EventType {
-			case kvstore.DELETE:
-				log.Debugw("delete-from-memory", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName()})
-
-				// Remove reference from cache
-				GetRevCache().Delete(latestRev.GetName())
-
-				// Remove reference from parent
-				parent := pr.GetBranch().Node.GetRoot()
-				parent.GetBranch(NONE).Latest.ChildDropByName(latestRev.GetName())
-
-				break StopWatchLoop
-
-			case kvstore.PUT:
-				log.Debugw("update-in-memory", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName()})
-				if latestRev.getVersion() >= event.Version {
-					log.Debugw("skipping-matching-or-older-revision", log.Fields{
-						"watch":          latestRev.GetName(),
-						"watch-version":  event.Version,
-						"latest-version": latestRev.getVersion(),
-					})
-					continue
-				} else {
-					log.Debugw("watch-revision-is-newer", log.Fields{
-						"watch":          latestRev.GetName(),
-						"watch-version":  event.Version,
-						"latest-version": latestRev.getVersion(),
-					})
-				}
-
-				data := reflect.New(reflect.TypeOf(latestRev.GetData()).Elem())
-
-				if err := proto.Unmarshal(event.Value.([]byte), data.Interface().(proto.Message)); err != nil {
-					log.Errorw("failed-to-unmarshal-watch-data", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName(), "error": err})
-				} else {
-					log.Debugw("un-marshaled-watch-data", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName(), "data": data.Interface()})
-
-					var pathLock string
-					var blobs map[string]*kvstore.KVPair
-
-					// The watch reported new persistence data.
-					// Construct an object that will be used to update the memory
-					blobs = make(map[string]*kvstore.KVPair)
-					key, _ := kvstore.ToString(event.Key)
-					blobs[key] = &kvstore.KVPair{
-						Key:     key,
-						Value:   event.Value,
-						Session: "",
-						Lease:   0,
-						Version: event.Version,
-					}
-
-					if latestRev.GetNode().GetProxy() != nil {
-						//
-						// If a proxy exists for this revision, use it to lock access to the path
-						// and prevent simultaneous updates to the object in memory
-						//
-
-						//If the proxy already has a request in progress, then there is no need to process the watch
-						if latestRev.GetNode().GetProxy().GetOperation() != PROXY_NONE {
-							log.Debugw("operation-in-progress", log.Fields{
-								"key":       latestRev.GetHash(),
-								"path":      latestRev.GetNode().GetProxy().getFullPath(),
-								"operation": latestRev.GetNode().GetProxy().operation.String(),
-							})
-							continue
-						}
-
-						pathLock, _ = latestRev.GetNode().GetProxy().parseForControlledPath(latestRev.GetNode().GetProxy().getFullPath())
-
-						// Reserve the path to prevent others to modify while we reload from persistence
-						latestRev.GetNode().GetProxy().GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-						latestRev.GetNode().GetProxy().SetOperation(PROXY_WATCH)
-
-						// Load changes and apply to memory
-						latestRev.LoadFromPersistence(context.Background(), latestRev.GetName(), "", blobs)
-
-						// Release path
-						latestRev.GetNode().GetProxy().GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-
-					} else {
-						// This block should be reached only if coming from a non-proxied request
-						log.Debugw("revision-with-no-proxy", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName()})
-
-						// Load changes and apply to memory
-						latestRev.LoadFromPersistence(context.Background(), latestRev.GetName(), "", blobs)
-					}
-				}
-
-			default:
-				log.Debugw("unhandled-event", log.Fields{"key": latestRev.GetHash(), "watch": latestRev.GetName(), "type": event.EventType})
-			}
-		}
-	}
-
-	Watches().Cache.Delete(pr.GetName() + "-" + pr.GetHash())
-
-	log.Debugw("exiting-watch", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
-}
-
-// UpdateData modifies the information in the data model and saves it in the persistent storage
-func (pr *PersistedRevision) UpdateData(ctx context.Context, data interface{}, branch *Branch) Revision {
-	log.Debugw("updating-persisted-data", log.Fields{"hash": pr.GetHash()})
-
-	newNPR := pr.Revision.UpdateData(ctx, data, branch)
-
-	newPR := &PersistedRevision{
-		Revision:  newNPR,
-		Compress:  pr.Compress,
-		kvStore:   pr.kvStore,
-		events:    pr.events,
-		Version:   pr.getVersion(),
-		isWatched: pr.isWatched,
-	}
-
-	if newPR.GetHash() != pr.GetHash() {
-		newPR.isStored = false
-		pr.Drop(branch.Txid, false)
-		pr.Drop(branch.Txid, false)
-	} else {
-		newPR.isStored = true
-	}
-
-	return newPR
-}
-
-// UpdateChildren modifies the children of a revision and of a specific component and saves it in the persistent storage
-func (pr *PersistedRevision) UpdateChildren(ctx context.Context, name string, children []Revision, branch *Branch) Revision {
-	log.Debugw("updating-persisted-children", log.Fields{"hash": pr.GetHash()})
-
-	newNPR := pr.Revision.UpdateChildren(ctx, name, children, branch)
-
-	newPR := &PersistedRevision{
-		Revision:  newNPR,
-		Compress:  pr.Compress,
-		kvStore:   pr.kvStore,
-		events:    pr.events,
-		Version:   pr.getVersion(),
-		isWatched: pr.isWatched,
-	}
-
-	if newPR.GetHash() != pr.GetHash() {
-		newPR.isStored = false
-		pr.Drop(branch.Txid, false)
-	} else {
-		newPR.isStored = true
-	}
-
-	return newPR
-}
-
-// UpdateAllChildren modifies the children for all components of a revision and saves it in the peristent storage
-func (pr *PersistedRevision) UpdateAllChildren(children map[string][]Revision, branch *Branch) Revision {
-	log.Debugw("updating-all-persisted-children", log.Fields{"hash": pr.GetHash()})
-
-	newNPR := pr.Revision.UpdateAllChildren(children, branch)
-
-	newPR := &PersistedRevision{
-		Revision:  newNPR,
-		Compress:  pr.Compress,
-		kvStore:   pr.kvStore,
-		events:    pr.events,
-		Version:   pr.getVersion(),
-		isWatched: pr.isWatched,
-	}
-
-	if newPR.GetHash() != pr.GetHash() {
-		newPR.isStored = false
-		pr.Drop(branch.Txid, false)
-	} else {
-		newPR.isStored = true
-	}
-
-	return newPR
-}
-
-// Drop takes care of eliminating a revision hash that is no longer needed
-// and its associated config when required
-func (pr *PersistedRevision) Drop(txid string, includeConfig bool) {
-	pr.Revision.Drop(txid, includeConfig)
-}
-
-// Drop takes care of eliminating a revision hash that is no longer needed
-// and its associated config when required
-func (pr *PersistedRevision) StorageDrop(txid string, includeConfig bool) {
-	log.Debugw("dropping-revision", log.Fields{"txid": txid, "hash": pr.GetHash(), "config-hash": pr.GetConfig().Hash})
-
-	pr.mutex.Lock()
-	defer pr.mutex.Unlock()
-	if pr.kvStore != nil && txid == "" {
-		if pr.isStored {
-			if pr.isWatched {
-				pr.kvStore.DeleteWatch(pr.GetName(), pr.events)
-				pr.isWatched = false
-			}
-
-			if err := pr.kvStore.Delete(pr.GetName()); err != nil {
-				log.Errorw("failed-to-remove-revision", log.Fields{"hash": pr.GetHash(), "error": err.Error()})
-			} else {
-				pr.isStored = false
-			}
-		}
-
-	} else {
-		if includeConfig {
-			log.Debugw("attempted-to-remove-transacted-revision-config", log.Fields{"hash": pr.GetConfig().Hash, "txid": txid})
-		}
-		log.Debugw("attempted-to-remove-transacted-revision", log.Fields{"hash": pr.GetHash(), "txid": txid})
-	}
-
-	pr.Revision.Drop(txid, includeConfig)
-}
-
-// verifyPersistedEntry validates if the provided data is available or not in memory and applies updates as required
-func (pr *PersistedRevision) verifyPersistedEntry(ctx context.Context, data interface{}, typeName string, keyName string,
-	keyValue string, txid string, version int64) (response Revision) {
-	// Parent which holds the current node entry
-	parent := pr.GetBranch().Node.GetRoot()
-
-	// Get a copy of the parent's children
-	children := make([]Revision, len(parent.GetBranch(NONE).Latest.GetChildren(typeName)))
-	copy(children, parent.GetBranch(NONE).Latest.GetChildren(typeName))
-
-	// Verify if a child with the provided key value can be found
-	if childIdx, childRev := pr.GetNode().findRevByKey(children, keyName, keyValue); childRev != nil {
-		// A child matching the provided key exists in memory
-		// Verify if the data differs from what was retrieved from persistence
-		// Also check if we are treating a newer revision of the data or not
-		if childRev.GetData().(proto.Message).String() != data.(proto.Message).String() && childRev.getVersion() < version {
-			log.Debugw("revision-data-is-different", log.Fields{
-				"key":               childRev.GetHash(),
-				"name":              childRev.GetName(),
-				"data":              childRev.GetData(),
-				"in-memory-version": childRev.getVersion(),
-				"persisted-version": version,
-			})
-
-			//
-			// Data has changed; replace the child entry and update the parent revision
-			//
-
-			// BEGIN Lock child -- prevent any incoming changes
-			childRev.GetBranch().LatestLock.Lock()
-
-			// Update child
-			updatedChildRev := childRev.UpdateData(ctx, data, childRev.GetBranch())
-
-			updatedChildRev.GetNode().SetProxy(childRev.GetNode().GetProxy())
-			updatedChildRev.SetupWatch(updatedChildRev.GetName())
-			updatedChildRev.SetLastUpdate()
-			updatedChildRev.(*PersistedRevision).setVersion(version)
-
-			// Update cache
-			GetRevCache().Set(updatedChildRev.GetName(), updatedChildRev)
-			childRev.Drop(txid, false)
-
-			childRev.GetBranch().LatestLock.Unlock()
-			// END lock child
-
-			// Update child entry
-			children[childIdx] = updatedChildRev
-
-			// BEGIN lock parent -- Update parent
-			parent.GetBranch(NONE).LatestLock.Lock()
-
-			updatedRev := parent.GetBranch(NONE).GetLatest().UpdateChildren(ctx, typeName, children, parent.GetBranch(NONE))
-			parent.GetBranch(NONE).Node.makeLatest(parent.GetBranch(NONE), updatedRev, nil)
-
-			parent.GetBranch(NONE).LatestLock.Unlock()
-			// END lock parent
-
-			// Drop the previous child revision
-			parent.GetBranch(NONE).Latest.ChildDrop(typeName, childRev.GetHash())
-
-			if updatedChildRev != nil {
-				log.Debugw("verify-persisted-entry--adding-child", log.Fields{
-					"key":  updatedChildRev.GetHash(),
-					"name": updatedChildRev.GetName(),
-					"data": updatedChildRev.GetData(),
-				})
-				response = updatedChildRev
-			}
-		} else {
-			if childRev != nil {
-				log.Debugw("keeping-revision-data", log.Fields{
-					"key":                 childRev.GetHash(),
-					"name":                childRev.GetName(),
-					"data":                childRev.GetData(),
-					"in-memory-version":   childRev.getVersion(),
-					"persistence-version": version,
-				})
-
-				// Update timestamp to reflect when it was last read and to reset tracked timeout
-				childRev.SetLastUpdate()
-				if childRev.getVersion() < version {
-					childRev.(*PersistedRevision).setVersion(version)
-				}
-				GetRevCache().Set(childRev.GetName(), childRev)
-				response = childRev
-			}
-		}
-
-	} else {
-		// There is no available child with that key value.
-		// Create a new child and update the parent revision.
-		log.Debugw("no-such-revision-entry", log.Fields{
-			"key":     keyValue,
-			"name":    typeName,
-			"data":    data,
-			"version": version,
-		})
-
-		// BEGIN child lock
-		pr.GetBranch().LatestLock.Lock()
-
-		// Construct a new child node with the retrieved persistence data
-		childRev = pr.GetBranch().Node.MakeNode(data, txid).Latest(txid)
-
-		// We need to start watching this entry for future changes
-		childRev.SetName(typeName + "/" + keyValue)
-		childRev.SetupWatch(childRev.GetName())
-		childRev.(*PersistedRevision).setVersion(version)
-
-		// Add entry to cache
-		GetRevCache().Set(childRev.GetName(), childRev)
-
-		pr.GetBranch().LatestLock.Unlock()
-		// END child lock
-
-		//
-		// Add the child to the parent revision
-		//
-
-		// BEGIN parent lock
-		parent.GetBranch(NONE).LatestLock.Lock()
-		children = append(children, childRev)
-		updatedRev := parent.GetBranch(NONE).GetLatest().UpdateChildren(ctx, typeName, children, parent.GetBranch(NONE))
-		updatedRev.GetNode().SetProxy(parent.GetBranch(NONE).Node.GetProxy())
-		parent.GetBranch(NONE).Node.makeLatest(parent.GetBranch(NONE), updatedRev, nil)
-		parent.GetBranch(NONE).LatestLock.Unlock()
-		// END parent lock
-
-		// Child entry is valid and can be included in the response object
-		if childRev != nil {
-			log.Debugw("adding-revision-to-response", log.Fields{
-				"key":  childRev.GetHash(),
-				"name": childRev.GetName(),
-				"data": childRev.GetData(),
-			})
-			response = childRev
-		}
-	}
-
-	return response
-}
-
-// LoadFromPersistence retrieves data from kv store at the specified location and refreshes the memory
-// by adding missing entries, updating changed entries and ignoring unchanged ones
-func (pr *PersistedRevision) LoadFromPersistence(ctx context.Context, path string, txid string, blobs map[string]*kvstore.KVPair) []Revision {
-	pr.mutex.Lock()
-	defer pr.mutex.Unlock()
-
-	log.Debugw("loading-from-persistence", log.Fields{"path": path, "txid": txid})
-
-	var response []Revision
-
-	for strings.HasPrefix(path, "/") {
-		path = path[1:]
-	}
-
-	if pr.kvStore != nil && path != "" {
-		if blobs == nil || len(blobs) == 0 {
-			log.Debugw("retrieve-from-kv", log.Fields{"path": path, "txid": txid})
-			blobs, _ = pr.kvStore.List(path)
-		}
-
-		partition := strings.SplitN(path, "/", 2)
-		name := partition[0]
-
-		var nodeType interface{}
-		if len(partition) < 2 {
-			path = ""
-			nodeType = pr.GetBranch().Node.Type
-		} else {
-			path = partition[1]
-			nodeType = pr.GetBranch().Node.GetRoot().Type
-		}
-
-		field := ChildrenFields(nodeType)[name]
-
-		if field != nil && field.IsContainer {
-			log.Debugw("parsing-data-blobs", log.Fields{
-				"path": path,
-				"name": name,
-				"size": len(blobs),
-			})
-
-			for _, blob := range blobs {
-				output := blob.Value.([]byte)
-
-				data := reflect.New(field.ClassType.Elem())
-
-				if err := proto.Unmarshal(output, data.Interface().(proto.Message)); err != nil {
-					log.Errorw("failed-to-unmarshal", log.Fields{
-						"path":  path,
-						"txid":  txid,
-						"error": err,
-					})
-				} else if path == "" {
-					if field.Key != "" {
-						log.Debugw("no-path-with-container-key", log.Fields{
-							"path": path,
-							"txid": txid,
-							"data": data.Interface(),
-						})
-
-						// Retrieve the key identifier value from the data structure
-						// based on the field's key attribute
-						_, key := GetAttributeValue(data.Interface(), field.Key, 0)
-
-						if entry := pr.verifyPersistedEntry(ctx, data.Interface(), name, field.Key, key.String(), txid, blob.Version); entry != nil {
-							response = append(response, entry)
-						}
-					} else {
-						log.Debugw("path-with-no-container-key", log.Fields{
-							"path": path,
-							"txid": txid,
-							"data": data.Interface(),
-						})
-					}
-
-				} else if field.Key != "" {
-					log.Debugw("path-with-container-key", log.Fields{
-						"path": path,
-						"txid": txid,
-						"data": data.Interface(),
-					})
-					// The request is for a specific entry/id
-					partition := strings.SplitN(path, "/", 2)
-					key := partition[0]
-					if len(partition) < 2 {
-						path = ""
-					} else {
-						path = partition[1]
-					}
-					keyValue := field.KeyFromStr(key)
-
-					if entry := pr.verifyPersistedEntry(ctx, data.Interface(), name, field.Key, keyValue.(string), txid, blob.Version); entry != nil {
-						response = append(response, entry)
-					}
-				}
-			}
-
-			log.Debugw("no-more-data-blobs", log.Fields{"path": path, "name": name})
-		} else {
-			log.Debugw("cannot-process-field", log.Fields{
-				"type": pr.GetBranch().Node.Type,
-				"name": name,
-			})
-		}
-	}
-
-	return response
-}
diff --git a/pkg/db/model/profiling.go b/pkg/db/model/profiling.go
deleted file mode 100644
index f8e9f7a..0000000
--- a/pkg/db/model/profiling.go
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"sync"
-)
-
-// Profiling is used to store performance details collected at runtime
-type profiling struct {
-	sync.RWMutex
-	DatabaseRetrieveTime  float64
-	DatabaseRetrieveCount int
-	InMemoryModelTime     float64
-	InMemoryModelCount    int
-	InMemoryProcessTime   float64
-	DatabaseStoreTime     float64
-	InMemoryLockTime      float64
-	InMemoryLockCount     int
-}
-
-var profilingInstance *profiling
-var profilingOnce sync.Once
-
-// GetProfiling returns a singleton instance of the Profiling structure
-func GetProfiling() *profiling {
-	profilingOnce.Do(func() {
-		profilingInstance = &profiling{}
-	})
-	return profilingInstance
-}
-
-// AddToDatabaseRetrieveTime appends a time period to retrieve data from the database
-func (p *profiling) AddToDatabaseRetrieveTime(period float64) {
-	p.Lock()
-	defer p.Unlock()
-
-	p.DatabaseRetrieveTime += period
-	p.DatabaseRetrieveCount++
-}
-
-// AddToInMemoryModelTime appends a time period to construct/deconstruct data in memory
-func (p *profiling) AddToInMemoryModelTime(period float64) {
-	p.Lock()
-	defer p.Unlock()
-
-	p.InMemoryModelTime += period
-	p.InMemoryModelCount++
-}
-
-// AddToInMemoryProcessTime appends a time period to process data
-func (p *profiling) AddToInMemoryProcessTime(period float64) {
-	p.Lock()
-	defer p.Unlock()
-
-	p.InMemoryProcessTime += period
-}
-
-// AddToDatabaseStoreTime appends a time period to store data in the database
-func (p *profiling) AddToDatabaseStoreTime(period float64) {
-	p.Lock()
-	defer p.Unlock()
-
-	p.DatabaseStoreTime += period
-}
-
-// AddToInMemoryLockTime appends a time period when a code block was locked
-func (p *profiling) AddToInMemoryLockTime(period float64) {
-	p.Lock()
-	defer p.Unlock()
-
-	p.InMemoryLockTime += period
-	p.InMemoryLockCount++
-}
-
-// Reset initializes the profile counters
-func (p *profiling) Reset() {
-	p.Lock()
-	defer p.Unlock()
-
-	p.DatabaseRetrieveTime = 0
-	p.DatabaseRetrieveCount = 0
-	p.InMemoryModelTime = 0
-	p.InMemoryModelCount = 0
-	p.InMemoryProcessTime = 0
-	p.DatabaseStoreTime = 0
-	p.InMemoryLockTime = 0
-	p.InMemoryLockCount = 0
-}
-
-// Report will provide the current profile counter status
-func (p *profiling) Report() {
-	p.Lock()
-	defer p.Unlock()
-
-	log.Infof("[ Profiling Report ]")
-	log.Infof("Database Retrieval : %f", p.DatabaseRetrieveTime)
-	log.Infof("Database Retrieval Count : %d", p.DatabaseRetrieveCount)
-	log.Infof("Avg Database Retrieval : %f", p.DatabaseRetrieveTime/float64(p.DatabaseRetrieveCount))
-	log.Infof("In-Memory Modeling : %f", p.InMemoryModelTime)
-	log.Infof("In-Memory Modeling Count: %d", p.InMemoryModelCount)
-	log.Infof("Avg In-Memory Modeling : %f", p.InMemoryModelTime/float64(p.InMemoryModelCount))
-	log.Infof("In-Memory Locking : %f", p.InMemoryLockTime)
-	log.Infof("In-Memory Locking Count: %d", p.InMemoryLockCount)
-	log.Infof("Avg In-Memory Locking : %f", p.InMemoryLockTime/float64(p.InMemoryLockCount))
-
-}
diff --git a/pkg/db/model/proxy.go b/pkg/db/model/proxy.go
deleted file mode 100644
index b5378fe..0000000
--- a/pkg/db/model/proxy.go
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"context"
-	"crypto/md5"
-	"errors"
-	"fmt"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-	"runtime"
-	"strings"
-	"sync"
-)
-
-// OperationContext holds details on the information used during an operation
-type OperationContext struct {
-	Path      string
-	Data      interface{}
-	FieldName string
-	ChildKey  string
-}
-
-// NewOperationContext instantiates a new OperationContext structure
-func NewOperationContext(path string, data interface{}, fieldName string, childKey string) *OperationContext {
-	oc := &OperationContext{
-		Path:      path,
-		Data:      data,
-		FieldName: fieldName,
-		ChildKey:  childKey,
-	}
-	return oc
-}
-
-// Update applies new data to the context structure
-func (oc *OperationContext) Update(data interface{}) *OperationContext {
-	oc.Data = data
-	return oc
-}
-
-// Proxy holds the information for a specific location with the data model
-type Proxy struct {
-	mutex      sync.RWMutex
-	Root       *root
-	Node       *node
-	ParentNode *node
-	Path       string
-	FullPath   string
-	Exclusive  bool
-	Callbacks  map[CallbackType]map[string]*CallbackTuple
-	operation  ProxyOperation
-}
-
-// NewProxy instantiates a new proxy to a specific location
-func NewProxy(root *root, node *node, parentNode *node, path string, fullPath string, exclusive bool) *Proxy {
-	callbacks := make(map[CallbackType]map[string]*CallbackTuple)
-	if fullPath == "/" {
-		fullPath = ""
-	}
-	p := &Proxy{
-		Root:       root,
-		Node:       node,
-		ParentNode: parentNode,
-		Exclusive:  exclusive,
-		Path:       path,
-		FullPath:   fullPath,
-		Callbacks:  callbacks,
-	}
-	return p
-}
-
-// GetRoot returns the root attribute of the proxy
-func (p *Proxy) GetRoot() *root {
-	return p.Root
-}
-
-// getPath returns the path attribute of the proxy
-func (p *Proxy) getPath() string {
-	return p.Path
-}
-
-// getFullPath returns the full path attribute of the proxy
-func (p *Proxy) getFullPath() string {
-	return p.FullPath
-}
-
-// getCallbacks returns the full list of callbacks associated to the proxy
-func (p *Proxy) getCallbacks(callbackType CallbackType) map[string]*CallbackTuple {
-	p.mutex.RLock()
-	defer p.mutex.RUnlock()
-
-	if p != nil {
-		if cb, exists := p.Callbacks[callbackType]; exists {
-			return cb
-		}
-	} else {
-		log.Debugw("proxy-is-nil", log.Fields{"callback-type": callbackType.String()})
-	}
-	return nil
-}
-
-// getCallback returns a specific callback matching the type and function hash
-func (p *Proxy) getCallback(callbackType CallbackType, funcHash string) *CallbackTuple {
-	p.mutex.Lock()
-	defer p.mutex.Unlock()
-	if tuple, exists := p.Callbacks[callbackType][funcHash]; exists {
-		return tuple
-	}
-	return nil
-}
-
-// setCallbacks applies a callbacks list to a type
-func (p *Proxy) setCallbacks(callbackType CallbackType, callbacks map[string]*CallbackTuple) {
-	p.mutex.Lock()
-	defer p.mutex.Unlock()
-	p.Callbacks[callbackType] = callbacks
-}
-
-// setCallback applies a callback to a type and hash value
-func (p *Proxy) setCallback(callbackType CallbackType, funcHash string, tuple *CallbackTuple) {
-	p.mutex.Lock()
-	defer p.mutex.Unlock()
-	p.Callbacks[callbackType][funcHash] = tuple
-}
-
-// DeleteCallback removes a callback matching the type and hash
-func (p *Proxy) DeleteCallback(callbackType CallbackType, funcHash string) {
-	p.mutex.Lock()
-	defer p.mutex.Unlock()
-	delete(p.Callbacks[callbackType], funcHash)
-}
-
-// CallbackType is an enumerated value to express when a callback should be executed
-type ProxyOperation uint8
-
-// Enumerated list of callback types
-const (
-	PROXY_NONE ProxyOperation = iota
-	PROXY_GET
-	PROXY_LIST
-	PROXY_ADD
-	PROXY_UPDATE
-	PROXY_REMOVE
-	PROXY_CREATE
-	PROXY_WATCH
-)
-
-var proxyOperationTypes = []string{
-	"PROXY_NONE",
-	"PROXY_GET",
-	"PROXY_LIST",
-	"PROXY_ADD",
-	"PROXY_UPDATE",
-	"PROXY_REMOVE",
-	"PROXY_CREATE",
-	"PROXY_WATCH",
-}
-
-func (t ProxyOperation) String() string {
-	return proxyOperationTypes[t]
-}
-
-func (p *Proxy) GetOperation() ProxyOperation {
-	p.mutex.RLock()
-	defer p.mutex.RUnlock()
-	return p.operation
-}
-
-func (p *Proxy) SetOperation(operation ProxyOperation) {
-	p.mutex.Lock()
-	defer p.mutex.Unlock()
-	p.operation = operation
-}
-
-// parseForControlledPath verifies if a proxy path matches a pattern
-// for locations that need to be access controlled.
-func (p *Proxy) parseForControlledPath(path string) (pathLock string, controlled bool) {
-	// TODO: Add other path prefixes that may need control
-	if strings.HasPrefix(path, "/devices") ||
-		strings.HasPrefix(path, "/logical_devices") ||
-		strings.HasPrefix(path, "/adapters") {
-
-		split := strings.SplitN(path, "/", -1)
-		switch len(split) {
-		case 2:
-			controlled = false
-			pathLock = ""
-			break
-		case 3:
-			fallthrough
-		default:
-			pathLock = fmt.Sprintf("%s/%s", split[1], split[2])
-			controlled = true
-		}
-	}
-	return pathLock, controlled
-}
-
-// List will retrieve information from the data model at the specified path location
-// A list operation will force access to persistence storage
-func (p *Proxy) List(ctx context.Context, path string, depth int, deep bool, txid string) interface{} {
-	var effectivePath string
-	if path == "/" {
-		effectivePath = p.getFullPath()
-	} else {
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_LIST)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-list", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	rv := p.GetRoot().List(ctx, path, "", depth, deep, txid)
-
-	return rv
-}
-
-// Get will retrieve information from the data model at the specified path location
-func (p *Proxy) Get(ctx context.Context, path string, depth int, deep bool, txid string) interface{} {
-	var effectivePath string
-	if path == "/" {
-		effectivePath = p.getFullPath()
-	} else {
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_GET)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-get", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	rv := p.GetRoot().Get(ctx, path, "", depth, deep, txid)
-
-	return rv
-}
-
-// Update will modify information in the data model at the specified location with the provided data
-func (p *Proxy) Update(ctx context.Context, path string, data interface{}, strict bool, txid string) interface{} {
-	if !strings.HasPrefix(path, "/") {
-		log.Errorf("invalid path: %s", path)
-		return nil
-	}
-	var fullPath string
-	var effectivePath string
-	if path == "/" {
-		fullPath = p.getPath()
-		effectivePath = p.getFullPath()
-	} else {
-		fullPath = p.getPath() + path
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_UPDATE)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-update", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"full":       fullPath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	if p.GetRoot().KvStore != nil {
-		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-	}
-
-	result := p.GetRoot().Update(ctx, fullPath, data, strict, txid, nil)
-
-	if result != nil {
-		return result.GetData()
-	}
-
-	return nil
-}
-
-// AddWithID will insert new data at specified location.
-// This method also allows the user to specify the ID of the data entry to ensure
-// that access control is active while inserting the information.
-func (p *Proxy) AddWithID(ctx context.Context, path string, id string, data interface{}, txid string) interface{} {
-	if !strings.HasPrefix(path, "/") {
-		log.Errorf("invalid path: %s", path)
-		return nil
-	}
-	var fullPath string
-	var effectivePath string
-	if path == "/" {
-		fullPath = p.getPath()
-		effectivePath = p.getFullPath()
-	} else {
-		fullPath = p.getPath() + path
-		effectivePath = p.getFullPath() + path + "/" + id
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_ADD)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-add-with-id", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"full":       fullPath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	if p.GetRoot().KvStore != nil {
-		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-	}
-
-	result := p.GetRoot().Add(ctx, fullPath, data, txid, nil)
-
-	if result != nil {
-		return result.GetData()
-	}
-
-	return nil
-}
-
-// Add will insert new data at specified location.
-func (p *Proxy) Add(ctx context.Context, path string, data interface{}, txid string) interface{} {
-	if !strings.HasPrefix(path, "/") {
-		log.Errorf("invalid path: %s", path)
-		return nil
-	}
-	var fullPath string
-	var effectivePath string
-	if path == "/" {
-		fullPath = p.getPath()
-		effectivePath = p.getFullPath()
-	} else {
-		fullPath = p.getPath() + path
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_ADD)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-add", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"full":       fullPath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	if p.GetRoot().KvStore != nil {
-		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-	}
-
-	result := p.GetRoot().Add(ctx, fullPath, data, txid, nil)
-
-	if result != nil {
-		return result.GetData()
-	}
-
-	return nil
-}
-
-// Remove will delete an entry at the specified location
-func (p *Proxy) Remove(ctx context.Context, path string, txid string) interface{} {
-	if !strings.HasPrefix(path, "/") {
-		log.Errorf("invalid path: %s", path)
-		return nil
-	}
-	var fullPath string
-	var effectivePath string
-	if path == "/" {
-		fullPath = p.getPath()
-		effectivePath = p.getFullPath()
-	} else {
-		fullPath = p.getPath() + path
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_REMOVE)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-remove", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"full":       fullPath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	if p.GetRoot().KvStore != nil {
-		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-	}
-
-	result := p.GetRoot().Remove(ctx, fullPath, txid, nil)
-
-	if result != nil {
-		return result.GetData()
-	}
-
-	return nil
-}
-
-// CreateProxy to interact with specific path directly
-func (p *Proxy) CreateProxy(ctx context.Context, path string, exclusive bool) *Proxy {
-	if !strings.HasPrefix(path, "/") {
-		log.Errorf("invalid path: %s", path)
-		return nil
-	}
-
-	var fullPath string
-	var effectivePath string
-	if path == "/" {
-		fullPath = p.getPath()
-		effectivePath = p.getFullPath()
-	} else {
-		fullPath = p.getPath() + path
-		effectivePath = p.getFullPath() + path
-	}
-
-	pathLock, controlled := p.parseForControlledPath(effectivePath)
-
-	p.SetOperation(PROXY_CREATE)
-	defer p.SetOperation(PROXY_NONE)
-
-	log.Debugw("proxy-create", log.Fields{
-		"path":       path,
-		"effective":  effectivePath,
-		"full":       fullPath,
-		"pathLock":   pathLock,
-		"controlled": controlled,
-		"operation":  p.GetOperation(),
-	})
-
-	if p.GetRoot().KvStore != nil {
-		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
-		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
-	}
-
-	return p.GetRoot().CreateProxy(ctx, fullPath, exclusive)
-}
-
-// OpenTransaction creates a new transaction branch to isolate operations made to the data model
-func (p *Proxy) OpenTransaction() *Transaction {
-	txid := p.GetRoot().MakeTxBranch()
-	return NewTransaction(p, txid)
-}
-
-// commitTransaction will apply and merge modifications made in the transaction branch to the data model
-func (p *Proxy) commitTransaction(txid string) {
-	p.GetRoot().FoldTxBranch(txid)
-}
-
-// cancelTransaction will terminate a transaction branch along will all changes within it
-func (p *Proxy) cancelTransaction(txid string) {
-	p.GetRoot().DeleteTxBranch(txid)
-}
-
-// CallbackFunction is a type used to define callback functions
-type CallbackFunction func(args ...interface{}) interface{}
-
-// CallbackTuple holds the function and arguments details of a callback
-type CallbackTuple struct {
-	callback CallbackFunction
-	args     []interface{}
-}
-
-// Execute will process the a callback with its provided arguments
-func (tuple *CallbackTuple) Execute(contextArgs []interface{}) interface{} {
-	args := []interface{}{}
-
-	for _, ta := range tuple.args {
-		args = append(args, ta)
-	}
-
-	if contextArgs != nil {
-		for _, ca := range contextArgs {
-			args = append(args, ca)
-		}
-	}
-
-	return tuple.callback(args...)
-}
-
-// RegisterCallback associates a callback to the proxy
-func (p *Proxy) RegisterCallback(callbackType CallbackType, callback CallbackFunction, args ...interface{}) {
-	if p.getCallbacks(callbackType) == nil {
-		p.setCallbacks(callbackType, make(map[string]*CallbackTuple))
-	}
-	funcName := runtime.FuncForPC(reflect.ValueOf(callback).Pointer()).Name()
-	log.Debugf("value of function: %s", funcName)
-	funcHash := fmt.Sprintf("%x", md5.Sum([]byte(funcName)))[:12]
-
-	p.setCallback(callbackType, funcHash, &CallbackTuple{callback, args})
-}
-
-// UnregisterCallback removes references to a callback within a proxy
-func (p *Proxy) UnregisterCallback(callbackType CallbackType, callback CallbackFunction, args ...interface{}) {
-	if p.getCallbacks(callbackType) == nil {
-		log.Errorf("no such callback type - %s", callbackType.String())
-		return
-	}
-
-	funcName := runtime.FuncForPC(reflect.ValueOf(callback).Pointer()).Name()
-	funcHash := fmt.Sprintf("%x", md5.Sum([]byte(funcName)))[:12]
-
-	log.Debugf("value of function: %s", funcName)
-
-	if p.getCallback(callbackType, funcHash) == nil {
-		log.Errorf("function with hash value: '%s' not registered with callback type: '%s'", funcHash, callbackType)
-		return
-	}
-
-	p.DeleteCallback(callbackType, funcHash)
-}
-
-func (p *Proxy) invoke(callback *CallbackTuple, context []interface{}) (result interface{}, err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			errStr := fmt.Sprintf("callback error occurred: %+v", r)
-			err = errors.New(errStr)
-			log.Error(errStr)
-		}
-	}()
-
-	result = callback.Execute(context)
-
-	return result, err
-}
-
-// InvokeCallbacks executes all callbacks associated to a specific type
-func (p *Proxy) InvokeCallbacks(args ...interface{}) (result interface{}) {
-	callbackType := args[0].(CallbackType)
-	proceedOnError := args[1].(bool)
-	context := args[2:]
-
-	var err error
-
-	if callbacks := p.getCallbacks(callbackType); callbacks != nil {
-		p.mutex.Lock()
-		for _, callback := range callbacks {
-			if result, err = p.invoke(callback, context); err != nil {
-				if !proceedOnError {
-					log.Info("An error occurred.  Stopping callback invocation")
-					break
-				}
-				log.Info("An error occurred.  Invoking next callback")
-			}
-		}
-		p.mutex.Unlock()
-	}
-
-	return result
-}
diff --git a/pkg/db/model/proxy_load_test.go b/pkg/db/model/proxy_load_test.go
deleted file mode 100644
index f28a727..0000000
--- a/pkg/db/model/proxy_load_test.go
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"context"
-	"encoding/hex"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"github.com/opencord/voltha-protos/v2/go/common"
-	"github.com/opencord/voltha-protos/v2/go/openflow_13"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"math/rand"
-	"reflect"
-	"strconv"
-	"sync"
-	"testing"
-)
-
-var (
-	BenchmarkProxy_Root        *root
-	BenchmarkProxy_DeviceProxy *Proxy
-	BenchmarkProxy_PLT         *proxyLoadTest
-	BenchmarkProxy_Logger      log.Logger
-)
-
-type proxyLoadChanges struct {
-	ID     string
-	Before interface{}
-	After  interface{}
-}
-type proxyLoadTest struct {
-	mutex sync.RWMutex
-
-	addMutex     sync.RWMutex
-	addedDevices []string
-
-	firmwareMutex    sync.RWMutex
-	updatedFirmwares []proxyLoadChanges
-	flowMutex        sync.RWMutex
-	updatedFlows     []proxyLoadChanges
-
-	preAddExecuted     bool
-	postAddExecuted    bool
-	preUpdateExecuted  bool
-	postUpdateExecuted bool
-}
-
-func (plt *proxyLoadTest) SetPreAddExecuted(status bool) {
-	plt.mutex.Lock()
-	defer plt.mutex.Unlock()
-	plt.preAddExecuted = status
-}
-func (plt *proxyLoadTest) SetPostAddExecuted(status bool) {
-	plt.mutex.Lock()
-	defer plt.mutex.Unlock()
-	plt.postAddExecuted = status
-}
-func (plt *proxyLoadTest) SetPreUpdateExecuted(status bool) {
-	plt.mutex.Lock()
-	defer plt.mutex.Unlock()
-	plt.preUpdateExecuted = status
-}
-func (plt *proxyLoadTest) SetPostUpdateExecuted(status bool) {
-	plt.mutex.Lock()
-	defer plt.mutex.Unlock()
-	plt.postUpdateExecuted = status
-}
-
-func init() {
-	BenchmarkProxy_Root = NewRoot(&voltha.Voltha{}, nil)
-
-	BenchmarkProxy_Logger, _ = log.AddPackage(log.JSON, log.DebugLevel, log.Fields{"instanceId": "PLT"})
-	//log.UpdateAllLoggers(log.Fields{"instanceId": "PROXY_LOAD_TEST"})
-	//Setup default logger - applies for packages that do not have specific logger set
-	if _, err := log.SetDefaultLogger(log.JSON, log.DebugLevel, log.Fields{"instanceId": "PLT"}); err != nil {
-		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
-	}
-
-	// Update all loggers (provisioned via init) with a common field
-	if err := log.UpdateAllLoggers(log.Fields{"instanceId": "PLT"}); err != nil {
-		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
-	}
-	log.SetPackageLogLevel("github.com/opencord/voltha-lib-go/v2/pkg/db/model", log.DebugLevel)
-
-	BenchmarkProxy_DeviceProxy = BenchmarkProxy_Root.node.CreateProxy(context.Background(), "/", false)
-	// Register ADD instructions callbacks
-	BenchmarkProxy_PLT = &proxyLoadTest{}
-
-	BenchmarkProxy_DeviceProxy.RegisterCallback(PRE_ADD, commonCallbackFunc, "PRE_ADD", BenchmarkProxy_PLT.SetPreAddExecuted)
-	BenchmarkProxy_DeviceProxy.RegisterCallback(POST_ADD, commonCallbackFunc, "POST_ADD", BenchmarkProxy_PLT.SetPostAddExecuted)
-
-	//// Register UPDATE instructions callbacks
-	BenchmarkProxy_DeviceProxy.RegisterCallback(PRE_UPDATE, commonCallbackFunc, "PRE_UPDATE", BenchmarkProxy_PLT.SetPreUpdateExecuted)
-	BenchmarkProxy_DeviceProxy.RegisterCallback(POST_UPDATE, commonCallbackFunc, "POST_UPDATE", BenchmarkProxy_PLT.SetPostUpdateExecuted)
-
-}
-
-func BenchmarkProxy_AddDevice(b *testing.B) {
-	defer GetProfiling().Report()
-	b.RunParallel(func(pb *testing.PB) {
-		b.Log("Started adding devices")
-		for pb.Next() {
-			ltPorts := []*voltha.Port{
-				{
-					PortNo:     123,
-					Label:      "lt-port-0",
-					Type:       voltha.Port_PON_OLT,
-					AdminState: common.AdminState_ENABLED,
-					OperStatus: common.OperStatus_ACTIVE,
-					DeviceId:   "lt-port-0-device-id",
-					Peers:      []*voltha.Port_PeerPort{},
-				},
-			}
-
-			ltStats := &openflow_13.OfpFlowStats{
-				Id: 1000,
-			}
-			ltFlows := &openflow_13.Flows{
-				Items: []*openflow_13.OfpFlowStats{ltStats},
-			}
-			ltDevice := &voltha.Device{
-				Id:         "",
-				Type:       "simulated_olt",
-				Address:    &voltha.Device_HostAndPort{HostAndPort: "1.2.3.4:5555"},
-				AdminState: voltha.AdminState_PREPROVISIONED,
-				Flows:      ltFlows,
-				Ports:      ltPorts,
-			}
-
-			ltDevIDBin, _ := uuid.New().MarshalBinary()
-			ltDevID := "0001" + hex.EncodeToString(ltDevIDBin)[:12]
-			ltDevice.Id = ltDevID
-
-			BenchmarkProxy_PLT.SetPreAddExecuted(false)
-			BenchmarkProxy_PLT.SetPostAddExecuted(false)
-
-			var added interface{}
-			// Add the device
-			if added = BenchmarkProxy_DeviceProxy.AddWithID(context.Background(), "/devices", ltDevID, ltDevice, ""); added == nil {
-				BenchmarkProxy_Logger.Errorf("Failed to add device: %+v", ltDevice)
-				continue
-			} else {
-				BenchmarkProxy_Logger.Infof("Device was added 1: %+v", added)
-			}
-
-			BenchmarkProxy_PLT.addMutex.Lock()
-			BenchmarkProxy_PLT.addedDevices = append(BenchmarkProxy_PLT.addedDevices, added.(*voltha.Device).Id)
-			BenchmarkProxy_PLT.addMutex.Unlock()
-		}
-	})
-
-	BenchmarkProxy_Logger.Infof("Number of added devices : %d", len(BenchmarkProxy_PLT.addedDevices))
-}
-
-func BenchmarkProxy_UpdateFirmware(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			//for i:=0; i < b.N; i++ {
-
-			if len(BenchmarkProxy_PLT.addedDevices) > 0 {
-				var target interface{}
-				randomID := BenchmarkProxy_PLT.addedDevices[rand.Intn(len(BenchmarkProxy_PLT.addedDevices))]
-				firmProxy := BenchmarkProxy_Root.node.CreateProxy(context.Background(), "/", false)
-				if target = firmProxy.Get(context.Background(), "/devices/"+randomID, 0, false,
-					""); !reflect.ValueOf(target).IsValid() {
-					BenchmarkProxy_Logger.Errorf("Failed to find device: %s %+v", randomID, target)
-					continue
-				}
-
-				BenchmarkProxy_PLT.SetPreUpdateExecuted(false)
-				BenchmarkProxy_PLT.SetPostUpdateExecuted(false)
-				firmProxy.RegisterCallback(PRE_UPDATE, commonCallbackFunc, "PRE_UPDATE", BenchmarkProxy_PLT.SetPreUpdateExecuted)
-				firmProxy.RegisterCallback(POST_UPDATE, commonCallbackFunc, "POST_UPDATE", BenchmarkProxy_PLT.SetPostUpdateExecuted)
-
-				var fwVersion int
-
-				before := target.(*voltha.Device).FirmwareVersion
-				if target.(*voltha.Device).FirmwareVersion == "n/a" {
-					fwVersion = 0
-				} else {
-					fwVersion, _ = strconv.Atoi(target.(*voltha.Device).FirmwareVersion)
-					fwVersion++
-				}
-
-				target.(*voltha.Device).FirmwareVersion = strconv.Itoa(fwVersion)
-				after := target.(*voltha.Device).FirmwareVersion
-
-				var updated interface{}
-				if updated = firmProxy.Update(context.Background(), "/devices/"+randomID, target.(*voltha.Device), false,
-					""); updated == nil {
-					BenchmarkProxy_Logger.Errorf("Failed to update device: %+v", target)
-					continue
-				} else {
-					BenchmarkProxy_Logger.Infof("Device was updated : %+v", updated)
-
-				}
-
-				if d := firmProxy.Get(context.Background(), "/devices/"+randomID, 0, false,
-					""); !reflect.ValueOf(d).IsValid() {
-					BenchmarkProxy_Logger.Errorf("Failed to get device: %s", randomID)
-					continue
-				} else if d.(*voltha.Device).FirmwareVersion == after {
-					BenchmarkProxy_Logger.Infof("Imm Device was updated with new value: %s %+v", randomID, d)
-				} else if d.(*voltha.Device).FirmwareVersion == before {
-					BenchmarkProxy_Logger.Errorf("Imm Device kept old value: %s %+v %+v", randomID, d, target)
-				} else {
-					BenchmarkProxy_Logger.Errorf("Imm Device has unknown value: %s %+v %+v", randomID, d, target)
-				}
-
-				BenchmarkProxy_PLT.firmwareMutex.Lock()
-
-				BenchmarkProxy_PLT.updatedFirmwares = append(
-					BenchmarkProxy_PLT.updatedFirmwares,
-					proxyLoadChanges{ID: randomID, Before: before, After: after},
-				)
-				BenchmarkProxy_PLT.firmwareMutex.Unlock()
-			}
-		}
-	})
-}
-
-func traverseBranches(revision Revision, depth int) {
-	if revision == nil {
-		return
-	}
-	prefix := strconv.Itoa(depth) + " ~~~~ "
-	for i := 0; i < depth; i++ {
-		prefix += "  "
-	}
-
-	BenchmarkProxy_Logger.Debugf("%sRevision: %s %+v", prefix, revision.GetHash(), revision.GetData())
-
-	//for brIdx, brRev := range revision.GetBranch().Revisions {
-	//	BenchmarkProxy_Logger.Debugf("%sbranchIndex: %s", prefix, brIdx)
-	//	traverseBranches(brRev, depth+1)
-	//}
-	for childrenI, children := range revision.GetAllChildren() {
-		BenchmarkProxy_Logger.Debugf("%schildrenIndex: %s, length: %d", prefix, childrenI, len(children))
-
-		for _, subrev := range children {
-			//subrev.GetBranch().Latest
-			traverseBranches(subrev, depth+1)
-		}
-	}
-
-}
-func BenchmarkProxy_UpdateFlows(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			if len(BenchmarkProxy_PLT.addedDevices) > 0 {
-				randomID := BenchmarkProxy_PLT.addedDevices[rand.Intn(len(BenchmarkProxy_PLT.addedDevices))]
-
-				flowsProxy := BenchmarkProxy_Root.node.CreateProxy(context.Background(), "/devices/"+randomID+"/flows", false)
-				flows := flowsProxy.Get(context.Background(), "/", 0, false, "")
-
-				before := flows.(*openflow_13.Flows).Items[0].TableId
-				flows.(*openflow_13.Flows).Items[0].TableId = uint32(rand.Intn(3000))
-				after := flows.(*openflow_13.Flows).Items[0].TableId
-
-				flowsProxy.RegisterCallback(
-					PRE_UPDATE,
-					commonCallback2,
-				)
-				flowsProxy.RegisterCallback(
-					POST_UPDATE,
-					commonCallback2,
-				)
-
-				var updated interface{}
-				if updated = flowsProxy.Update(context.Background(), "/", flows.(*openflow_13.Flows), false, ""); updated == nil {
-					b.Errorf("Failed to update flows for device: %+v", flows)
-				} else {
-					BenchmarkProxy_Logger.Infof("Flows were updated : %+v", updated)
-				}
-				BenchmarkProxy_PLT.flowMutex.Lock()
-				BenchmarkProxy_PLT.updatedFlows = append(
-					BenchmarkProxy_PLT.updatedFlows,
-					proxyLoadChanges{ID: randomID, Before: before, After: after},
-				)
-				BenchmarkProxy_PLT.flowMutex.Unlock()
-			}
-		}
-	})
-}
-
-func BenchmarkProxy_GetDevices(b *testing.B) {
-	//traverseBranches(BenchmarkProxy_DeviceProxy.Root.node.Branches[NONE].GetLatest(), 0)
-
-	for i := 0; i < len(BenchmarkProxy_PLT.addedDevices); i++ {
-		devToGet := BenchmarkProxy_PLT.addedDevices[i]
-		// Verify that the added device can now be retrieved
-		if d := BenchmarkProxy_DeviceProxy.Get(context.Background(), "/devices/"+devToGet, 0, false,
-			""); !reflect.ValueOf(d).IsValid() {
-			BenchmarkProxy_Logger.Errorf("Failed to get device: %s", devToGet)
-			continue
-		} else {
-			BenchmarkProxy_Logger.Infof("Got device: %s %+v", devToGet, d)
-		}
-	}
-}
-
-func BenchmarkProxy_GetUpdatedFirmware(b *testing.B) {
-	for i := 0; i < len(BenchmarkProxy_PLT.updatedFirmwares); i++ {
-		devToGet := BenchmarkProxy_PLT.updatedFirmwares[i].ID
-		// Verify that the updated device can be retrieved and that the updates were actually applied
-		if d := BenchmarkProxy_DeviceProxy.Get(context.Background(), "/devices/"+devToGet, 0, false,
-			""); !reflect.ValueOf(d).IsValid() {
-			BenchmarkProxy_Logger.Errorf("Failed to get device: %s", devToGet)
-			continue
-		} else if d.(*voltha.Device).FirmwareVersion == BenchmarkProxy_PLT.updatedFirmwares[i].After.(string) {
-			BenchmarkProxy_Logger.Infof("Device was updated with new value: %s %+v", devToGet, d)
-		} else if d.(*voltha.Device).FirmwareVersion == BenchmarkProxy_PLT.updatedFirmwares[i].Before.(string) {
-			BenchmarkProxy_Logger.Errorf("Device kept old value: %s %+v %+v", devToGet, d, BenchmarkProxy_PLT.updatedFirmwares[i])
-		} else {
-			BenchmarkProxy_Logger.Errorf("Device has unknown value: %s %+v %+v", devToGet, d, BenchmarkProxy_PLT.updatedFirmwares[i])
-		}
-	}
-}
diff --git a/pkg/db/model/proxy_test.go b/pkg/db/model/proxy_test.go
deleted file mode 100644
index 785c65b..0000000
--- a/pkg/db/model/proxy_test.go
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"context"
-	"encoding/hex"
-	"encoding/json"
-	"github.com/golang/protobuf/proto"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-protos/v2/go/common"
-	"github.com/opencord/voltha-protos/v2/go/openflow_13"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"math/rand"
-	"reflect"
-	"strconv"
-	"testing"
-	"time"
-)
-
-var (
-	TestProxy_Root                  *root
-	TestProxy_Root_LogicalDevice    *Proxy
-	TestProxy_Root_Device           *Proxy
-	TestProxy_Root_Adapter          *Proxy
-	TestProxy_DeviceId              string
-	TestProxy_AdapterId             string
-	TestProxy_LogicalDeviceId       string
-	TestProxy_TargetDeviceId        string
-	TestProxy_TargetLogicalDeviceId string
-	TestProxy_LogicalPorts          []*voltha.LogicalPort
-	TestProxy_Ports                 []*voltha.Port
-	TestProxy_Stats                 *openflow_13.OfpFlowStats
-	TestProxy_Flows                 *openflow_13.Flows
-	TestProxy_Device                *voltha.Device
-	TestProxy_LogicalDevice         *voltha.LogicalDevice
-	TestProxy_Adapter               *voltha.Adapter
-)
-
-func init() {
-	//log.AddPackage(log.JSON, log.InfoLevel, log.Fields{"instanceId": "DB_MODEL"})
-	//log.UpdateAllLoggers(log.Fields{"instanceId": "PROXY_LOAD_TEST"})
-	TestProxy_Root = NewRoot(&voltha.Voltha{}, nil)
-	TestProxy_Root_LogicalDevice = TestProxy_Root.CreateProxy(context.Background(), "/", false)
-	TestProxy_Root_Device = TestProxy_Root.CreateProxy(context.Background(), "/", false)
-	TestProxy_Root_Adapter = TestProxy_Root.CreateProxy(context.Background(), "/", false)
-
-	TestProxy_LogicalPorts = []*voltha.LogicalPort{
-		{
-			Id:           "123",
-			DeviceId:     "logicalport-0-device-id",
-			DevicePortNo: 123,
-			RootPort:     false,
-		},
-	}
-	TestProxy_Ports = []*voltha.Port{
-		{
-			PortNo:     123,
-			Label:      "test-port-0",
-			Type:       voltha.Port_PON_OLT,
-			AdminState: common.AdminState_ENABLED,
-			OperStatus: common.OperStatus_ACTIVE,
-			DeviceId:   "etcd_port-0-device-id",
-			Peers:      []*voltha.Port_PeerPort{},
-		},
-	}
-
-	TestProxy_Stats = &openflow_13.OfpFlowStats{
-		Id: 1111,
-	}
-	TestProxy_Flows = &openflow_13.Flows{
-		Items: []*openflow_13.OfpFlowStats{TestProxy_Stats},
-	}
-	TestProxy_Device = &voltha.Device{
-		Id:         TestProxy_DeviceId,
-		Type:       "simulated_olt",
-		Address:    &voltha.Device_HostAndPort{HostAndPort: "1.2.3.4:5555"},
-		AdminState: voltha.AdminState_PREPROVISIONED,
-		Flows:      TestProxy_Flows,
-		Ports:      TestProxy_Ports,
-	}
-
-	TestProxy_LogicalDevice = &voltha.LogicalDevice{
-		Id:         TestProxy_DeviceId,
-		DatapathId: 0,
-		Ports:      TestProxy_LogicalPorts,
-		Flows:      TestProxy_Flows,
-	}
-
-	TestProxy_Adapter = &voltha.Adapter{
-		Id:      TestProxy_AdapterId,
-		Vendor:  "test-adapter-vendor",
-		Version: "test-adapter-version",
-	}
-}
-
-func TestProxy_1_1_1_Add_NewDevice(t *testing.T) {
-	devIDBin, _ := uuid.New().MarshalBinary()
-	TestProxy_DeviceId = "0001" + hex.EncodeToString(devIDBin)[:12]
-	TestProxy_Device.Id = TestProxy_DeviceId
-
-	preAddExecuted := make(chan struct{})
-	postAddExecuted := make(chan struct{})
-	preAddExecutedPtr, postAddExecutedPtr := preAddExecuted, postAddExecuted
-
-	devicesProxy := TestProxy_Root.node.CreateProxy(context.Background(), "/devices", false)
-	devicesProxy.RegisterCallback(PRE_ADD, commonCallback2, "PRE_ADD Device container changes")
-	devicesProxy.RegisterCallback(POST_ADD, commonCallback2, "POST_ADD Device container changes")
-
-	// Register ADD instructions callbacks
-	TestProxy_Root_Device.RegisterCallback(PRE_ADD, commonChanCallback, "PRE_ADD instructions", &preAddExecutedPtr)
-	TestProxy_Root_Device.RegisterCallback(POST_ADD, commonChanCallback, "POST_ADD instructions", &postAddExecutedPtr)
-
-	if added := TestProxy_Root_Device.Add(context.Background(), "/devices", TestProxy_Device, ""); added == nil {
-		t.Error("Failed to add device")
-	} else {
-		t.Logf("Added device : %+v", added)
-	}
-
-	if !verifyGotResponse(preAddExecuted) {
-		t.Error("PRE_ADD callback was not executed")
-	}
-	if !verifyGotResponse(postAddExecuted) {
-		t.Error("POST_ADD callback was not executed")
-	}
-
-	// Verify that the added device can now be retrieved
-	if d := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_DeviceId, 0, false, ""); !reflect.ValueOf(d).IsValid() {
-		t.Error("Failed to find added device")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found device: %s", string(djson))
-	}
-}
-
-func TestProxy_1_1_2_Add_ExistingDevice(t *testing.T) {
-	TestProxy_Device.Id = TestProxy_DeviceId
-
-	added := TestProxy_Root_Device.Add(context.Background(), "/devices", TestProxy_Device, "")
-	if added.(proto.Message).String() != reflect.ValueOf(TestProxy_Device).Interface().(proto.Message).String() {
-		t.Errorf("Devices don't match - existing: %+v returned: %+v", TestProxy_LogicalDevice, added)
-	}
-}
-
-func verifyGotResponse(callbackIndicator <-chan struct{}) bool {
-	timeout := time.After(1 * time.Second)
-	// Wait until the channel closes, or we time out
-	select {
-	case <-callbackIndicator:
-		// Received response successfully
-		return true
-
-	case <-timeout:
-		// Got a timeout! fail with a timeout error
-		return false
-	}
-}
-
-func TestProxy_1_1_3_Add_NewAdapter(t *testing.T) {
-	TestProxy_AdapterId = "test-adapter"
-	TestProxy_Adapter.Id = TestProxy_AdapterId
-	preAddExecuted := make(chan struct{})
-	postAddExecuted := make(chan struct{})
-	preAddExecutedPtr, postAddExecutedPtr := preAddExecuted, postAddExecuted
-
-	// Register ADD instructions callbacks
-	TestProxy_Root_Adapter.RegisterCallback(PRE_ADD, commonChanCallback, "PRE_ADD instructions for adapters", &preAddExecutedPtr)
-	TestProxy_Root_Adapter.RegisterCallback(POST_ADD, commonChanCallback, "POST_ADD instructions for adapters", &postAddExecutedPtr)
-
-	// Add the adapter
-	if added := TestProxy_Root_Adapter.Add(context.Background(), "/adapters", TestProxy_Adapter, ""); added == nil {
-		t.Error("Failed to add adapter")
-	} else {
-		t.Logf("Added adapter : %+v", added)
-	}
-
-	verifyGotResponse(postAddExecuted)
-
-	// Verify that the added device can now be retrieved
-	if d := TestProxy_Root_Adapter.Get(context.Background(), "/adapters/"+TestProxy_AdapterId, 0, false, ""); !reflect.ValueOf(d).IsValid() {
-		t.Error("Failed to find added adapter")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found adapter: %s", string(djson))
-	}
-
-	if !verifyGotResponse(preAddExecuted) {
-		t.Error("PRE_ADD callback was not executed")
-	}
-	if !verifyGotResponse(postAddExecuted) {
-		t.Error("POST_ADD callback was not executed")
-	}
-}
-
-func TestProxy_1_2_1_Get_AllDevices(t *testing.T) {
-	devices := TestProxy_Root_Device.Get(context.Background(), "/devices", 1, false, "")
-
-	if len(devices.([]interface{})) == 0 {
-		t.Error("there are no available devices to retrieve")
-	} else {
-		// Save the target device id for later tests
-		TestProxy_TargetDeviceId = devices.([]interface{})[0].(*voltha.Device).Id
-		t.Logf("retrieved all devices: %+v", devices)
-	}
-}
-
-func TestProxy_1_2_2_Get_SingleDevice(t *testing.T) {
-	if d := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_TargetDeviceId, 0, false, ""); !reflect.ValueOf(d).IsValid() {
-		t.Errorf("Failed to find device : %s", TestProxy_TargetDeviceId)
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found device: %s", string(djson))
-	}
-}
-
-func TestProxy_1_3_1_Update_Device(t *testing.T) {
-	var fwVersion int
-
-	preUpdateExecuted := make(chan struct{})
-	postUpdateExecuted := make(chan struct{})
-	preUpdateExecutedPtr, postUpdateExecutedPtr := preUpdateExecuted, postUpdateExecuted
-
-	if retrieved := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_TargetDeviceId, 1, false, ""); retrieved == nil {
-		t.Error("Failed to get device")
-	} else {
-		t.Logf("Found raw device (root proxy): %+v", retrieved)
-
-		if retrieved.(*voltha.Device).FirmwareVersion == "n/a" {
-			fwVersion = 0
-		} else {
-			fwVersion, _ = strconv.Atoi(retrieved.(*voltha.Device).FirmwareVersion)
-			fwVersion++
-		}
-
-		retrieved.(*voltha.Device).FirmwareVersion = strconv.Itoa(fwVersion)
-
-		TestProxy_Root_Device.RegisterCallback(
-			PRE_UPDATE,
-			commonChanCallback,
-			"PRE_UPDATE instructions (root proxy)", &preUpdateExecutedPtr,
-		)
-		TestProxy_Root_Device.RegisterCallback(
-			POST_UPDATE,
-			commonChanCallback,
-			"POST_UPDATE instructions (root proxy)", &postUpdateExecutedPtr,
-		)
-
-		if afterUpdate := TestProxy_Root_Device.Update(context.Background(), "/devices/"+TestProxy_TargetDeviceId, retrieved, false, ""); afterUpdate == nil {
-			t.Error("Failed to update device")
-		} else {
-			t.Logf("Updated device : %+v", afterUpdate)
-		}
-
-		if !verifyGotResponse(preUpdateExecuted) {
-			t.Error("PRE_UPDATE callback was not executed")
-		}
-		if !verifyGotResponse(postUpdateExecuted) {
-			t.Error("POST_UPDATE callback was not executed")
-		}
-
-		if d := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_TargetDeviceId, 1, false, ""); !reflect.ValueOf(d).IsValid() {
-			t.Error("Failed to find updated device (root proxy)")
-		} else {
-			djson, _ := json.Marshal(d)
-			t.Logf("Found device (root proxy): %s raw: %+v", string(djson), d)
-		}
-	}
-}
-
-func TestProxy_1_3_2_Update_DeviceFlows(t *testing.T) {
-	// Get a device proxy and update a specific port
-	devFlowsProxy := TestProxy_Root.node.CreateProxy(context.Background(), "/devices/"+TestProxy_DeviceId+"/flows", false)
-	flows := devFlowsProxy.Get(context.Background(), "/", 0, false, "")
-	flows.(*openflow_13.Flows).Items[0].TableId = 2244
-
-	preUpdateExecuted := make(chan struct{})
-	postUpdateExecuted := make(chan struct{})
-	preUpdateExecutedPtr, postUpdateExecutedPtr := preUpdateExecuted, postUpdateExecuted
-
-	devFlowsProxy.RegisterCallback(
-		PRE_UPDATE,
-		commonChanCallback,
-		"PRE_UPDATE instructions (flows proxy)", &preUpdateExecutedPtr,
-	)
-	devFlowsProxy.RegisterCallback(
-		POST_UPDATE,
-		commonChanCallback,
-		"POST_UPDATE instructions (flows proxy)", &postUpdateExecutedPtr,
-	)
-
-	kvFlows := devFlowsProxy.Get(context.Background(), "/", 0, false, "")
-
-	if reflect.DeepEqual(flows, kvFlows) {
-		t.Errorf("Local changes have changed the KV store contents -  local:%+v, kv: %+v", flows, kvFlows)
-	}
-
-	if updated := devFlowsProxy.Update(context.Background(), "/", flows.(*openflow_13.Flows), false, ""); updated == nil {
-		t.Error("Failed to update flow")
-	} else {
-		t.Logf("Updated flows : %+v", updated)
-	}
-
-	if !verifyGotResponse(preUpdateExecuted) {
-		t.Error("PRE_UPDATE callback was not executed")
-	}
-	if !verifyGotResponse(postUpdateExecuted) {
-		t.Error("POST_UPDATE callback was not executed")
-	}
-
-	if d := devFlowsProxy.Get(context.Background(), "/", 0, false, ""); d == nil {
-		t.Error("Failed to find updated flows (flows proxy)")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found flows (flows proxy): %s", string(djson))
-	}
-
-	if d := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_DeviceId+"/flows", 1, false, ""); !reflect.ValueOf(d).IsValid() {
-		t.Error("Failed to find updated flows (root proxy)")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found flows (root proxy): %s", string(djson))
-	}
-}
-
-func TestProxy_1_3_3_Update_Adapter(t *testing.T) {
-	preUpdateExecuted := make(chan struct{})
-	postUpdateExecuted := make(chan struct{})
-	preUpdateExecutedPtr, postUpdateExecutedPtr := preUpdateExecuted, postUpdateExecuted
-
-	adaptersProxy := TestProxy_Root.node.CreateProxy(context.Background(), "/adapters", false)
-
-	if retrieved := TestProxy_Root_Adapter.Get(context.Background(), "/adapters/"+TestProxy_AdapterId, 1, false, ""); retrieved == nil {
-		t.Error("Failed to get adapter")
-	} else {
-		t.Logf("Found raw adapter (root proxy): %+v", retrieved)
-
-		retrieved.(*voltha.Adapter).Version = "test-adapter-version-2"
-
-		adaptersProxy.RegisterCallback(
-			PRE_UPDATE,
-			commonChanCallback,
-			"PRE_UPDATE instructions for adapters", &preUpdateExecutedPtr,
-		)
-		adaptersProxy.RegisterCallback(
-			POST_UPDATE,
-			commonChanCallback,
-			"POST_UPDATE instructions for adapters", &postUpdateExecutedPtr,
-		)
-
-		if afterUpdate := adaptersProxy.Update(context.Background(), "/"+TestProxy_AdapterId, retrieved, false, ""); afterUpdate == nil {
-			t.Error("Failed to update adapter")
-		} else {
-			t.Logf("Updated adapter : %+v", afterUpdate)
-		}
-
-		if !verifyGotResponse(preUpdateExecuted) {
-			t.Error("PRE_UPDATE callback for adapter was not executed")
-		}
-		if !verifyGotResponse(postUpdateExecuted) {
-			t.Error("POST_UPDATE callback for adapter was not executed")
-		}
-
-		if d := TestProxy_Root_Adapter.Get(context.Background(), "/adapters/"+TestProxy_AdapterId, 1, false, ""); !reflect.ValueOf(d).IsValid() {
-			t.Error("Failed to find updated adapter (root proxy)")
-		} else {
-			djson, _ := json.Marshal(d)
-			t.Logf("Found adapter (root proxy): %s raw: %+v", string(djson), d)
-		}
-	}
-}
-
-func TestProxy_1_4_1_Remove_Device(t *testing.T) {
-	preRemoveExecuted := make(chan struct{})
-	postRemoveExecuted := make(chan struct{})
-	preRemoveExecutedPtr, postRemoveExecutedPtr := preRemoveExecuted, postRemoveExecuted
-
-	TestProxy_Root_Device.RegisterCallback(
-		PRE_REMOVE,
-		commonChanCallback,
-		"PRE_REMOVE instructions (root proxy)", &preRemoveExecutedPtr,
-	)
-	TestProxy_Root_Device.RegisterCallback(
-		POST_REMOVE,
-		commonChanCallback,
-		"POST_REMOVE instructions (root proxy)", &postRemoveExecutedPtr,
-	)
-
-	if removed := TestProxy_Root_Device.Remove(context.Background(), "/devices/"+TestProxy_DeviceId, ""); removed == nil {
-		t.Error("Failed to remove device")
-	} else {
-		t.Logf("Removed device : %+v", removed)
-	}
-
-	if !verifyGotResponse(preRemoveExecuted) {
-		t.Error("PRE_REMOVE callback was not executed")
-	}
-	if !verifyGotResponse(postRemoveExecuted) {
-		t.Error("POST_REMOVE callback was not executed")
-	}
-
-	if d := TestProxy_Root_Device.Get(context.Background(), "/devices/"+TestProxy_DeviceId, 0, false, ""); reflect.ValueOf(d).IsValid() {
-		djson, _ := json.Marshal(d)
-		t.Errorf("Device was not removed - %s", djson)
-	} else {
-		t.Logf("Device was removed: %s", TestProxy_DeviceId)
-	}
-}
-
-func TestProxy_2_1_1_Add_NewLogicalDevice(t *testing.T) {
-
-	ldIDBin, _ := uuid.New().MarshalBinary()
-	TestProxy_LogicalDeviceId = "0001" + hex.EncodeToString(ldIDBin)[:12]
-	TestProxy_LogicalDevice.Id = TestProxy_LogicalDeviceId
-
-	preAddExecuted := make(chan struct{})
-	postAddExecuted := make(chan struct{})
-	preAddExecutedPtr, postAddExecutedPtr := preAddExecuted, postAddExecuted
-
-	// Register
-	TestProxy_Root_LogicalDevice.RegisterCallback(PRE_ADD, commonChanCallback, "PRE_ADD instructions", &preAddExecutedPtr)
-	TestProxy_Root_LogicalDevice.RegisterCallback(POST_ADD, commonChanCallback, "POST_ADD instructions", &postAddExecutedPtr)
-
-	if added := TestProxy_Root_LogicalDevice.Add(context.Background(), "/logical_devices", TestProxy_LogicalDevice, ""); added == nil {
-		t.Error("Failed to add logical device")
-	} else {
-		t.Logf("Added logical device : %+v", added)
-	}
-
-	verifyGotResponse(postAddExecuted)
-
-	if ld := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_LogicalDeviceId, 0, false, ""); !reflect.ValueOf(ld).IsValid() {
-		t.Error("Failed to find added logical device")
-	} else {
-		ldJSON, _ := json.Marshal(ld)
-		t.Logf("Found logical device: %s", string(ldJSON))
-	}
-
-	if !verifyGotResponse(preAddExecuted) {
-		t.Error("PRE_ADD callback was not executed")
-	}
-	if !verifyGotResponse(postAddExecuted) {
-		t.Error("POST_ADD callback was not executed")
-	}
-}
-
-func TestProxy_2_1_2_Add_ExistingLogicalDevice(t *testing.T) {
-	TestProxy_LogicalDevice.Id = TestProxy_LogicalDeviceId
-
-	added := TestProxy_Root_LogicalDevice.Add(context.Background(), "/logical_devices", TestProxy_LogicalDevice, "")
-	if added.(proto.Message).String() != reflect.ValueOf(TestProxy_LogicalDevice).Interface().(proto.Message).String() {
-		t.Errorf("Logical devices don't match - existing: %+v returned: %+v", TestProxy_LogicalDevice, added)
-	}
-}
-
-func TestProxy_2_2_1_Get_AllLogicalDevices(t *testing.T) {
-	logicalDevices := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices", 1, false, "")
-
-	if len(logicalDevices.([]interface{})) == 0 {
-		t.Error("there are no available logical devices to retrieve")
-	} else {
-		// Save the target device id for later tests
-		TestProxy_TargetLogicalDeviceId = logicalDevices.([]interface{})[0].(*voltha.LogicalDevice).Id
-		t.Logf("retrieved all logical devices: %+v", logicalDevices)
-	}
-}
-
-func TestProxy_2_2_2_Get_SingleLogicalDevice(t *testing.T) {
-	if ld := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_TargetLogicalDeviceId, 0, false, ""); !reflect.ValueOf(ld).IsValid() {
-		t.Errorf("Failed to find logical device : %s", TestProxy_TargetLogicalDeviceId)
-	} else {
-		ldJSON, _ := json.Marshal(ld)
-		t.Logf("Found logical device: %s", string(ldJSON))
-	}
-
-}
-
-func TestProxy_2_3_1_Update_LogicalDevice(t *testing.T) {
-	var fwVersion int
-	preUpdateExecuted := make(chan struct{})
-	postUpdateExecuted := make(chan struct{})
-	preUpdateExecutedPtr, postUpdateExecutedPtr := preUpdateExecuted, postUpdateExecuted
-
-	if retrieved := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_TargetLogicalDeviceId, 1, false, ""); retrieved == nil {
-		t.Error("Failed to get logical device")
-	} else {
-		t.Logf("Found raw logical device (root proxy): %+v", retrieved)
-
-		if retrieved.(*voltha.LogicalDevice).RootDeviceId == "" {
-			fwVersion = 0
-		} else {
-			fwVersion, _ = strconv.Atoi(retrieved.(*voltha.LogicalDevice).RootDeviceId)
-			fwVersion++
-		}
-
-		TestProxy_Root_LogicalDevice.RegisterCallback(
-			PRE_UPDATE,
-			commonChanCallback,
-			"PRE_UPDATE instructions (root proxy)", &preUpdateExecutedPtr,
-		)
-		TestProxy_Root_LogicalDevice.RegisterCallback(
-			POST_UPDATE,
-			commonChanCallback,
-			"POST_UPDATE instructions (root proxy)", &postUpdateExecutedPtr,
-		)
-
-		retrieved.(*voltha.LogicalDevice).RootDeviceId = strconv.Itoa(fwVersion)
-
-		if afterUpdate := TestProxy_Root_LogicalDevice.Update(context.Background(), "/logical_devices/"+TestProxy_TargetLogicalDeviceId, retrieved, false,
-			""); afterUpdate == nil {
-			t.Error("Failed to update logical device")
-		} else {
-			t.Logf("Updated logical device : %+v", afterUpdate)
-		}
-
-		if !verifyGotResponse(preUpdateExecuted) {
-			t.Error("PRE_UPDATE callback was not executed")
-		}
-		if !verifyGotResponse(postUpdateExecuted) {
-			t.Error("POST_UPDATE callback was not executed")
-		}
-
-		if d := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_TargetLogicalDeviceId, 1, false, ""); !reflect.ValueOf(d).IsValid() {
-			t.Error("Failed to find updated logical device (root proxy)")
-		} else {
-			djson, _ := json.Marshal(d)
-
-			t.Logf("Found logical device (root proxy): %s raw: %+v", string(djson), d)
-		}
-	}
-}
-
-func TestProxy_2_3_2_Update_LogicalDeviceFlows(t *testing.T) {
-	// Get a device proxy and update a specific port
-	ldFlowsProxy := TestProxy_Root.node.CreateProxy(context.Background(), "/logical_devices/"+TestProxy_LogicalDeviceId+"/flows", false)
-	flows := ldFlowsProxy.Get(context.Background(), "/", 0, false, "")
-	flows.(*openflow_13.Flows).Items[0].TableId = rand.Uint32()
-	t.Logf("before updated flows: %+v", flows)
-
-	ldFlowsProxy.RegisterCallback(
-		PRE_UPDATE,
-		commonCallback2,
-	)
-	ldFlowsProxy.RegisterCallback(
-		POST_UPDATE,
-		commonCallback2,
-	)
-
-	kvFlows := ldFlowsProxy.Get(context.Background(), "/", 0, false, "")
-
-	if reflect.DeepEqual(flows, kvFlows) {
-		t.Errorf("Local changes have changed the KV store contents -  local:%+v, kv: %+v", flows, kvFlows)
-	}
-
-	if updated := ldFlowsProxy.Update(context.Background(), "/", flows.(*openflow_13.Flows), false, ""); updated == nil {
-		t.Error("Failed to update logical device flows")
-	} else {
-		t.Logf("Updated logical device flows : %+v", updated)
-	}
-
-	if d := ldFlowsProxy.Get(context.Background(), "/", 0, false, ""); d == nil {
-		t.Error("Failed to find updated logical device flows (flows proxy)")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found flows (flows proxy): %s", string(djson))
-	}
-
-	if d := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_LogicalDeviceId+"/flows", 0, false,
-		""); !reflect.ValueOf(d).IsValid() {
-		t.Error("Failed to find updated logical device flows (root proxy)")
-	} else {
-		djson, _ := json.Marshal(d)
-		t.Logf("Found logical device flows (root proxy): %s", string(djson))
-	}
-}
-
-func TestProxy_2_4_1_Remove_Device(t *testing.T) {
-	preRemoveExecuted := make(chan struct{})
-	postRemoveExecuted := make(chan struct{})
-	preRemoveExecutedPtr, postRemoveExecutedPtr := preRemoveExecuted, postRemoveExecuted
-
-	TestProxy_Root_LogicalDevice.RegisterCallback(
-		PRE_REMOVE,
-		commonChanCallback,
-		"PRE_REMOVE instructions (root proxy)", &preRemoveExecutedPtr,
-	)
-	TestProxy_Root_LogicalDevice.RegisterCallback(
-		POST_REMOVE,
-		commonChanCallback,
-		"POST_REMOVE instructions (root proxy)", &postRemoveExecutedPtr,
-	)
-
-	if removed := TestProxy_Root_LogicalDevice.Remove(context.Background(), "/logical_devices/"+TestProxy_LogicalDeviceId, ""); removed == nil {
-		t.Error("Failed to remove logical device")
-	} else {
-		t.Logf("Removed device : %+v", removed)
-	}
-
-	if !verifyGotResponse(preRemoveExecuted) {
-		t.Error("PRE_REMOVE callback was not executed")
-	}
-	if !verifyGotResponse(postRemoveExecuted) {
-		t.Error("POST_REMOVE callback was not executed")
-	}
-
-	if d := TestProxy_Root_LogicalDevice.Get(context.Background(), "/logical_devices/"+TestProxy_LogicalDeviceId, 0, false, ""); reflect.ValueOf(d).IsValid() {
-		djson, _ := json.Marshal(d)
-		t.Errorf("Device was not removed - %s", djson)
-	} else {
-		t.Logf("Device was removed: %s", TestProxy_LogicalDeviceId)
-	}
-}
-
-// -----------------------------
-// Callback tests
-// -----------------------------
-
-func TestProxy_Callbacks_1_Register(t *testing.T) {
-	TestProxy_Root_Device.RegisterCallback(PRE_ADD, firstCallback, "abcde", "12345")
-
-	m := make(map[string]string)
-	m["name"] = "fghij"
-	TestProxy_Root_Device.RegisterCallback(PRE_ADD, secondCallback, m, 1.2345)
-
-	d := &voltha.Device{Id: "12345"}
-	TestProxy_Root_Device.RegisterCallback(PRE_ADD, thirdCallback, "klmno", d)
-}
-
-func TestProxy_Callbacks_2_Invoke_WithNoInterruption(t *testing.T) {
-	TestProxy_Root_Device.InvokeCallbacks(PRE_ADD, false, nil)
-}
-
-func TestProxy_Callbacks_3_Invoke_WithInterruption(t *testing.T) {
-	TestProxy_Root_Device.InvokeCallbacks(PRE_ADD, true, nil)
-}
-
-func TestProxy_Callbacks_4_Unregister(t *testing.T) {
-	TestProxy_Root_Device.UnregisterCallback(PRE_ADD, firstCallback)
-	TestProxy_Root_Device.UnregisterCallback(PRE_ADD, secondCallback)
-	TestProxy_Root_Device.UnregisterCallback(PRE_ADD, thirdCallback)
-}
-
-//func TestProxy_Callbacks_5_Add(t *testing.T) {
-//	TestProxy_Root_Device.Root.AddCallback(TestProxy_Root_Device.InvokeCallbacks, POST_UPDATE, false, "some data", "some new data")
-//}
-//
-//func TestProxy_Callbacks_6_Execute(t *testing.T) {
-//	TestProxy_Root_Device.Root.ExecuteCallbacks()
-//}
diff --git a/pkg/db/model/revision.go b/pkg/db/model/revision.go
deleted file mode 100644
index 29fc5e9..0000000
--- a/pkg/db/model/revision.go
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"context"
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/kvstore"
-	"time"
-)
-
-type Revision interface {
-	Finalize(bool)
-	SetConfig(revision *DataRevision)
-	GetConfig() *DataRevision
-	Drop(txid string, includeConfig bool)
-	StorageDrop(txid string, includeConfig bool)
-	ChildDrop(childType string, childHash string)
-	ChildDropByName(childName string)
-	SetChildren(name string, children []Revision)
-	GetChildren(name string) []Revision
-	SetAllChildren(children map[string][]Revision)
-	GetAllChildren() map[string][]Revision
-	SetHash(hash string)
-	GetHash() string
-	ClearHash()
-	getVersion() int64
-	SetupWatch(key string)
-	SetName(name string)
-	GetName() string
-	SetBranch(branch *Branch)
-	GetBranch() *Branch
-	Get(int) interface{}
-	GetData() interface{}
-	GetNode() *node
-	SetLastUpdate(ts ...time.Time)
-	GetLastUpdate() time.Time
-	LoadFromPersistence(ctx context.Context, path string, txid string, blobs map[string]*kvstore.KVPair) []Revision
-	UpdateData(ctx context.Context, data interface{}, branch *Branch) Revision
-	UpdateChildren(ctx context.Context, name string, children []Revision, branch *Branch) Revision
-	UpdateAllChildren(children map[string][]Revision, branch *Branch) Revision
-}
diff --git a/pkg/db/model/root.go b/pkg/db/model/root.go
deleted file mode 100644
index 771f938..0000000
--- a/pkg/db/model/root.go
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"context"
-	"encoding/hex"
-	"encoding/json"
-	"github.com/golang/protobuf/proto"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-	"reflect"
-	"sync"
-)
-
-// Root is used to provide an abstraction to the base root structure
-type Root interface {
-	Node
-
-	ExecuteCallbacks()
-	AddCallback(callback CallbackFunction, args ...interface{})
-	AddNotificationCallback(callback CallbackFunction, args ...interface{})
-}
-
-// root points to the top of the data model tree or sub-tree identified by a proxy
-type root struct {
-	*node
-
-	Callbacks             []CallbackTuple
-	NotificationCallbacks []CallbackTuple
-
-	DirtyNodes    map[string][]*node
-	KvStore       *Backend
-	Loading       bool
-	RevisionClass interface{}
-
-	mutex sync.RWMutex
-}
-
-// NewRoot creates an new instance of a root object
-func NewRoot(initialData interface{}, kvStore *Backend) *root {
-	root := &root{}
-
-	root.KvStore = kvStore
-	root.DirtyNodes = make(map[string][]*node)
-	root.Loading = false
-
-	// If there is no storage in place just revert to
-	// a non persistent mechanism
-	if kvStore != nil {
-		root.RevisionClass = reflect.TypeOf(PersistedRevision{})
-	} else {
-		root.RevisionClass = reflect.TypeOf(NonPersistedRevision{})
-	}
-
-	root.Callbacks = []CallbackTuple{}
-	root.NotificationCallbacks = []CallbackTuple{}
-
-	root.node = NewNode(root, initialData, false, "")
-
-	return root
-}
-
-// MakeTxBranch creates a new transaction branch
-func (r *root) MakeTxBranch() string {
-	txidBin, _ := uuid.New().MarshalBinary()
-	txid := hex.EncodeToString(txidBin)[:12]
-
-	r.DirtyNodes[txid] = []*node{r.node}
-	r.node.MakeBranch(txid)
-
-	return txid
-}
-
-// DeleteTxBranch removes a transaction branch
-func (r *root) DeleteTxBranch(txid string) {
-	for _, dirtyNode := range r.DirtyNodes[txid] {
-		dirtyNode.DeleteBranch(txid)
-	}
-	delete(r.DirtyNodes, txid)
-	r.node.DeleteBranch(txid)
-}
-
-// FoldTxBranch will merge the contents of a transaction branch with the root object
-func (r *root) FoldTxBranch(txid string) {
-	// Start by doing a dry run of the merge
-	// If that fails, it bails out and the branch is deleted
-	if _, err := r.node.MergeBranch(txid, true); err != nil {
-		// Merge operation fails
-		r.DeleteTxBranch(txid)
-	} else {
-		r.node.MergeBranch(txid, false)
-		r.node.GetRoot().ExecuteCallbacks()
-		r.DeleteTxBranch(txid)
-	}
-}
-
-// ExecuteCallbacks will invoke all the callbacks linked to root object
-func (r *root) ExecuteCallbacks() {
-	r.mutex.Lock()
-	defer r.mutex.Unlock()
-
-	for len(r.Callbacks) > 0 {
-		callback := r.Callbacks[0]
-		r.Callbacks = r.Callbacks[1:]
-		go callback.Execute(nil)
-	}
-	//for len(r.NotificationCallbacks) > 0 {
-	//	callback := r.NotificationCallbacks[0]
-	//	r.NotificationCallbacks = r.NotificationCallbacks[1:]
-	//	go callback.Execute(nil)
-	//}
-}
-
-func (r *root) hasCallbacks() bool {
-	return len(r.Callbacks) == 0
-}
-
-// getCallbacks returns the available callbacks
-func (r *root) GetCallbacks() []CallbackTuple {
-	r.mutex.Lock()
-	defer r.mutex.Unlock()
-
-	return r.Callbacks
-}
-
-// getCallbacks returns the available notification callbacks
-func (r *root) GetNotificationCallbacks() []CallbackTuple {
-	r.mutex.Lock()
-	defer r.mutex.Unlock()
-
-	return r.NotificationCallbacks
-}
-
-// AddCallback inserts a new callback with its arguments
-func (r *root) AddCallback(callback CallbackFunction, args ...interface{}) {
-	r.mutex.Lock()
-	defer r.mutex.Unlock()
-
-	r.Callbacks = append(r.Callbacks, CallbackTuple{callback, args})
-}
-
-// AddNotificationCallback inserts a new notification callback with its arguments
-func (r *root) AddNotificationCallback(callback CallbackFunction, args ...interface{}) {
-	r.mutex.Lock()
-	defer r.mutex.Unlock()
-
-	r.NotificationCallbacks = append(r.NotificationCallbacks, CallbackTuple{callback, args})
-}
-
-func (r *root) syncParent(childRev Revision, txid string) {
-	data := proto.Clone(r.GetProxy().ParentNode.Latest().GetData().(proto.Message))
-
-	for fieldName, _ := range ChildrenFields(data) {
-		childDataName, childDataHolder := GetAttributeValue(data, fieldName, 0)
-		if reflect.TypeOf(childRev.GetData()) == reflect.TypeOf(childDataHolder.Interface()) {
-			childDataHolder = reflect.ValueOf(childRev.GetData())
-			reflect.ValueOf(data).Elem().FieldByName(childDataName).Set(childDataHolder)
-		}
-	}
-
-	r.GetProxy().ParentNode.Latest().SetConfig(NewDataRevision(r.GetProxy().ParentNode.GetRoot(), data))
-	r.GetProxy().ParentNode.Latest(txid).Finalize(false)
-}
-
-// Update modifies the content of an object at a given path with the provided data
-func (r *root) Update(ctx context.Context, path string, data interface{}, strict bool, txid string, makeBranch MakeBranchFunction) Revision {
-	var result Revision
-
-	if makeBranch != nil {
-		// TODO: raise error
-	}
-
-	if r.hasCallbacks() {
-		// TODO: raise error
-	}
-
-	if txid != "" {
-		trackDirty := func(node *node) *Branch {
-			r.DirtyNodes[txid] = append(r.DirtyNodes[txid], node)
-			return node.MakeBranch(txid)
-		}
-		result = r.node.Update(ctx, path, data, strict, txid, trackDirty)
-	} else {
-		result = r.node.Update(ctx, path, data, strict, "", nil)
-	}
-
-	if result != nil {
-		if r.GetProxy().FullPath != r.GetProxy().Path {
-			r.syncParent(result, txid)
-		} else {
-			result.Finalize(false)
-		}
-	}
-
-	r.node.GetRoot().ExecuteCallbacks()
-
-	return result
-}
-
-// Add creates a new object at the given path with the provided data
-func (r *root) Add(ctx context.Context, path string, data interface{}, txid string, makeBranch MakeBranchFunction) Revision {
-	var result Revision
-
-	if makeBranch != nil {
-		// TODO: raise error
-	}
-
-	if r.hasCallbacks() {
-		// TODO: raise error
-	}
-
-	if txid != "" {
-		trackDirty := func(node *node) *Branch {
-			r.DirtyNodes[txid] = append(r.DirtyNodes[txid], node)
-			return node.MakeBranch(txid)
-		}
-		result = r.node.Add(ctx, path, data, txid, trackDirty)
-	} else {
-		result = r.node.Add(ctx, path, data, "", nil)
-	}
-
-	if result != nil {
-		result.Finalize(true)
-		r.node.GetRoot().ExecuteCallbacks()
-	}
-	return result
-}
-
-// Remove discards an object at a given path
-func (r *root) Remove(ctx context.Context, path string, txid string, makeBranch MakeBranchFunction) Revision {
-	var result Revision
-
-	if makeBranch != nil {
-		// TODO: raise error
-	}
-
-	if r.hasCallbacks() {
-		// TODO: raise error
-	}
-
-	if txid != "" {
-		trackDirty := func(node *node) *Branch {
-			r.DirtyNodes[txid] = append(r.DirtyNodes[txid], node)
-			return node.MakeBranch(txid)
-		}
-		result = r.node.Remove(ctx, path, txid, trackDirty)
-	} else {
-		result = r.node.Remove(ctx, path, "", nil)
-	}
-
-	r.node.GetRoot().ExecuteCallbacks()
-
-	return result
-}
-
-// MakeLatest updates a branch with the latest node revision
-func (r *root) MakeLatest(branch *Branch, revision Revision, changeAnnouncement []ChangeTuple) {
-	r.makeLatest(branch, revision, changeAnnouncement)
-}
-
-func (r *root) MakeRevision(branch *Branch, data interface{}, children map[string][]Revision) Revision {
-	if r.RevisionClass.(reflect.Type) == reflect.TypeOf(PersistedRevision{}) {
-		return NewPersistedRevision(branch, data, children)
-	}
-
-	return NewNonPersistedRevision(r, branch, data, children)
-}
-
-func (r *root) makeLatest(branch *Branch, revision Revision, changeAnnouncement []ChangeTuple) {
-	r.node.makeLatest(branch, revision, changeAnnouncement)
-
-	if r.KvStore != nil && branch.Txid == "" {
-		tags := make(map[string]string)
-		for k, v := range r.node.Tags {
-			tags[k] = v.GetHash()
-		}
-		data := &rootData{
-			Latest: branch.GetLatest().GetHash(),
-			Tags:   tags,
-		}
-		if blob, err := json.Marshal(data); err != nil {
-			// TODO report error
-		} else {
-			log.Debugf("Changing root to : %s", string(blob))
-			if err := r.KvStore.Put("root", blob); err != nil {
-				log.Errorf("failed to properly put value in kvstore - err: %s", err.Error())
-			}
-		}
-	}
-}
-
-type rootData struct {
-	Latest string            `json:"latest"`
-	Tags   map[string]string `json:"tags"`
-}
diff --git a/pkg/db/model/transaction.go b/pkg/db/model/transaction.go
deleted file mode 100644
index d7a34e7..0000000
--- a/pkg/db/model/transaction.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package model
-
-import (
-	"context"
-	"github.com/opencord/voltha-lib-go/v2/pkg/log"
-)
-
-type Transaction struct {
-	proxy *Proxy
-	txid  string
-}
-
-func NewTransaction(proxy *Proxy, txid string) *Transaction {
-	tx := &Transaction{
-		proxy: proxy,
-		txid:  txid,
-	}
-	return tx
-}
-func (t *Transaction) Get(ctx context.Context, path string, depth int, deep bool) interface{} {
-	if t.txid == "" {
-		log.Errorf("closed transaction")
-		return nil
-	}
-	// TODO: need to review the return values at the different layers!!!!!
-	return t.proxy.Get(ctx, path, depth, deep, t.txid)
-}
-func (t *Transaction) Update(ctx context.Context, path string, data interface{}, strict bool) interface{} {
-	if t.txid == "" {
-		log.Errorf("closed transaction")
-		return nil
-	}
-	return t.proxy.Update(ctx, path, data, strict, t.txid)
-}
-func (t *Transaction) Add(ctx context.Context, path string, data interface{}) interface{} {
-	if t.txid == "" {
-		log.Errorf("closed transaction")
-		return nil
-	}
-	return t.proxy.Add(ctx, path, data, t.txid)
-}
-func (t *Transaction) Remove(ctx context.Context, path string) interface{} {
-	if t.txid == "" {
-		log.Errorf("closed transaction")
-		return nil
-	}
-	return t.proxy.Remove(ctx, path, t.txid)
-}
-func (t *Transaction) Cancel() {
-	t.proxy.cancelTransaction(t.txid)
-	t.txid = ""
-}
-func (t *Transaction) Commit() {
-	t.proxy.commitTransaction(t.txid)
-	t.txid = ""
-}
diff --git a/pkg/db/model/transaction_test.go b/pkg/db/model/transaction_test.go
deleted file mode 100644
index c33e5be..0000000
--- a/pkg/db/model/transaction_test.go
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"context"
-	"encoding/hex"
-	"github.com/google/uuid"
-	"github.com/opencord/voltha-protos/v2/go/common"
-	"github.com/opencord/voltha-protos/v2/go/voltha"
-	"strconv"
-	"testing"
-)
-
-var (
-	TestTransaction_Root           *root
-	TestTransaction_RootProxy      *Proxy
-	TestTransaction_TargetDeviceId string
-	TestTransaction_DeviceId       string
-)
-
-func init() {
-	TestTransaction_Root = NewRoot(&voltha.Voltha{}, nil)
-	TestTransaction_RootProxy = TestTransaction_Root.node.CreateProxy(context.Background(), "/", false)
-}
-
-//func TestTransaction_1_GetDevices(t *testing.T) {
-//	getTx := TestTransaction_RootProxy.OpenTransaction()
-//
-//	devices := getTx.Get("/devices", 1, false)
-//
-//	if len(devices.([]interface{})) == 0 {
-//		t.Error("there are no available devices to retrieve")
-//	} else {
-//		// Save the target device id for later tests
-//		TestTransaction_TargetDeviceId = devices.([]interface{})[0].(*voltha.Device).Id
-//		t.Logf("retrieved devices: %+v", devices)
-//	}
-//
-//	getTx.Commit()
-//}
-
-func TestTransaction_2_AddDevice(t *testing.T) {
-	devIDBin, _ := uuid.New().MarshalBinary()
-	TestTransaction_DeviceId = "0001" + hex.EncodeToString(devIDBin)[:12]
-
-	ports := []*voltha.Port{
-		{
-			PortNo:     123,
-			Label:      "test-port-0",
-			Type:       voltha.Port_PON_OLT,
-			AdminState: common.AdminState_ENABLED,
-			OperStatus: common.OperStatus_ACTIVE,
-			DeviceId:   "etcd_port-0-device-id",
-			Peers:      []*voltha.Port_PeerPort{},
-		},
-	}
-
-	device := &voltha.Device{
-		Id:         TestTransaction_DeviceId,
-		Type:       "simulated_olt",
-		Address:    &voltha.Device_HostAndPort{HostAndPort: "1.2.3.4:5555"},
-		AdminState: voltha.AdminState_PREPROVISIONED,
-		Ports:      ports,
-	}
-
-	addTx := TestTransaction_RootProxy.OpenTransaction()
-
-	if added := addTx.Add(context.Background(), "/devices", device); added == nil {
-		t.Error("Failed to add device")
-	} else {
-		TestTransaction_TargetDeviceId = added.(*voltha.Device).Id
-		t.Logf("Added device : %+v", added)
-	}
-	addTx.Commit()
-}
-
-func TestTransaction_3_GetDevice_PostAdd(t *testing.T) {
-
-	basePath := "/devices/" + TestTransaction_DeviceId
-
-	getDevWithPortsTx := TestTransaction_RootProxy.OpenTransaction()
-	device1 := getDevWithPortsTx.Get(context.Background(), basePath+"/ports", 1, false)
-	t.Logf("retrieved device with ports: %+v", device1)
-	getDevWithPortsTx.Commit()
-
-	getDevTx := TestTransaction_RootProxy.OpenTransaction()
-	device2 := getDevTx.Get(context.Background(), basePath, 0, false)
-	t.Logf("retrieved device: %+v", device2)
-
-	getDevTx.Commit()
-}
-
-func TestTransaction_4_UpdateDevice(t *testing.T) {
-	updateTx := TestTransaction_RootProxy.OpenTransaction()
-	if retrieved := updateTx.Get(context.Background(), "/devices/"+TestTransaction_TargetDeviceId, 1, false); retrieved == nil {
-		t.Error("Failed to get device")
-	} else {
-		var fwVersion int
-		if retrieved.(*voltha.Device).FirmwareVersion == "n/a" {
-			fwVersion = 0
-		} else {
-			fwVersion, _ = strconv.Atoi(retrieved.(*voltha.Device).FirmwareVersion)
-			fwVersion++
-		}
-
-		//cloned := reflect.ValueOf(retrieved).Elem().Interface().(voltha.Device)
-		retrieved.(*voltha.Device).FirmwareVersion = strconv.Itoa(fwVersion)
-		t.Logf("Before update : %+v", retrieved)
-
-		// FIXME: The makeBranch passed in function is nil or not being executed properly!!!!!
-		if afterUpdate := updateTx.Update(context.Background(), "/devices/"+TestTransaction_TargetDeviceId, retrieved, false); afterUpdate == nil {
-			t.Error("Failed to update device")
-		} else {
-			t.Logf("Updated device : %+v", afterUpdate)
-		}
-	}
-	updateTx.Commit()
-}
-
-func TestTransaction_5_GetDevice_PostUpdate(t *testing.T) {
-
-	basePath := "/devices/" + TestTransaction_DeviceId
-
-	getDevWithPortsTx := TestTransaction_RootProxy.OpenTransaction()
-	device1 := getDevWithPortsTx.Get(context.Background(), basePath+"/ports", 1, false)
-	t.Logf("retrieved device with ports: %+v", device1)
-	getDevWithPortsTx.Commit()
-
-	getDevTx := TestTransaction_RootProxy.OpenTransaction()
-	device2 := getDevTx.Get(context.Background(), basePath, 0, false)
-	t.Logf("retrieved device: %+v", device2)
-
-	getDevTx.Commit()
-}
-
-func TestTransaction_6_RemoveDevice(t *testing.T) {
-	removeTx := TestTransaction_RootProxy.OpenTransaction()
-	if removed := removeTx.Remove(context.Background(), "/devices/"+TestTransaction_DeviceId); removed == nil {
-		t.Error("Failed to remove device")
-	} else {
-		t.Logf("Removed device : %+v", removed)
-	}
-	removeTx.Commit()
-}
-
-func TestTransaction_7_GetDevice_PostRemove(t *testing.T) {
-
-	basePath := "/devices/" + TestTransaction_DeviceId
-
-	getDevTx := TestTransaction_RootProxy.OpenTransaction()
-	device := TestTransaction_RootProxy.Get(context.Background(), basePath, 0, false, "")
-	t.Logf("retrieved device: %+v", device)
-
-	getDevTx.Commit()
-}
diff --git a/pkg/db/model/utils.go b/pkg/db/model/utils.go
deleted file mode 100644
index b28e92f..0000000
--- a/pkg/db/model/utils.go
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package model
-
-import (
-	"bytes"
-	"encoding/gob"
-	"reflect"
-	"strings"
-)
-
-// IsProtoMessage determines if the specified implements proto.Message type
-func IsProtoMessage(object interface{}) bool {
-	var ok = false
-
-	if object != nil {
-		st := reflect.TypeOf(object)
-		_, ok = st.MethodByName("ProtoMessage")
-	}
-	return ok
-}
-
-// FindOwnerType will traverse a data structure and find the parent type of the specified object
-func FindOwnerType(obj reflect.Value, name string, depth int, found bool) reflect.Type {
-	prefix := ""
-	for d := 0; d < depth; d++ {
-		prefix += ">>"
-	}
-	k := obj.Kind()
-	switch k {
-	case reflect.Ptr:
-		if found {
-			return obj.Type()
-		}
-
-		t := obj.Type().Elem()
-		n := reflect.New(t)
-
-		if rc := FindOwnerType(n.Elem(), name, depth+1, found); rc != nil {
-			return rc
-		}
-
-	case reflect.Struct:
-		if found {
-			return obj.Type()
-		}
-
-		for i := 0; i < obj.NumField(); i++ {
-			v := reflect.Indirect(obj)
-
-			json := strings.Split(v.Type().Field(i).Tag.Get("json"), ",")
-
-			if json[0] == name {
-				return FindOwnerType(obj.Field(i), name, depth+1, true)
-			}
-
-			if rc := FindOwnerType(obj.Field(i), name, depth+1, found); rc != nil {
-				return rc
-			}
-		}
-	case reflect.Slice:
-		s := reflect.MakeSlice(obj.Type(), 1, 1)
-		n := reflect.New(obj.Type())
-		n.Elem().Set(s)
-
-		for i := 0; i < n.Elem().Len(); i++ {
-			if found {
-				return reflect.ValueOf(n.Elem().Index(i).Interface()).Type()
-			}
-		}
-
-		for i := 0; i < obj.Len(); i++ {
-			if found {
-				return obj.Index(i).Type()
-			}
-
-			if rc := FindOwnerType(obj.Index(i), name, depth+1, found); rc != nil {
-				return rc
-			}
-		}
-	default:
-		//log.Debugf("%s Unhandled <%+v> ... It's a %+v\n", prefix, obj, k)
-	}
-
-	return nil
-}
-
-// FindKeyOwner will traverse a structure to find the owner type of the specified name
-func FindKeyOwner(iface interface{}, name string, depth int) interface{} {
-	obj := reflect.ValueOf(iface)
-	k := obj.Kind()
-	switch k {
-	case reflect.Ptr:
-		t := obj.Type().Elem()
-		n := reflect.New(t)
-
-		if rc := FindKeyOwner(n.Elem().Interface(), name, depth+1); rc != nil {
-			return rc
-		}
-
-	case reflect.Struct:
-		for i := 0; i < obj.NumField(); i++ {
-			json := strings.Split(obj.Type().Field(i).Tag.Get("json"), ",")
-
-			if json[0] == name {
-				return obj.Type().Field(i).Type
-			}
-
-			if rc := FindKeyOwner(obj.Field(i).Interface(), name, depth+1); rc != nil {
-				return rc
-			}
-		}
-
-	case reflect.Slice:
-		s := reflect.MakeSlice(obj.Type(), 1, 1)
-		n := reflect.New(obj.Type())
-		n.Elem().Set(s)
-
-		for i := 0; i < n.Elem().Len(); i++ {
-			if rc := FindKeyOwner(n.Elem().Index(i).Interface(), name, depth+1); rc != nil {
-				return rc
-			}
-		}
-	default:
-		//log.Debugf("%s Unhandled <%+v> ... It's a %+v\n", prefix, obj, k)
-	}
-
-	return nil
-}
-
-// GetAttributeValue traverse a structure to find the value of an attribute
-// FIXME: Need to figure out if GetAttributeValue and GetAttributeStructure can become one
-// Code is repeated in both, but outputs have a different purpose
-// Left as-is for now to get things working
-func GetAttributeValue(data interface{}, name string, depth int) (string, reflect.Value) {
-	var attribName string
-	var attribValue reflect.Value
-	obj := reflect.ValueOf(data)
-
-	if !obj.IsValid() {
-		return attribName, attribValue
-	}
-
-	k := obj.Kind()
-	switch k {
-	case reflect.Ptr:
-		if obj.IsNil() {
-			return attribName, attribValue
-		}
-
-		if attribName, attribValue = GetAttributeValue(obj.Elem().Interface(), name, depth+1); attribValue.IsValid() {
-			return attribName, attribValue
-		}
-
-	case reflect.Struct:
-		for i := 0; i < obj.NumField(); i++ {
-			json := strings.Split(obj.Type().Field(i).Tag.Get("json"), ",")
-
-			if json[0] == name {
-				return obj.Type().Field(i).Name, obj.Field(i)
-			}
-
-			if obj.Field(i).IsValid() {
-				if attribName, attribValue = GetAttributeValue(obj.Field(i).Interface(), name, depth+1); attribValue.IsValid() {
-					return attribName, attribValue
-				}
-			}
-		}
-
-	case reflect.Slice:
-		s := reflect.MakeSlice(obj.Type(), 1, 1)
-		n := reflect.New(obj.Type())
-		n.Elem().Set(s)
-
-		for i := 0; i < obj.Len(); i++ {
-			if attribName, attribValue = GetAttributeValue(obj.Index(i).Interface(), name, depth+1); attribValue.IsValid() {
-				return attribName, attribValue
-			}
-		}
-	default:
-		//log.Debugf("%s Unhandled <%+v> ... It's a %+v\n", prefix, obj, k)
-	}
-
-	return attribName, attribValue
-
-}
-
-// GetAttributeStructure will traverse a structure to find the data structure for the named attribute
-// FIXME: See GetAttributeValue(...) comment
-func GetAttributeStructure(data interface{}, name string, depth int) reflect.StructField {
-	var result reflect.StructField
-	obj := reflect.ValueOf(data)
-
-	if !obj.IsValid() {
-		return result
-	}
-
-	k := obj.Kind()
-	switch k {
-	case reflect.Ptr:
-		t := obj.Type().Elem()
-		n := reflect.New(t)
-
-		if rc := GetAttributeStructure(n.Elem().Interface(), name, depth+1); rc.Name != "" {
-			return rc
-		}
-
-	case reflect.Struct:
-		for i := 0; i < obj.NumField(); i++ {
-			v := reflect.Indirect(obj)
-			json := strings.Split(obj.Type().Field(i).Tag.Get("json"), ",")
-
-			if json[0] == name {
-				return v.Type().Field(i)
-			}
-
-			if obj.Field(i).IsValid() {
-				if rc := GetAttributeStructure(obj.Field(i).Interface(), name, depth+1); rc.Name != "" {
-					return rc
-				}
-			}
-		}
-
-	case reflect.Slice:
-		s := reflect.MakeSlice(obj.Type(), 1, 1)
-		n := reflect.New(obj.Type())
-		n.Elem().Set(s)
-
-		for i := 0; i < obj.Len(); i++ {
-			if rc := GetAttributeStructure(obj.Index(i).Interface(), name, depth+1); rc.Name != "" {
-				return rc
-			}
-
-		}
-	default:
-		//log.Debugf("%s Unhandled <%+v> ... It's a %+v\n", prefix, obj, k)
-	}
-
-	return result
-
-}
-
-func clone2(a interface{}) interface{} {
-	b := reflect.ValueOf(a)
-	buff := new(bytes.Buffer)
-	enc := gob.NewEncoder(buff)
-	dec := gob.NewDecoder(buff)
-	enc.Encode(a)
-	dec.Decode(b.Elem().Interface())
-
-	return b.Interface()
-}
-
-func clone(a, b interface{}) interface{} {
-	buff := new(bytes.Buffer)
-	enc := gob.NewEncoder(buff)
-	dec := gob.NewDecoder(buff)
-	enc.Encode(a)
-	dec.Decode(b)
-	return b
-}
diff --git a/pkg/ponresourcemanager/ponresourcemanager.go b/pkg/ponresourcemanager/ponresourcemanager.go
index 279dc35..0abe6c1 100755
--- a/pkg/ponresourcemanager/ponresourcemanager.go
+++ b/pkg/ponresourcemanager/ponresourcemanager.go
@@ -23,9 +23,9 @@
 	"fmt"
 	"strconv"
 
-	bitmap "github.com/boljen/go-bitmap"
+	"github.com/boljen/go-bitmap"
+	"github.com/opencord/voltha-lib-go/v2/pkg/db"
 	"github.com/opencord/voltha-lib-go/v2/pkg/db/kvstore"
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/model"
 	"github.com/opencord/voltha-lib-go/v2/pkg/log"
 	tp "github.com/opencord/voltha-lib-go/v2/pkg/techprofile"
 )
@@ -128,7 +128,7 @@
 	Host           string // host ip of the KV store
 	Port           int    // port number for the KV store
 	OLTModel       string
-	KVStore        *model.Backend
+	KVStore        *db.Backend
 	TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
 
 	// Below attribute, pon_resource_ranges, should be initialized
@@ -151,7 +151,7 @@
 	return nil, errors.New("unsupported-kv-store")
 }
 
-func SetKVClient(Technology string, Backend string, Host string, Port int) *model.Backend {
+func SetKVClient(Technology string, Backend string, Host string, Port int) *db.Backend {
 	addr := Host + ":" + strconv.Itoa(Port)
 	// TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
 	// issue between kv store and backend , core is not calling NewBackend directly
@@ -160,7 +160,7 @@
 		log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
 		return nil
 	}
-	kvbackend := &model.Backend{
+	kvbackend := &db.Backend{
 		Client:     kvClient,
 		StoreType:  Backend,
 		Host:       Host,
diff --git a/pkg/techprofile/config.go b/pkg/techprofile/config.go
index 3a45af1..9c64bd8 100644
--- a/pkg/techprofile/config.go
+++ b/pkg/techprofile/config.go
@@ -16,7 +16,7 @@
 package techprofile
 
 import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/model"
+	"github.com/opencord/voltha-lib-go/v2/pkg/db"
 )
 
 // tech profile default constants
@@ -83,7 +83,7 @@
 	KVStorePort          int
 	KVStoreType          string
 	KVStoreTimeout       int
-	KVBackend            *model.Backend
+	KVBackend            *db.Backend
 	TPKVPathPrefix       string
 	TPFileKVPath         string
 	TPInstanceKVPath     string
diff --git a/pkg/techprofile/tech_profile.go b/pkg/techprofile/tech_profile.go
index ea7b36a..92569f0 100644
--- a/pkg/techprofile/tech_profile.go
+++ b/pkg/techprofile/tech_profile.go
@@ -22,8 +22,8 @@
 	"fmt"
 	"strconv"
 
+	"github.com/opencord/voltha-lib-go/v2/pkg/db"
 	"github.com/opencord/voltha-lib-go/v2/pkg/db/kvstore"
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/model"
 	"github.com/opencord/voltha-lib-go/v2/pkg/log"
 	tp_pb "github.com/opencord/voltha-protos/v2/go/tech_profile"
 )
@@ -226,7 +226,7 @@
 	DownstreamGemPortAttributeList []iGemPortAttribute `json:"downstream_gem_port_attribute_list"`
 }
 
-func (t *TechProfileMgr) SetKVClient() *model.Backend {
+func (t *TechProfileMgr) SetKVClient() *db.Backend {
 	addr := t.config.KVStoreHost + ":" + strconv.Itoa(t.config.KVStorePort)
 	kvClient, err := newKVClient(t.config.KVStoreType, addr, t.config.KVStoreTimeout)
 	if err != nil {
@@ -238,7 +238,7 @@
 			})
 		return nil
 	}
-	return &model.Backend{
+	return &db.Backend{
 		Client:     kvClient,
 		StoreType:  t.config.KVStoreType,
 		Host:       t.config.KVStoreHost,
diff --git a/pkg/techprofile/tech_profile_if.go b/pkg/techprofile/tech_profile_if.go
index 0904d7e..3267759 100644
--- a/pkg/techprofile/tech_profile_if.go
+++ b/pkg/techprofile/tech_profile_if.go
@@ -17,12 +17,12 @@
 package techprofile
 
 import (
-	"github.com/opencord/voltha-lib-go/v2/pkg/db/model"
+	"github.com/opencord/voltha-lib-go/v2/pkg/db"
 	tp_pb "github.com/opencord/voltha-protos/v2/go/tech_profile"
 )
 
 type TechProfileIf interface {
-	SetKVClient() *model.Backend
+	SetKVClient() *db.Backend
 	GetTechProfileInstanceKVPath(techProfiletblID uint32, uniPortName string) string
 	GetTPInstanceFromKVStore(techProfiletblID uint32, path string) (*TechProfile, error)
 	CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) *TechProfile
