VOL-1459 : Fix failure to load device from persistence
- fixed watch logic which was not really updating memory
- force get depth to 0 to work around corrupted data structures
Change-Id: I595981e2ee3d816d17702e7f39c099193590fa6f
diff --git a/db/model/node.go b/db/model/node.go
index 7ea4417..7b05f8e 100644
--- a/db/model/node.go
+++ b/db/model/node.go
@@ -249,7 +249,7 @@
// Get retrieves the data from a node tree that resides at the specified path
func (n *node) List(path string, hash string, depth int, deep bool, txid string) interface{} {
- log.Debugw("node-list-request", log.Fields{"path": path, "hash": hash, "depth":depth, "deep":deep, "txid":txid})
+ log.Debugw("node-list-request", log.Fields{"path": path, "hash": hash, "depth": depth, "deep": deep, "txid": txid})
if deep {
depth = -1
}
@@ -285,7 +285,7 @@
// 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})
+ log.Debugw("node-get-request", log.Fields{"path": path, "hash": hash, "depth": depth, "deep": deep, "txid": txid})
if deep {
depth = -1
}
@@ -309,14 +309,19 @@
var result interface{}
if result = n.getPath(rev.GetBranch().GetLatest(), path, depth);
- reflect.ValueOf(result).IsValid() && reflect.ValueOf(result).IsNil() && n.Root.KvStore != nil {
+ (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
var prList []interface{}
if pr := rev.LoadFromPersistence(path, txid); pr != nil {
- for _, revEntry := range pr {
- prList = append(prList, revEntry.GetData())
+ // Did we receive a single or multiple revisions?
+ if len(pr) > 1 {
+ for _, revEntry := range pr {
+ prList = append(prList, revEntry.GetData())
+ }
+ result = prList
+ } else {
+ result = pr[0].GetData()
}
- result = prList
}
}
@@ -404,7 +409,7 @@
// Update changes the content of a node at the specified path with the provided data
func (n *node) Update(path string, data interface{}, strict bool, txid string, makeBranch MakeBranchFunction) Revision {
- log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid":txid, "makeBranch": makeBranch})
+ log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid": txid, "makeBranch": makeBranch})
for strings.HasPrefix(path, "/") {
path = path[1:]
@@ -435,7 +440,6 @@
path = partition[1]
}
-
field := ChildrenFields(n.Type)[name]
var children []Revision
@@ -559,7 +563,7 @@
// Add inserts a new node at the specified path with the provided data
func (n *node) Add(path string, data interface{}, txid string, makeBranch MakeBranchFunction) Revision {
- log.Debugw("node-add-request", log.Fields{"path": path, "txid":txid, "makeBranch": makeBranch})
+ log.Debugw("node-add-request", log.Fields{"path": path, "txid": txid, "makeBranch": makeBranch})
for strings.HasPrefix(path, "/") {
path = path[1:]
@@ -669,7 +673,7 @@
// Remove eliminates a node at the specified path
func (n *node) Remove(path string, txid string, makeBranch MakeBranchFunction) Revision {
- log.Debugw("node-remove-request", log.Fields{"path": path, "txid":txid, "makeBranch": makeBranch})
+ log.Debugw("node-remove-request", log.Fields{"path": path, "txid": txid, "makeBranch": makeBranch})
for strings.HasPrefix(path, "/") {
path = path[1:]
diff --git a/db/model/persisted_revision.go b/db/model/persisted_revision.go
index ecef3ae..b21deeb 100644
--- a/db/model/persisted_revision.go
+++ b/db/model/persisted_revision.go
@@ -136,7 +136,9 @@
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(), "error": err})
} else {
- pr.UpdateData(data.Interface(), pr.GetBranch())
+ // Traverse the node and update as necessary
+ rev := pr.GetBranch().GetLatest()
+ rev.GetBranch().Node.Update("", data.Interface(), false, "", nil)
}
}
@@ -190,32 +192,20 @@
"loading-from-persistence--failed-to-unmarshal",
log.Fields{"path": path, "txid": txid, "error": err},
)
- } else {
+ } else if field.Key != "" {
+ var key reflect.Value
+ var keyValue interface{}
+ var keyStr string
+
if path == "" {
- if field.Key != "" {
- // e.g. /logical_devices/abcde --> path="" name=logical_devices key=abcde
- if field.Key != "" {
- _, key := GetAttributeValue(data.Interface(), field.Key, 0)
+ // e.g. /logical_devices --> path="" name=logical_devices key=""
+ _, key = GetAttributeValue(data.Interface(), field.Key, 0)
+ keyStr = key.String()
- childRev := rev.GetBranch().Node.MakeNode(data.Interface(), txid).Latest(txid)
- childRev.SetHash(name + "/" + key.String())
-
- // 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())
-
- rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
- }
- response = append(response, childRev)
- continue
- }
- }
- } else if field.Key != "" {
- // e.g. /logical_devices/abcde/flows/vwxyz --> path=abcde/flows/vwxyz
+ } else {
+ // e.g.
+ // /logical_devices/abcde --> path="abcde" name=logical_devices
+ // /logical_devices/abcde/image_downloads --> path="abcde/image_downloads" name=logical_devices
partition := strings.SplitN(path, "/", 2)
key := partition[0]
@@ -224,24 +214,43 @@
} else {
path = partition[1]
}
- keyValue := field.KeyFromStr(key)
+ keyValue = field.KeyFromStr(key)
+ keyStr = keyValue.(string)
- idx, childRev := rev.GetBranch().Node.findRevByKey(children, field.Key, keyValue)
+ if idx, childRev := rev.GetBranch().Node.findRevByKey(children, field.Key, keyValue); childRev != nil {
+ // Key is memory, continue recursing path
+ newChildRev := childRev.LoadFromPersistence(path, txid)
- newChildRev := childRev.LoadFromPersistence(path, txid)
+ children[idx] = newChildRev[0]
- children[idx] = newChildRev[0]
+ rev := rev.UpdateChildren(name, rev.GetChildren(name), rev.GetBranch())
+ rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
- rev := rev.UpdateChildren(name, rev.GetChildren(name), rev.GetBranch())
- rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
-
- response = append(response, newChildRev[0])
- continue
+ response = append(response, newChildRev[0])
+ continue
+ }
}
+
+ childRev := rev.GetBranch().Node.MakeNode(data.Interface(), txid).Latest(txid)
+ childRev.SetHash(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())
+
+ children = append(children, childRev)
+ rev = rev.UpdateChildren(name, children, rev.GetBranch())
+
+ rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
+ }
+ response = append(response, childRev)
+ continue
}
}
}
}
+
return response
}
diff --git a/db/model/proxy_access_control.go b/db/model/proxy_access_control.go
index a3a7cee..234bcd9 100644
--- a/db/model/proxy_access_control.go
+++ b/db/model/proxy_access_control.go
@@ -183,8 +183,7 @@
// FIXME: Forcing depth to 0 for now due to problems deep copying the data structure
// The data traversal through reflection currently corrupts the content
-
- return pac.getProxy().GetRoot().Get(path, "", depth, deep, txid)
+ return pac.getProxy().GetRoot().Get(path, "", 0, deep, txid)
}
// Update changes the content of the data model at the specified location with the provided data