VOL-1497 : Add more control to kv/memory access

- Added kv locking mechanism (etcd only)
- (watch) control path access whenever possible
- (watch) use a transaction for updates and merge with memory
- cleaned up vendoring
- misc changes to fix exceptions found along the way

Amendments:

- Copyright header got removed in auto-generated file
- Changed default locking to false for KV list operation
- Updated backend api to allow the passing of locking parameter

Change-Id: Ie1a55d3ca8b9d92ae71a85ce42bb22fcf1419e2c
diff --git a/db/model/node.go b/db/model/node.go
index 77ca565..707fe75 100644
--- a/db/model/node.go
+++ b/db/model/node.go
@@ -114,6 +114,9 @@
 
 // makeLatest will mark the revision of a node as being the latest
 func (n *node) makeLatest(branch *Branch, revision Revision, changeAnnouncement []ChangeTuple) {
+	n.Lock()
+	defer n.Unlock()
+
 	branch.AddRevision(revision)
 
 	if branch.GetLatest() == nil || revision.GetHash() != branch.GetLatest().GetHash() {
@@ -121,17 +124,17 @@
 	}
 
 	if changeAnnouncement != nil && branch.Txid == "" {
-		if n.GetProxy() != nil {
+		if n.Proxy != nil {
 			for _, change := range changeAnnouncement {
-				log.Debugw("invoking callback",
-					log.Fields{
-						"callbacks":    n.GetProxy().getCallbacks(change.Type),
-						"type":         change.Type,
-						"previousData": change.PreviousData,
-						"latestData":   change.LatestData,
-					})
-				n.GetRoot().AddCallback(
-					n.GetProxy().InvokeCallbacks,
+				//log.Debugw("invoking callback",
+				//	log.Fields{
+				//		"callbacks":    n.Proxy.getCallbacks(change.Type),
+				//		"type":         change.Type,
+				//		"previousData": change.PreviousData,
+				//		"latestData":   change.LatestData,
+				//	})
+				n.Root.AddCallback(
+					n.Proxy.InvokeCallbacks,
 					change.Type,
 					true,
 					change.PreviousData,
@@ -139,18 +142,18 @@
 			}
 		}
 
-		for _, change := range changeAnnouncement {
-			log.Debugf("sending notification - changeType: %+v, previous:%+v, latest: %+v",
-				change.Type,
-				change.PreviousData,
-				change.LatestData)
-			n.GetRoot().AddNotificationCallback(
-				n.makeEventBus().Advertise,
-				change.Type,
-				revision.GetHash(),
-				change.PreviousData,
-				change.LatestData)
-		}
+		//for _, change := range changeAnnouncement {
+		//log.Debugf("sending notification - changeType: %+v, previous:%+v, latest: %+v",
+		//	change.Type,
+		//	change.PreviousData,
+		//	change.LatestData)
+		//n.Root.AddNotificationCallback(
+		//	n.makeEventBus().Advertise,
+		//	change.Type,
+		//	revision.GetHash(),
+		//	change.PreviousData,
+		//	change.LatestData)
+		//}
 	}
 }
 
@@ -284,12 +287,9 @@
 }
 
 // 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
-	}
-
+func (n *node) Get(path string, hash string, depth int, reconcile bool, txid string) interface{} {
+	log.Debugw("node-get-request", log.Fields{"path": path, "hash": hash, "depth": depth, "reconcile": reconcile,
+		"txid": txid})
 	for strings.HasPrefix(path, "/") {
 		path = path[1:]
 	}
@@ -308,11 +308,20 @@
 	}
 
 	var result interface{}
-	if result = n.getPath(rev.GetBranch().GetLatest(), path, depth);
-		(result == nil || reflect.ValueOf(result).IsValid() && reflect.ValueOf(result).IsNil()) && n.Root.KvStore != nil {
-		// We got nothing from memory, try to pull it from persistence
+
+	// If there is not request to reconcile, try to get it from memory
+	if !reconcile {
+		if result = n.getPath(rev.GetBranch().GetLatest(), path, depth);
+			result != nil && reflect.ValueOf(result).IsValid() && !reflect.ValueOf(result).IsNil() {
+			return result
+		}
+	}
+
+	// If we got to this point, we are either trying to reconcile with the db or
+	// or we simply failed at getting information from memory
+	if n.Root.KvStore != nil {
 		var prList []interface{}
-		if pr := rev.LoadFromPersistence(path, txid); pr != nil {
+		if pr := rev.LoadFromPersistence(path, txid); pr != nil && len(pr) > 0 {
 			// Did we receive a single or multiple revisions?
 			if len(pr) > 1 {
 				for _, revEntry := range pr {
@@ -551,7 +560,7 @@
 
 		// FIXME VOL-1293: the following statement corrupts the kv when using a subproxy (commenting for now)
 		// FIXME VOL-1293 cont'd: need to figure out the required conditions otherwise we are not cleaning up entries
-		//branch.GetLatest().Drop(branch.Txid, true)
+		branch.GetLatest().Drop(branch.Txid, false)
 
 		n.makeLatest(branch, rev, changes)
 
@@ -611,7 +620,7 @@
 
 				if _, exists := n.findRevByKey(children, field.Key, key.String()); exists != nil {
 					// TODO raise error
-					log.Warnw("duplicate-key-found", log.Fields{"key":key.String()})
+					log.Warnw("duplicate-key-found", log.Fields{"key": key.String()})
 					return exists
 				}
 				childRev := n.MakeNode(data, "").Latest()
@@ -809,6 +818,7 @@
 
 	if !dryRun {
 		if rev != nil {
+			rev.SetHash(dstRev.GetHash())
 			n.makeLatest(dstBranch, rev, changes)
 		}
 		n.DeleteBranch(txid)