[VOL-5417] Add GetWithPrefix and GetWithPrefixKeysOnly functions for the kvclient Interface

Change-Id: I446f414d157d5794de4302450fc075073243b564
Signed-off-by: pnalmas <praneeth.nalmas@radisys.com>
diff --git a/pkg/ponresourcemanager/ponresourcemanager.go b/pkg/ponresourcemanager/ponresourcemanager.go
index 1af791f..26bef32 100755
--- a/pkg/ponresourcemanager/ponresourcemanager.go
+++ b/pkg/ponresourcemanager/ponresourcemanager.go
@@ -214,13 +214,13 @@
 	PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
 	if PONMgr.KVStore == nil {
 		logger.Error(ctx, "KV Client initilization failed")
-		return nil, errors.New("Failed to init KV client")
+		return nil, errors.New("failed to init KV client")
 	}
 	// init kv client to read from the config path
 	PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
 	if PONMgr.KVStoreForConfig == nil {
 		logger.Error(ctx, "KV Config Client initilization failed")
-		return nil, errors.New("Failed to init KV Config client")
+		return nil, errors.New("failed to init KV Config client")
 	}
 
 	PONMgr.PonResourceRanges = make(map[string]interface{})
@@ -483,7 +483,7 @@
 		}
 		if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
 			logger.Error(ctx, "Failed to clear ONU ID resource pool")
-			return errors.New("Failed to clear ONU ID resource pool")
+			return errors.New("failed to clear ONU ID resource pool")
 		}
 		if SharedPoolID != 0 {
 			break
@@ -497,7 +497,7 @@
 		}
 		if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
 			logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
-			return errors.New("Failed to clear ALLOC ID resource pool")
+			return errors.New("failed to clear ALLOC ID resource pool")
 		}
 		if SharedPoolID != 0 {
 			break
@@ -510,7 +510,7 @@
 		}
 		if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
 			logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
-			return errors.New("Failed to clear GEMPORT ID resource pool")
+			return errors.New("failed to clear GEMPORT ID resource pool")
 		}
 		if SharedPoolID != 0 {
 			break
@@ -524,7 +524,7 @@
 		}
 		if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
 			logger.Error(ctx, "Failed to clear FLOW ID resource pool")
-			return errors.New("Failed to clear FLOW ID resource pool")
+			return errors.New("failed to clear FLOW ID resource pool")
 		}
 		if SharedPoolID != 0 {
 			break
@@ -539,22 +539,22 @@
 
 	if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ONU_ID); !status {
 		logger.Error(ctx, "Failed to clear ONU ID resource pool")
-		return errors.New("Failed to clear ONU ID resource pool")
+		return errors.New("failed to clear ONU ID resource pool")
 	}
 
 	if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ALLOC_ID); !status {
 		logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
-		return errors.New("Failed to clear ALLOC ID resource pool")
+		return errors.New("failed to clear ALLOC ID resource pool")
 	}
 
 	if status := PONRMgr.ClearResourceIDPool(ctx, intfID, GEMPORT_ID); !status {
 		logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
-		return errors.New("Failed to clear GEMPORT ID resource pool")
+		return errors.New("failed to clear GEMPORT ID resource pool")
 	}
 
 	if status := PONRMgr.ClearResourceIDPool(ctx, intfID, FLOW_ID); !status {
 		logger.Error(ctx, "Failed to clear FLOW ID resource pool")
-		return errors.New("Failed to clear FLOW ID resource pool")
+		return errors.New("failed to clear FLOW ID resource pool")
 	}
 
 	return nil
@@ -580,7 +580,7 @@
 	Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
 	if Path == "" {
 		logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
-		return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
+		return fmt.Errorf("failed to get path for resource type %s", ResourceType)
 	}
 
 	//In case of adapter reboot and reconciliation resource in kv store
@@ -663,7 +663,7 @@
 	var TSData *bitmap.Threadsafe
 	if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
 		logger.Error(ctx, "Failed to create a bitmap")
-		return nil, errors.New("Failed to create bitmap")
+		return nil, errors.New("failed to create bitmap")
 	}
 	for _, excludedID := range Excluded {
 		if excludedID < StartIDx || excludedID > EndIDx {
@@ -781,7 +781,7 @@
 
 	if NumIDs < 1 {
 		logger.Error(ctx, "Invalid number of resources requested")
-		return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
+		return nil, fmt.Errorf("invalid number of resources requested %d", NumIDs)
 	}
 	// delegate to the master instance if sharing enabled across instances
 
@@ -794,7 +794,7 @@
 	Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
 	if Path == "" {
 		logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
-		return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
+		return nil, fmt.Errorf("failed to get path for resource type %s", ResourceType)
 	}
 	logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
 	var Result []uint32
@@ -831,7 +831,7 @@
 	//Update resource in kv store
 	if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
 		logger.Errorf(ctx, "Failed to update resource %s", Path)
-		return nil, fmt.Errorf("Failed to update resource %s", Path)
+		return nil, fmt.Errorf("failed to update resource %s", Path)
 	}
 	return Result, nil
 }
