VOL-1459 : Ensure data model synchronization from kv

- Introduced a new List function to force a load from persistence
- Properly create a proxy for non-keyed nodes (e.g. /adapters)
- Optimized load from persistence operation to avoid existing entries
- Fixed/Enhanced proxy unit test

Change-Id: Ib368d32c517e74410b541bb8927429d066a9cfd0
diff --git a/db/model/node.go b/db/model/node.go
index 67848eb..7ea4417 100644
--- a/db/model/node.go
+++ b/db/model/node.go
@@ -125,10 +125,10 @@
 			for _, change := range changeAnnouncement {
 				log.Debugw("invoking callback",
 					log.Fields{
-						"callbacks": n.GetProxy().getCallbacks(change.Type),
-						"type":change.Type,
+						"callbacks":    n.GetProxy().getCallbacks(change.Type),
+						"type":         change.Type,
 						"previousData": change.PreviousData,
-						"latestData": change.LatestData,
+						"latestData":   change.LatestData,
 					})
 				n.GetRoot().AddCallback(
 					n.GetProxy().InvokeCallbacks,
@@ -248,7 +248,44 @@
 }
 
 // Get retrieves the data from a node tree that resides at the specified path
+func (n *node) List(path string, hash string, depth int, deep bool, txid string) interface{} {
+	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(path, txid); 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(path string, hash string, depth int, deep bool, txid string) interface{} {
+	log.Debugw("node-get-request", log.Fields{"path": path, "hash": hash, "depth":depth, "deep":deep, "txid":txid})
 	if deep {
 		depth = -1
 	}
@@ -355,7 +392,7 @@
 	var modifiedMsg interface{}
 
 	if n.GetProxy() != nil {
-		log.Debug("invoking proxy GET Callbacks : %+v", msg)
+		log.Debugw("invoking-get-callbacks", log.Fields{"data": msg})
 		if modifiedMsg = n.GetProxy().InvokeCallbacks(GET, false, msg); modifiedMsg != nil {
 			msg = modifiedMsg
 		}
@@ -367,6 +404,8 @@
 
 // Update changes the content of a node at the specified path with the provided data
 func (n *node) Update(path string, data interface{}, strict bool, txid string, makeBranch MakeBranchFunction) Revision {
+	log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid":txid, "makeBranch": makeBranch})
+
 	for strings.HasPrefix(path, "/") {
 		path = path[1:]
 	}
@@ -396,9 +435,14 @@
 		path = partition[1]
 	}
 
+
 	field := ChildrenFields(n.Type)[name]
 	var children []Revision
 
+	if field == nil {
+		return n.doUpdate(branch, data, strict)
+	}
+
 	if field.IsContainer {
 		if path == "" {
 			log.Errorf("cannot update a list")
@@ -515,12 +559,15 @@
 
 // Add inserts a new node at the specified path with the provided data
 func (n *node) Add(path string, data interface{}, txid string, makeBranch MakeBranchFunction) Revision {
+	log.Debugw("node-add-request", log.Fields{"path": path, "txid":txid, "makeBranch": makeBranch})
+
 	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
@@ -622,6 +669,8 @@
 
 // Remove eliminates a node at the specified path
 func (n *node) Remove(path string, txid string, makeBranch MakeBranchFunction) Revision {
+	log.Debugw("node-remove-request", log.Fields{"path": path, "txid":txid, "makeBranch": makeBranch})
+
 	for strings.HasPrefix(path, "/") {
 		path = path[1:]
 	}
@@ -820,7 +869,8 @@
 	if field.IsContainer {
 		if path == "" {
 			//log.Error("cannot proxy a container field")
-			return n.makeProxy(path, fullPath, parentNode, exclusive)
+			newNode := n.MakeNode(reflect.New(field.ClassType.Elem()).Interface(), "")
+			return newNode.makeProxy(path, fullPath, parentNode, exclusive)
 		} else if field.Key != "" {
 			partition := strings.SplitN(path, "/", 2)
 			key := partition[0]