VOL-1387 : Added watch mechanism

- Fixed a few failure cases
- Adjusted a few logs

Change-Id: Ied1ecb3d8996a338eee00e9643685482700e860b
diff --git a/db/model/backend.go b/db/model/backend.go
index 693ec02..dc0e6bd 100644
--- a/db/model/backend.go
+++ b/db/model/backend.go
@@ -55,7 +55,12 @@
 
 	address := host + ":" + strconv.Itoa(port)
 	if b.Client, err = b.newClient(address, timeout); err != nil {
-		log.Errorf("failed to create a new kv Client - %s", err.Error())
+		log.Errorw("failed-to-create-kv-client",
+			log.Fields{
+				"type": storeType, "host": host, "port": port,
+				"timeout": timeout, "prefix": pathPrefix,
+				"error": err.Error(),
+			})
 	}
 
 	return b
@@ -68,7 +73,7 @@
 	case "etcd":
 		return kvstore.NewEtcdClient(address, timeout)
 	}
-	return nil, errors.New("Unsupported KV store")
+	return nil, errors.New("unsupported-kv-store")
 }
 
 func (b *Backend) makePath(key string) string {
@@ -82,7 +87,7 @@
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugf("List key: %s, path: %s", key, formattedPath)
+	log.Debugw("listing-key", log.Fields{"key": key, "path": formattedPath})
 
 	return b.Client.List(formattedPath, b.Timeout)
 }
@@ -93,7 +98,7 @@
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugf("Get key: %s, path: %s", key, formattedPath)
+	log.Debugw("getting-key", log.Fields{"key": key, "path": formattedPath})
 
 	start := time.Now()
 	err, pair := b.Client.Get(formattedPath, b.Timeout)
@@ -110,7 +115,7 @@
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugf("Put key: %s, value: %+v, path: %s", key, string(value.([]byte)), formattedPath)
+	log.Debugw("putting-key", log.Fields{"key": key, "value": string(value.([]byte)), "path": formattedPath})
 
 	return b.Client.Put(formattedPath, value, b.Timeout)
 }
@@ -121,7 +126,29 @@
 	defer b.Unlock()
 
 	formattedPath := b.makePath(key)
-	log.Debugf("Delete key: %s, path: %s", key, formattedPath)
+	log.Debugw("deleting-key", log.Fields{"key": key, "path": formattedPath})
 
 	return b.Client.Delete(formattedPath, b.Timeout)
 }
+
+// CreateWatch starts watching events for the specified key
+func (b *Backend) CreateWatch(key string) chan *kvstore.Event {
+	b.Lock()
+	defer b.Unlock()
+
+	formattedPath := b.makePath(key)
+	log.Debugw("creating-key-watch", log.Fields{"key": key, "path": formattedPath})
+
+	return b.Client.Watch(formattedPath)
+}
+
+// DeleteWatch stops watching events for the specified key
+func (b *Backend) DeleteWatch(key string, ch chan *kvstore.Event) {
+	b.Lock()
+	defer b.Unlock()
+
+	formattedPath := b.makePath(key)
+	log.Debugw("deleting-key-watch", log.Fields{"key": key, "path": formattedPath})
+
+	b.Client.CloseWatch(formattedPath, ch)
+}