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/proxy_test.go b/db/model/proxy_test.go
index ea15bac..0180ce1 100644
--- a/db/model/proxy_test.go
+++ b/db/model/proxy_test.go
@@ -33,7 +33,9 @@
 	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
@@ -43,6 +45,7 @@
 	TestProxy_Flows                 *openflow_13.Flows
 	TestProxy_Device                *voltha.Device
 	TestProxy_LogicalDevice         *voltha.LogicalDevice
+	TestProxy_Adapter               *voltha.Adapter
 )
 
 func init() {
@@ -51,6 +54,7 @@
 	TestProxy_Root = NewRoot(&voltha.Voltha{}, nil)
 	TestProxy_Root_LogicalDevice = TestProxy_Root.CreateProxy("/", false)
 	TestProxy_Root_Device = TestProxy_Root.CreateProxy("/", false)
+	TestProxy_Root_Adapter = TestProxy_Root.CreateProxy("/", false)
 
 	TestProxy_LogicalPorts = []*voltha.LogicalPort{
 		{
@@ -93,6 +97,12 @@
 		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) {
@@ -143,6 +153,39 @@
 	}
 }
 
+func TestProxy_1_1_3_Add_NewAdapter(t *testing.T) {
+	TestProxy_AdapterId = "test-adapter"
+	TestProxy_Adapter.Id = TestProxy_AdapterId
+	preAddExecuted := false
+	postAddExecuted := false
+
+	// Register ADD instructions callbacks
+	TestProxy_Root_Adapter.RegisterCallback(PRE_ADD, commonCallback, "PRE_ADD instructions for adapters", &preAddExecuted)
+	TestProxy_Root_Adapter.RegisterCallback(POST_ADD, commonCallback, "POST_ADD instructions for adapters", &postAddExecuted)
+
+	// Add the adapter
+	if added := TestProxy_Root_Adapter.Add("/adapters", TestProxy_Adapter, ""); added == nil {
+		t.Error("Failed to add adapter")
+	} else {
+		t.Logf("Added adapter : %+v", added)
+	}
+
+	// Verify that the added device can now be retrieved
+	if d := TestProxy_Root_Adapter.Get("/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 !preAddExecuted {
+		t.Error("PRE_ADD callback was not executed")
+	}
+	if !postAddExecuted {
+		t.Error("POST_ADD callback was not executed")
+	}
+}
+
 func TestProxy_1_2_1_Get_AllDevices(t *testing.T) {
 	devices := TestProxy_Root_Device.Get("/devices", 1, false, "")
 
@@ -270,6 +313,52 @@
 	}
 }
 
+func TestProxy_1_3_3_Update_Adapter(t *testing.T) {
+	preUpdateExecuted := false
+	postUpdateExecuted := false
+
+	adaptersProxy := TestProxy_Root.node.CreateProxy("/adapters", false)
+
+	if retrieved := TestProxy_Root_Adapter.Get("/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,
+			commonCallback,
+			"PRE_UPDATE instructions for adapters", &preUpdateExecuted,
+		)
+		adaptersProxy.RegisterCallback(
+			POST_UPDATE,
+			commonCallback,
+			"POST_UPDATE instructions for adapters", &postUpdateExecuted,
+		)
+
+		if afterUpdate := adaptersProxy.Update("/"+TestProxy_AdapterId, retrieved, false, ""); afterUpdate == nil {
+			t.Error("Failed to update adapter")
+		} else {
+			t.Logf("Updated adapter : %+v", afterUpdate)
+		}
+
+		if d := TestProxy_Root_Adapter.Get("/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)
+		}
+
+		if !preUpdateExecuted {
+			t.Error("PRE_UPDATE callback for adapter was not executed")
+		}
+		if !postUpdateExecuted {
+			t.Error("POST_UPDATE callback for adapter was not executed")
+		}
+	}
+}
+
 func TestProxy_1_4_1_Remove_Device(t *testing.T) {
 	preRemoveExecuted := false
 	postRemoveExecuted := false