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{}