@@ -863,12 +863,12 @@
 	})
 
 	if !checkValidResourceType(ResourceType) {
-		err := fmt.Errorf("Invalid resource type: %s", ResourceType)
+		err := fmt.Errorf("invalid resource type: %s", ResourceType)
 		logger.Error(ctx, err.Error())
 		return err
 	}
 	if ReleaseContent == nil {
-		err := fmt.Errorf("Nothing to release")
+		err := fmt.Errorf("nothing to release")
 		logger.Debug(ctx, err.Error())
 		return err
 	}
@@ -879,7 +879,7 @@
 	}
 	Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
 	if Path == "" {
-		err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
+		err := fmt.Errorf("failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
 		logger.Error(ctx, err.Error())
 		return err
 	}
@@ -892,7 +892,7 @@
 		PONRMgr.ReleaseID(ctx, Resource, Val)
 	}
 	if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
-		err := fmt.Errorf("Free resource for %s failed", Path)
+		err := fmt.Errorf("free resource for %s failed", Path)
 		logger.Errorf(ctx, err.Error())
 		return err
 	}
@@ -1292,7 +1292,7 @@
 	}
 	Data := bitmap.TSFromData(ByteArray, false)
 	if Data == nil {
-		return 0, errors.New("Failed to get data from byte array")
+		return 0, errors.New("failed to get data from byte array")
 	}
 
 	Len := Data.Len()
diff --git a/pkg/ponresourcemanager/ponresourcemanager_test.go b/pkg/ponresourcemanager/ponresourcemanager_test.go
index ff80b11..626864e 100644
--- a/pkg/ponresourcemanager/ponresourcemanager_test.go
+++ b/pkg/ponresourcemanager/ponresourcemanager_test.go
@@ -20,11 +20,12 @@
 	"context"
 	"encoding/json"
 	"errors"
-	"github.com/boljen/go-bitmap"
 	"strings"
 	"testing"
 	"time"
 
+	"github.com/boljen/go-bitmap"
+
 	"github.com/opencord/voltha-lib-go/v7/pkg/db"
 	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
@@ -44,6 +45,7 @@
 func newMockKvClient(ctx context.Context) *MockResKVClient {
 	var mockResKVClient MockResKVClient
 	mockResKVClient.resourceMap = make(map[string]interface{})
+	logger.Debug(ctx, "Creating new MockKVClient")
 	return &mockResKVClient
 }
 
@@ -74,6 +76,42 @@
 	return nil, errors.New("key didn't find")
 }
 
+// GetWithPrefix mock function implementation for KVClient
+func (kvclient *MockResKVClient) GetWithPrefix(ctx context.Context, prefixKey string) (map[string]*kvstore.KVPair, error) {
+	logger.Debugw(ctx, "GetWithPrefix of MockKVClient called", log.Fields{"prefixKey": prefixKey})
+	if prefixKey != "" {
+		if strings.Contains(prefixKey, GEM_POOL_PATH) {
+			logger.Debug(ctx, "Getting keys with prefix:", GEM_POOL_PATH)
+			maps := make(map[string]*kvstore.KVPair)
+			for key, resource := range kvclient.resourceMap {
+				if strings.HasPrefix(key, prefixKey) {
+					maps[key] = kvstore.NewKVPair(key, resource, "mock", 3000, 1)
+				}
+			}
+			return maps, nil
+		}
+	}
+	return nil, errors.New("prefixKey didn't find")
+}
+
+// GetWithPrefixKeysOnly returns only the keys with the specified prefix.
+func (kvclient *MockResKVClient) GetWithPrefixKeysOnly(ctx context.Context, prefixKey string) ([]string, error) {
+	logger.Debugw(ctx, "GetWithPrefixKeysOnly of MockKVClient called", log.Fields{"prefixKey": prefixKey})
+	if prefixKey != "" {
+		if strings.Contains(prefixKey, GEM_POOL_PATH) {
+			logger.Debug(ctx, "Getting keys with prefix:", GEM_POOL_PATH)
+			var keys []string
+			for key := range kvclient.resourceMap {
+				if strings.HasPrefix(key, prefixKey) {
+					keys = append(keys, key)
+				}
+			}
+			return keys, nil
+		}
+	}
+	return nil, errors.New("prefixKey not found")
+}
+
 // Put mock function implementation for KVClient
 func (kvclient *MockResKVClient) Put(ctx context.Context, key string, value interface{}) error {
 	if key != "" {