[VOL-3731] added DeleteWithPrefix method from KV

Provides deleting multiple keys in one shot

Change-Id: I71e3089adcdc90a8307b9503197d220d1405f030
diff --git a/VERSION b/VERSION
index 120a6ae..2d2d681 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.10-dev
+4.0.10
diff --git a/pkg/db/backend.go b/pkg/db/backend.go
index 418bf8e..bf30a48 100644
--- a/pkg/db/backend.go
+++ b/pkg/db/backend.go
@@ -234,6 +234,21 @@
 	return err
 }
 
+// DeleteWithPrefix removes items having prefix key
+func (b *Backend) DeleteWithPrefix(ctx context.Context, prefixKey string) error {
+	span, ctx := log.CreateChildSpan(ctx, "etcd-delete-with-prefix")
+	defer span.Finish()
+
+	formattedPath := b.makePath(ctx, prefixKey)
+	logger.Debugw(ctx, "deleting-prefix-key", log.Fields{"key": prefixKey, "path": formattedPath})
+
+	err := b.Client.DeleteWithPrefix(ctx, formattedPath)
+
+	b.updateLiveness(ctx, b.isErrorIndicatingAliveKvstore(ctx, err))
+
+	return err
+}
+
 // CreateWatch starts watching events for the specified key
 func (b *Backend) CreateWatch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event {
 	span, ctx := log.CreateChildSpan(ctx, "etcd-create-watch")
diff --git a/pkg/db/kvstore/client.go b/pkg/db/kvstore/client.go
index 2060b06..b35f1f3 100644
--- a/pkg/db/kvstore/client.go
+++ b/pkg/db/kvstore/client.go
@@ -78,6 +78,7 @@
 	Get(ctx context.Context, key string) (*KVPair, error)
 	Put(ctx context.Context, key string, value interface{}) error
 	Delete(ctx context.Context, key string) error
+	DeleteWithPrefix(ctx context.Context, prefixKey string) error
 	Reserve(ctx context.Context, key string, value interface{}, ttl time.Duration) (interface{}, error)
 	ReleaseReservation(ctx context.Context, key string) error
 	ReleaseAllReservations(ctx context.Context) error
diff --git a/pkg/db/kvstore/etcdclient.go b/pkg/db/kvstore/etcdclient.go
index aa5adbf..868b301 100644
--- a/pkg/db/kvstore/etcdclient.go
+++ b/pkg/db/kvstore/etcdclient.go
@@ -157,6 +157,17 @@
 	return nil
 }
 
+func (c *EtcdClient) DeleteWithPrefix(ctx context.Context, prefixKey string) error {
+
+	//delete the prefix
+	if _, err := c.ectdAPI.Delete(ctx, prefixKey, v3Client.WithPrefix()); err != nil {
+		logger.Errorw(ctx, "failed-to-delete-prefix-key", log.Fields{"key": prefixKey, "error": err})
+		return err
+	}
+	logger.Debugw(ctx, "key(s)-deleted", log.Fields{"key": prefixKey})
+	return nil
+}
+
 // Reserve is invoked to acquire a key and set it to a given value. Value can only be a string or []byte since
 // the etcd API accepts only a string.  Timeout defines how long the function will wait for a response.  TTL
 // defines how long that reservation is valid.  When TTL expires the key is unreserved by the KV store itself.
diff --git a/pkg/ponresourcemanager/ponresourcemanager.go b/pkg/ponresourcemanager/ponresourcemanager.go
index 0e1ae8f..415ce21 100755
--- a/pkg/ponresourcemanager/ponresourcemanager.go
+++ b/pkg/ponresourcemanager/ponresourcemanager.go
@@ -112,8 +112,11 @@
 	FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
 
 	//Flow Id info: Use to store more metadata associated with the flow_id
-	//Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
-	FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
+	FLOW_ID_INFO_PATH_PREFIX = "{%s}/flow_id_info"
+	//Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)>
+	FLOW_ID_INFO_PATH_INTF_ONU_PREFIX = "{%s}/flow_id_info/{%s}"
+	//Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)><flow_id>
+	FLOW_ID_INFO_PATH = FLOW_ID_INFO_PATH_PREFIX + "/{%s}/{%d}"
 
 	//path on the kvstore to store onugem info map
 	//format: <device-id>/onu_gem_info/<intfid>
@@ -1034,6 +1037,20 @@
 	return true
 }
 
+func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
+	/*
+	    Remove flow_id_info details configured for the ONU.
+	   :param pon_intf_onu_id: reference of PON interface id and onu id
+	*/
+	Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
+
+	if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
+		logger.Errorf(ctx, "Falied to remove resource %s", Path)
+		return false
+	}
+	return true
+}
+
 func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
 	/*
 	   Update currently configured alloc ids for given pon_intf_onu_id
diff --git a/pkg/ponresourcemanager/ponresourcemanager_test.go b/pkg/ponresourcemanager/ponresourcemanager_test.go
index ecdccc7..1bc908e 100644
--- a/pkg/ponresourcemanager/ponresourcemanager_test.go
+++ b/pkg/ponresourcemanager/ponresourcemanager_test.go
@@ -88,6 +88,10 @@
 	return nil
 }
 
+func (c *MockResKVClient) DeleteWithPrefix(ctx context.Context, prefixKey string) error {
+	return nil
+}
+
 // Reserve mock function implementation for KVClient
 func (kvclient *MockResKVClient) Reserve(ctx context.Context, key string, value interface{}, ttl time.Duration) (interface{}, error) {
 	return nil, errors.New("key didn't find")