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/persisted_revision.go b/db/model/persisted_revision.go
index 98e80e4..ecef3ae 100644
--- a/db/model/persisted_revision.go
+++ b/db/model/persisted_revision.go
@@ -172,37 +172,44 @@
 		field := ChildrenFields(rev.GetBranch().Node.Type)[name]
 
 		if field.IsContainer {
+			var children []Revision
+			children = make([]Revision, len(rev.GetChildren(name)))
+			copy(children, rev.GetChildren(name))
+			existChildMap := make(map[string]int)
+			for i, child := range rev.GetChildren(name) {
+				existChildMap[child.GetHash()] = i
+			}
+
 			for _, blob := range blobMap {
 				output := blob.Value.([]byte)
 
 				data := reflect.New(field.ClassType.Elem())
 
 				if err := proto.Unmarshal(output, data.Interface().(proto.Message)); err != nil {
-					// TODO report error
+					log.Errorw(
+						"loading-from-persistence--failed-to-unmarshal",
+						log.Fields{"path": path, "txid": txid, "error": err},
+					)
 				} else {
-
-					var children []Revision
-
 					if path == "" {
 						if field.Key != "" {
 							// e.g. /logical_devices/abcde --> path="" name=logical_devices key=abcde
 							if field.Key != "" {
-								children = make([]Revision, len(rev.GetChildren(name)))
-								copy(children, rev.GetChildren(name))
-
 								_, key := GetAttributeValue(data.Interface(), field.Key, 0)
 
 								childRev := rev.GetBranch().Node.MakeNode(data.Interface(), txid).Latest(txid)
 								childRev.SetHash(name + "/" + key.String())
 
-								// Create watch for <component>/<key>
-								pr.SetupWatch(childRev.GetHash())
+								// Do not process a child that is already in memory
+								if _, childExists := existChildMap[childRev.GetHash()]; !childExists {
+									// Create watch for <component>/<key>
+									pr.SetupWatch(childRev.GetHash())
 
-								children = append(children, childRev)
-								rev = rev.UpdateChildren(name, children, rev.GetBranch())
+									children = append(children, childRev)
+									rev = rev.UpdateChildren(name, children, rev.GetBranch())
 
-								rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
-
+									rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
+								}
 								response = append(response, childRev)
 								continue
 							}
@@ -219,9 +226,6 @@
 						}
 						keyValue := field.KeyFromStr(key)
 
-						children = make([]Revision, len(rev.GetChildren(name)))
-						copy(children, rev.GetChildren(name))
-
 						idx, childRev := rev.GetBranch().Node.findRevByKey(children, field.Key, keyValue)
 
 						newChildRev := childRev.LoadFromPersistence(path, txid)