VOL-1543 : Fix to properly delete a device from storage

Change-Id: I52d37d947ee6aaf4108fb8252951a123a2829d0c
diff --git a/db/model/node.go b/db/model/node.go
index aeac883..2a9309c 100644
--- a/db/model/node.go
+++ b/db/model/node.go
@@ -501,7 +501,7 @@
 			}
 
 			// Prefix the hash value with the data type (e.g. devices, logical_devices, adapters)
-			newChildRev.SetHash(name + "/" + _keyValueType)
+			newChildRev.SetName(name + "/" + _keyValueType)
 			children[idx] = newChildRev
 
 			updatedRev := rev.UpdateChildren(name, children, branch)
@@ -626,10 +626,10 @@
 				childRev := n.MakeNode(data, "").Latest()
 
 				// Prefix the hash with the data type (e.g. devices, logical_devices, adapters)
-				childRev.SetHash(name + "/" + key.String())
+				childRev.SetName(name + "/" + key.String())
 
 				// Create watch for <component>/<key>
-				childRev.SetupWatch(childRev.GetHash())
+				childRev.SetupWatch(childRev.GetName())
 
 				children = append(children, childRev)
 				rev = rev.UpdateChildren(name, children, branch)
@@ -661,7 +661,7 @@
 			newChildRev := childNode.Add(path, data, txid, makeBranch)
 
 			// Prefix the hash with the data type (e.g. devices, logical_devices, adapters)
-			childRev.SetHash(name + "/" + keyValue.(string))
+			childRev.SetName(name + "/" + keyValue.(string))
 
 			children[idx] = newChildRev
 
@@ -751,7 +751,7 @@
 					postAnnouncement = append(postAnnouncement, ChangeTuple{POST_REMOVE, childRev.GetData(), nil})
 				}
 
-				childRev.Drop(txid, true)
+				childRev.StorageDrop(txid, true)
 				children = append(children[:idx], children[idx+1:]...)
 				rev.SetChildren(name, children)
 
@@ -818,7 +818,7 @@
 
 	if !dryRun {
 		if rev != nil {
-			rev.SetHash(dstRev.GetHash())
+			rev.SetName(dstRev.GetName())
 			n.makeLatest(dstBranch, rev, changes)
 		}
 		n.DeleteBranch(txid)
diff --git a/db/model/non_persisted_revision.go b/db/model/non_persisted_revision.go
index 1b9325d..3c39e01 100644
--- a/db/model/non_persisted_revision.go
+++ b/db/model/non_persisted_revision.go
@@ -49,6 +49,7 @@
 	Hash     string
 	Branch   *Branch
 	WeakRef  string
+	Name     string
 }
 
 func NewNonPersistedRevision(root *root, branch *Branch, data interface{}, children map[string][]Revision) Revision {
@@ -57,6 +58,7 @@
 	r.Branch = branch
 	r.Config = NewDataRevision(root, data)
 	r.Children = children
+	r.Hash = r.hashContent()
 	return r
 }
 
@@ -119,6 +121,17 @@
 	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()
@@ -343,4 +356,8 @@
 
 func (npr *NonPersistedRevision) SetupWatch(key string) {
 	// stub ... required by interface
-}
\ No newline at end of file
+}
+
+func (pr *NonPersistedRevision) StorageDrop(txid string, includeConfig bool) {
+	// stub ... required by interface
+}
diff --git a/db/model/persisted_revision.go b/db/model/persisted_revision.go
index f335216..c2a6c64 100644
--- a/db/model/persisted_revision.go
+++ b/db/model/persisted_revision.go
@@ -40,7 +40,6 @@
 	mutex     sync.RWMutex        `json:"-"`
 	isStored  bool
 	isWatched bool
-	watchName string
 }
 
 // NewPersistedRevision creates a new instance of a PersistentRevision structure
@@ -66,8 +65,8 @@
 		return
 	}
 
-	if pair, _ := pr.kvStore.Get(pr.GetHash()); pair != nil && skipOnExist {
-		log.Debugw("revision-config-already-exists", log.Fields{"hash": pr.GetHash()})
+	if pair, _ := pr.kvStore.Get(pr.GetName()); pair != nil && skipOnExist {
+		log.Debugw("revision-config-already-exists", log.Fields{"hash": pr.GetHash(), "name": pr.GetName()})
 		return
 	}
 
@@ -82,12 +81,11 @@
 			blob = b.Bytes()
 		}
 
-		if err := pr.kvStore.Put(pr.GetHash(), blob); err != nil {
+		if err := pr.kvStore.Put(pr.GetName(), blob); err != nil {
 			log.Warnw("problem-storing-revision-config",
-				log.Fields{"error": err, "hash": pr.GetHash(), "data": pr.GetConfig().Data})
+				log.Fields{"error": err, "hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetConfig().Data})
 		} else {
-			log.Debugw("storing-revision-config",
-				log.Fields{"hash": pr.GetHash(), "data": pr.GetConfig().Data})
+			log.Debugw("storing-revision-config", log.Fields{"hash": pr.GetHash(), "name": pr.GetName(), "data": pr.GetConfig().Data})
 			pr.isStored = true
 		}
 	}
@@ -99,7 +97,7 @@
 
 		log.Debugw("setting-watch", log.Fields{"key": key, "revision-hash": pr.GetHash()})
 
-		pr.watchName = key
+		pr.SetName(key)
 		pr.events = pr.kvStore.CreateWatch(key)
 
 		pr.isWatched = true
@@ -109,57 +107,6 @@
 	}
 }
 
-//func (pr *PersistedRevision) mergeWithMemory(pacBlock bool) Revision {
-//	if pair, err := pr.kvStore.Get(pr.GetHash()); err != nil {
-//		log.Debugw("merge-with-memory--error-occurred", log.Fields{"hash": pr.GetHash(), "error": err})
-//	} else if pair == nil {
-//		log.Debugw("merge-with-memory--no-data-to-merge", log.Fields{"hash": pr.GetHash()})
-//	} else {
-//		data := reflect.New(reflect.TypeOf(pr.GetData()).Elem()).Interface()
-//
-//		if err := proto.Unmarshal(pair.Value.([]byte), data.(proto.Message)); err != nil {
-//			log.Errorw("merge-with-memory--unmarshal-failed", log.Fields{"key": pr.GetHash(), "error": err})
-//		} else {
-//			if pr.GetNode().GetProxy() != nil && pacBlock {
-//				var pac *proxyAccessControl
-//				var pathLock string
-//
-//				pathLock, _ = pr.GetNode().GetProxy().parseForControlledPath(pr.GetNode().GetProxy().getFullPath())
-//				log.Debugw("update-in-memory--reserve-and-lock", log.Fields{"key": pr.GetHash(), "path": pathLock})
-//
-//				pac = PAC().ReservePath(pr.GetNode().GetProxy().getFullPath(), pr.GetNode().GetProxy(), pathLock)
-//				pac.SetProxy(pr.GetNode().GetProxy())
-//				pac.lock()
-//
-//				defer log.Debugw("update-in-memory--release-and-unlock", log.Fields{"key": pr.GetHash(), "path": pathLock})
-//				defer pac.unlock()
-//				defer PAC().ReleasePath(pathLock)
-//			}
-//			//Prepare the transaction
-//			branch := pr.GetBranch()
-//			//latest := branch.GetLatest()
-//			txidBin, _ := uuid.New().MarshalBinary()
-//			txid := hex.EncodeToString(txidBin)[:12]
-//
-//			makeBranch := func(node *node) *Branch {
-//				return node.MakeBranch(txid)
-//			}
-//
-//			//Apply the update in a transaction branch
-//			updatedRev := pr.GetNode().Update("", data, false, txid, makeBranch)
-//			updatedRev.SetHash(pr.GetHash())
-//
-//			//Merge the transaction branch in memory
-//			if mergedRev, _ := pr.GetNode().MergeBranch(txid, false); mergedRev != nil {
-//				branch.SetLatest(mergedRev)
-//				return mergedRev
-//			}
-//		}
-//	}
-//
-//	return nil
-//}
-
 func (pr *PersistedRevision) updateInMemory(data interface{}) {
 	pr.mutex.Lock()
 	defer pr.mutex.Unlock()
@@ -223,7 +170,7 @@
 
 	// Apply the update in a transaction branch
 	updatedRev := latest.GetNode().Update("", data, false, txid, makeBranch)
-	updatedRev.SetHash(latest.GetHash())
+	updatedRev.SetName(latest.GetName())
 
 	// Merge the transaction branch in memory
 	if mergedRev, _ := latest.GetNode().MergeBranch(txid, false); mergedRev != nil {
@@ -239,40 +186,40 @@
 		select {
 		case event, ok := <-pr.events:
 			if !ok {
-				log.Errorw("event-channel-failure: stopping watch loop", log.Fields{"key": pr.GetHash(), "watch": pr.watchName})
+				log.Errorw("event-channel-failure: stopping watch loop", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
 				break StopWatchLoop
 			}
 
-			log.Debugw("received-event", log.Fields{"type": event.EventType, "watch": pr.watchName})
+			log.Debugw("received-event", log.Fields{"type": event.EventType, "watch": pr.GetName()})
 
 			switch event.EventType {
 			case kvstore.DELETE:
-				log.Debugw("delete-from-memory", log.Fields{"key": pr.GetHash(), "watch": pr.watchName})
+				log.Debugw("delete-from-memory", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
 				pr.Revision.Drop("", true)
 				break StopWatchLoop
 
 			case kvstore.PUT:
-				log.Debugw("update-in-memory", log.Fields{"key": pr.GetHash(), "watch": pr.watchName})
+				log.Debugw("update-in-memory", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
 
-				if dataPair, err := pr.kvStore.Get(pr.watchName); err != nil || dataPair == nil {
-					log.Errorw("update-in-memory--key-retrieval-failed", log.Fields{"key": pr.GetHash(), "watch": pr.watchName, "error": err})
+				if dataPair, err := pr.kvStore.Get(pr.GetName()); err != nil || dataPair == nil {
+					log.Errorw("update-in-memory--key-retrieval-failed", log.Fields{"key": pr.GetHash(), "watch": pr.GetName(), "error": err})
 				} else {
 					data := reflect.New(reflect.TypeOf(pr.GetData()).Elem())
 
 					if err := proto.Unmarshal(dataPair.Value.([]byte), data.Interface().(proto.Message)); err != nil {
-						log.Errorw("update-in-memory--unmarshal-failed", log.Fields{"key": pr.GetHash(), "watch": pr.watchName, "error": err})
+						log.Errorw("update-in-memory--unmarshal-failed", log.Fields{"key": pr.GetHash(), "watch": pr.GetName(), "error": err})
 					} else {
 						pr.updateInMemory(data.Interface())
 					}
 				}
 
 			default:
-				log.Debugw("unhandled-event", log.Fields{"key": pr.GetHash(), "watch": pr.watchName, "type": event.EventType})
+				log.Debugw("unhandled-event", log.Fields{"key": pr.GetHash(), "watch": pr.GetName(), "type": event.EventType})
 			}
 		}
 	}
 
-	log.Debugw("exiting-watch", log.Fields{"key": pr.GetHash(), "watch": pr.watchName})
+	log.Debugw("exiting-watch", log.Fields{"key": pr.GetHash(), "watch": pr.GetName()})
 }
 
 func (pr *PersistedRevision) LoadFromPersistence(path string, txid string) []Revision {
@@ -356,12 +303,12 @@
 					}
 
 					childRev := rev.GetBranch().Node.MakeNode(data.Interface(), txid).Latest(txid)
-					childRev.SetHash(name + "/" + keyStr)
+					childRev.SetName(name + "/" + keyStr)
 
 					// Do not process a child that is already in memory
 					if _, childExists := existChildMap[childRev.GetHash()]; !childExists {
 						// Create watch for <component>/<key>
-						childRev.SetupWatch(childRev.GetHash())
+						childRev.SetupWatch(childRev.GetName())
 
 						children = append(children, childRev)
 						rev = rev.UpdateChildren(name, children, rev.GetBranch())
@@ -426,6 +373,12 @@
 // 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, "stack": string(debug.Stack())})
 
@@ -433,22 +386,16 @@
 	defer pr.mutex.Unlock()
 	if pr.kvStore != nil && txid == "" {
 		if pr.isStored {
-			if includeConfig {
-				if err := pr.kvStore.Delete(pr.GetConfig().Hash); err != nil {
-					log.Errorw("failed-to-remove-revision-config", log.Fields{"hash": pr.GetConfig().Hash, "error": err.Error()})
-				}
+			if pr.isWatched {
+				pr.kvStore.DeleteWatch(pr.GetName(), pr.events)
+				pr.isWatched = false
 			}
 
-			if err := pr.kvStore.Delete(pr.GetHash()); err != nil {
+			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
 			}
-
-			if pr.isWatched {
-				pr.kvStore.DeleteWatch(pr.GetHash(), pr.events)
-				pr.isWatched = false
-			}
 		}
 
 	} else {
diff --git a/db/model/revision.go b/db/model/revision.go
index 51f7a1a..2c10137 100644
--- a/db/model/revision.go
+++ b/db/model/revision.go
@@ -20,6 +20,7 @@
 	SetConfig(revision *DataRevision)
 	GetConfig() *DataRevision
 	Drop(txid string, includeConfig bool)
+	StorageDrop(txid string, includeConfig bool)
 	SetChildren(name string, children []Revision)
 	GetChildren(name string) []Revision
 	SetAllChildren(children map[string][]Revision)
@@ -28,6 +29,8 @@
 	GetHash() string
 	ClearHash()
 	SetupWatch(key string)
+	SetName(name string)
+	GetName() string
 	SetBranch(branch *Branch)
 	GetBranch() *Branch
 	Get(int) interface{}