[VOL-5291] - pon & nni stats changes, onu stats from OLT, onu stats from onu

Change-Id: I4f23cb1b1276d27ca6f2c183875b8b227f772edd
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index 6e6d0d3..28fadce 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -21,7 +21,6 @@
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/user"
@@ -32,8 +31,8 @@
 	"strings"
 	"time"
 
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
+	"github.com/golang/protobuf/jsonpb" //nolint:staticcheck
+	"github.com/golang/protobuf/proto"  //nolint:staticcheck
 	configv1 "github.com/opencord/voltctl/internal/pkg/apis/config/v1"
 	configv2 "github.com/opencord/voltctl/internal/pkg/apis/config/v2"
 	configv3 "github.com/opencord/voltctl/internal/pkg/apis/config/v3"
@@ -234,7 +233,7 @@
 	}
 
 	if info, err := os.Stat(GlobalOptions.CommandOptions); err == nil && !info.IsDir() {
-		optionsFile, err := ioutil.ReadFile(GlobalOptions.CommandOptions)
+		optionsFile, err := os.ReadFile(GlobalOptions.CommandOptions)
 		if err != nil {
 			Error.Fatalf("Unable to read command options configuration file '%s' : %s",
 				GlobalOptions.CommandOptions, err.Error())
@@ -350,7 +349,7 @@
 	}
 
 	if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
-		configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+		configFile, err := os.ReadFile(GlobalOptions.Config)
 		if err != nil {
 			Error.Fatalf("Unable to read the configuration file '%s': %s",
 				GlobalOptions.Config, err.Error())
diff --git a/internal/pkg/commands/completion.go b/internal/pkg/commands/completion.go
index 0052a10..fa66982 100644
--- a/internal/pkg/commands/completion.go
+++ b/internal/pkg/commands/completion.go
@@ -17,6 +17,7 @@
 
 import (
 	"fmt"
+
 	flags "github.com/jessevdk/go-flags"
 	"github.com/opencord/voltctl/internal/pkg/completion"
 )
@@ -34,6 +35,6 @@
 }
 
 func (options *BashOptions) Execute(args []string) error {
-	fmt.Println(completion.Bash)
+	fmt.Print(completion.Bash)
 	return nil
 }
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index ba2b8c2..7d824f4 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -110,6 +110,49 @@
 DFrames_512To_1023Octets:	{{.DFrames_512To_1023Octets}}
 DFrames_1024To_1518Octets:	{{.DFrames_1024To_1518Octets}}
 PmFormat:	                {{.PmFormat}}`
+	DEFAULT_PON_PORT_STATS_FORMAT = `Pon Port:                   {{.PonPort}}
+Bip Units:                  {{.BipUnits}}
+Bip Errors:                 {{.BipErrors}}
+RxPackets:                  {{.RxPackets}}
+RxGem:                      {{.RxGem}}
+RxGemDropped:               {{.RxGemDropped}}
+RxGemIdle:                  {{.RxGemIdle}}
+RxGemCorrected:             {{.RxGemCorrected}}
+RxGemIllegal:               {{.RxGemIllegal}}
+RxCrcError:                 {{.RxCrcErrors}}
+RxFragmentError:            {{.RxFragmentError}}
+RxPacketsDropped:           {{.RxPacketsDropped}}
+RxCpuOmciPacketsDropped:    {{.RxCpuOmciPacketsDropped}}
+RxCpu:                      {{.RxCpu}}
+RxOmci:                     {{.RxOmci}}
+RxOmciPacketsCrcError:      {{.RxOmciPacketsCrcError}}
+TxPackets:                  {{.TxPackets}}
+TxGem:                      {{.TxGem}}
+TxCpu:                      {{.TxCpu}}
+TxOmci:                     {{.TxOmci}}
+TxDroppedIllegalLength:     {{.TxDroppedIllegalLength}}
+TxDroppedTpidMiss:          {{.TxDroppedTpidMiss}}
+TxDroppedVidMiss:           {{.TxDroppedVidMiss}}
+TxDroppedTotal:             {{.TxDroppedTotal}}`
+	DEFAULT_NNI_PORT_STATS_FORMAT = `Nni Port:               {{.NniPort}}
+RxBytes:                {{.RxBytes}}
+RxPackets:              {{.RxPackets}}
+RxUcastPackets:         {{.RxUcastPackets}}
+RxMcastPackets:         {{.RxMcastPackets}}
+RxBcastPackets:         {{.RxBcastPackets}}
+RxErrorPackets:         {{.RxErrorPackets}}
+RxFcsErrorPackets:      {{.RxFcsErrorPackets}}
+RxUndersizePackets:     {{.RxUndersizePackets}}
+RxOversizePackets:      {{.RxOversizePackets}}
+TxBytes:                {{.TxBytes}}
+TxPackets:              {{.TxPackets}}
+TxUcastPackets:         {{.TxUcastPackets}}
+TxMcastPackets:         {{.TxMcastPackets}}
+TxBcastPackets:         {{.TxBcastPackets}}
+TxErrorPackets:         {{.TxErrorPackets}}
+TxUndersizePackets:     {{.TxUndersizePackets}}
+TxOversizePackets:      {{.TxOversizePackets}}`
+
 	DEFAULT_ONU_OMCI_TX_RX_STATS_FORMAT = `BaseTxArFrames:        {{.BaseTxArFrames}}
 BaseRxAkFrames:        {{.BaseRxAkFrames}}
 BaseTxNoArFrames:      {{.BaseTxNoArFrames}}
@@ -120,10 +163,28 @@
 ExtRxNoAkFrames:       {{.ExtRxNoAkFrames}}
 TxOmciCounterRetries:  {{.TxOmciCounterRetries}}
 TxOmciCounterTimeouts: {{.TxOmciCounterTimeouts}}`
-	DEFAULT_DEVICE_ALARMS_FORMAT       = "table{{ .ClassId }}\t{{.InstanceId}}\t{{.Name}}\t{{.Description}}"
-	DEFAULT_DEVICE_ALARMS_ORDER        = "ClassId,InstanceId"
-	DEFAULT_PON_RX_POWER_STATUS_FORMAT = "table{{.OnuSn}}\t{{.Status}}\t{{.FailReason}}\t{{.RxPower}}\t"
-	DEFAULT_ONU_DISTANCE_FORMAT        = `Distance`
+	DEFAULT_ONU_STATS_FROM_OLT_FORMAT = `AllocId:        {{.AllocId}}
+AllocRxBytes:   {{.AllocRxBytes}}
+{{range .GemPortStats}}
+-GemId:          {{.GemId}}
+ RxPackets:      {{.RxPackets}}
+ RxBytes:        {{.RxBytes}}
+ TxPackets:      {{.TxPackets}}
+ TxBytes:        {{.TxBytes}}{{end}}`
+
+	DEFAULT_ONU_DISTANCE_FORMAT          = `Distance`
+	DEFAULT_DEVICE_ALARMS_FORMAT         = "table{{ .ClassId }}\t{{.InstanceId}}\t{{.Name}}\t{{.Description}}"
+	DEFAULT_DEVICE_ALARMS_ORDER          = "ClassId,InstanceId"
+	DEFAULT_PON_RX_POWER_STATUS_FORMAT   = "table{{.OnuSn}}\t{{.Status}}\t{{.FailReason}}\t{{.RxPower}}\t"
+	DEFAULT_DEVICE_VALUE_GEM_PORT_FORMAT = `AllocId:                {{.AllocId}}
+ AllocRxBytes:           {{.AllocRxBytes}}
+ {{range .GemHistoryStats}}
+-GemId:                  {{.GemId}}
+ TransmittedGEMFrames:   {{.TransmittedGEMFrames}}
+ ReceivedGEMFrames:      {{.ReceivedGEMFrames}}
+ ReceivedPayloadBytes:   {{.ReceivedPayloadBytes}}
+ TransmittedPayloadBytes:{{.TransmittedPayloadBytes}}
+ EncryptionKeyErrors:    {{.EncryptionKeyErrors}}{{end}}`
 )
 
 type DeviceList struct {
@@ -454,6 +515,30 @@
 	} `positional-args:"yes"`
 }
 
+type GetPonPortStats struct {
+	ListOutputOptions
+	Reset bool `long:"reset" description:"Reset the counters"`
+	Args  struct {
+		Id        DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+		PortLabel string   `positional-arg-name:"PORT_LABEL" required:"yes"`
+	} `positional-args:"yes"`
+}
+
+type GetNniPortStats struct {
+	ListOutputOptions
+	Reset bool `long:"reset" description:"Reset the counters"`
+	Args  struct {
+		Id        DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+		PortLabel string   `positional-arg-name:"PORT_LABEL" required:"yes"`
+	} `positional-args:"yes"`
+}
+
+type GetOnuAllocGemStatsFromOlt struct {
+	ListOutputOptions
+	Args struct {
+		Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+	} `positional-args:"yes"`
+}
 type RxPower struct {
 	ListOutputOptions
 	Args struct {
@@ -486,6 +571,13 @@
 	} `positional-args:"yes"`
 }
 
+type GetOnuGEMStats struct {
+	ListOutputOptions
+	Args struct {
+		Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+	} `positional-args:"yes"`
+}
+
 type GetOnuDistance struct {
 	ListOutputOptions
 	Args struct {
@@ -560,6 +652,10 @@
 		PonRxPower              PonRxPower                            `command:"pon_rx_power"`
 		OnuDistance             GetOnuDistance                        `command:"onu_distance"`
 		OffloadAppStats         GetOffloadApp                         `command:"offload_app_stats"`
+		PonStats                GetPonPortStats                       `command:"itu_pon_stats"`
+		NniStats                GetNniPortStats                       `command:"nni_statistics"`
+		OnuGEMStats             GetOnuGEMStats                        `command:"onu_gem_stats"`
+		OnuAllocGemStats        GetOnuAllocGemStatsFromOlt            `command:"onu_alloc_gem_from_olt"`
 	} `command:"getextval"`
 	SetExtVal struct {
 		OffloadAppStatsSet SetOffloadApp `command:"set_offload_app"`
@@ -567,6 +663,38 @@
 	} `command:"setextval"`
 }
 
+type AllocGemStatsFromOlt struct {
+	AllocId      uint32
+	AllocRxBytes uint64
+	GemPortStats []GemPortStatsFromOlt
+}
+type GemPortStatsFromOlt struct {
+	GemId     uint32
+	RxPackets uint64
+	RxBytes   uint64
+	TxPackets uint64
+	TxBytes   uint64
+}
+type onugemstats struct {
+	AllocId         uint32
+	AllocRxBytes    uint32
+	GemHistoryStats []gemHistoryStats
+}
+type gemHistoryStats struct {
+	GemId                   uint32
+	TransmittedGEMFrames    uint32
+	ReceivedGEMFrames       uint32
+	ReceivedPayloadBytes    uint32
+	TransmittedPayloadBytes uint32
+	EncryptionKeyErrors     uint32
+}
+
+type PortStats struct {
+	PonPort uint32 // use this for PON
+	NniPort uint32 // use this for NNI
+	*common.PortStatistics
+}
+
 var deviceOpts = DeviceOpts{}
 
 func RegisterDeviceCommands(parser *flags.Parser) {
@@ -2349,6 +2477,104 @@
 	}
 }
 
+func (options *GetPonPortStats) Execute(args []string) error {
+	conn, err := NewConnection()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	client := extension.NewExtensionClient(conn)
+
+	singleGetValReq := extension.SingleGetValueRequest{
+		TargetId: string(options.Args.Id),
+		Request: &extension.GetValueRequest{
+			Request: &extension.GetValueRequest_OltPonStats{
+				OltPonStats: &extension.GetPonStatsRequest{
+					PortInfo: &extension.GetPonStatsRequest_PortLabel{
+						PortLabel: options.Args.PortLabel,
+					},
+				},
+			},
+		},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+	defer cancel()
+	rv, err := client.GetExtValue(ctx, &singleGetValReq)
+	if err != nil {
+		Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+		return err
+	}
+
+	if rv.Response.Status != extension.GetValueResponse_OK {
+		return fmt.Errorf("failed to get pon port stats %v", rv.Response.ErrReason.String())
+	}
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("device-get-pon-stats", "format", DEFAULT_PON_PORT_STATS_FORMAT)
+	}
+	data := PortStats{
+		PonPort:        rv.GetResponse().GetOltPonStatsResponse().GetPonPort(),
+		PortStatistics: rv.GetResponse().GetOltPonStatsResponse().GetPortStatistics(),
+	}
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      data,
+	}
+	GenerateOutput(&result)
+	return nil
+}
+
+func (options *GetNniPortStats) Execute(args []string) error {
+	conn, err := NewConnection()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	client := extension.NewExtensionClient(conn)
+
+	singleGetValReq := extension.SingleGetValueRequest{
+		TargetId: string(options.Args.Id),
+		Request: &extension.GetValueRequest{
+			Request: &extension.GetValueRequest_OltNniStats{
+				OltNniStats: &extension.GetNNIStatsRequest{
+					PortInfo: &extension.GetNNIStatsRequest_PortLabel{
+						PortLabel: options.Args.PortLabel,
+					},
+				},
+			},
+		},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+	defer cancel()
+	rv, err := client.GetExtValue(ctx, &singleGetValReq)
+	if err != nil {
+		Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+		return err
+	}
+
+	if rv.Response.Status != extension.GetValueResponse_OK {
+		return fmt.Errorf("failed to get nni port stats %v", rv.Response.ErrReason.String())
+	}
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("device-get-nni-stats", "format", DEFAULT_NNI_PORT_STATS_FORMAT)
+	}
+	data := PortStats{
+		NniPort:        rv.GetResponse().GetOltNniStatsResponse().GetNniPort(),
+		PortStatistics: rv.GetResponse().GetOltNniStatsResponse().GetPortStatistics(),
+	}
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      data,
+	}
+	GenerateOutput(&result)
+	return nil
+}
+
 func (options *GetOnuEthernetFrameExtendedPmCounters) Execute(args []string) error {
 	conn, err := NewConnection()
 	if err != nil {
@@ -2789,3 +3015,123 @@
 	GenerateOutput(&result)
 	return nil
 }
+
+func (options *GetOnuGEMStats) Execute(args []string) error {
+
+	conn, err := NewConnection()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	client := extension.NewExtensionClient(conn)
+	singleGetValReq := extension.SingleGetValueRequest{
+		TargetId: string(options.Args.Id),
+		Request: &extension.GetValueRequest{
+			Request: &extension.GetValueRequest_OnuAllocGemStats{
+				OnuAllocGemStats: &extension.GetOnuAllocGemHistoryRequest{},
+			},
+		},
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+	defer cancel()
+
+	rv, err := client.GetExtValue(ctx, &singleGetValReq)
+
+	if err != nil {
+		Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+		return err
+	}
+
+	if rv.Response.Status != extension.GetValueResponse_OK {
+		return fmt.Errorf("failed to get gem port response %v", rv.Response.ErrReason.String())
+	}
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("device-get-gem-port", "format", DEFAULT_DEVICE_VALUE_GEM_PORT_FORMAT)
+	}
+	onugemhistoryresponse := rv.GetResponse().GetOnuAllocGemStatsResponse()
+	for _, OnuallocGemHistoryData := range onugemhistoryresponse.OnuAllocGemHistoryData {
+		data := onugemstats{}
+		data.AllocId = OnuallocGemHistoryData.OnuAllocIdInfo.AllocId
+		data.AllocRxBytes = OnuallocGemHistoryData.OnuAllocIdInfo.RxBytes
+		for _, gemStatsInfo := range OnuallocGemHistoryData.GemPortInfo {
+			data.GemHistoryStats = append(data.GemHistoryStats, gemHistoryStats{
+				GemId:                   gemStatsInfo.GemId,
+				TransmittedGEMFrames:    gemStatsInfo.TransmittedGEMFrames,
+				ReceivedGEMFrames:       gemStatsInfo.ReceivedGEMFrames,
+				ReceivedPayloadBytes:    gemStatsInfo.ReceivedPayloadBytes,
+				TransmittedPayloadBytes: gemStatsInfo.TransmittedPayloadBytes,
+				EncryptionKeyErrors:     gemStatsInfo.EncryptionKeyErrors,
+			})
+		}
+		result := CommandResult{
+			Format:    format.Format(outputFormat),
+			OutputAs:  toOutputType(options.OutputAs),
+			NameLimit: options.NameLimit,
+			Data:      &data,
+		}
+		GenerateOutput(&result)
+	}
+	return nil
+
+}
+
+func (options *GetOnuAllocGemStatsFromOlt) Execute(args []string) error {
+	conn, err := NewConnection()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	client := extension.NewExtensionClient(conn)
+
+	singleGetValReq := extension.SingleGetValueRequest{
+		TargetId: string(options.Args.Id),
+		Request: &extension.GetValueRequest{
+			Request: &extension.GetValueRequest_OnuStatsFromOlt{
+				OnuStatsFromOlt: &extension.GetOnuStatsFromOltRequest{},
+			},
+		},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+	defer cancel()
+	rv, err := client.GetExtValue(ctx, &singleGetValReq)
+	if err != nil {
+		Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+		return err
+	}
+
+	if rv.Response.Status != extension.GetValueResponse_OK {
+		return fmt.Errorf("failed to get onu alloc gem stats from olt %v", rv.Response.ErrReason.String())
+	}
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("device-get-onu-status", "format", DEFAULT_ONU_STATS_FROM_OLT_FORMAT)
+	}
+
+	onuAllocGemStatsResponse := rv.GetResponse().GetOnuStatsFromOltResponse()
+
+	for _, allocGemStatsInfo := range onuAllocGemStatsResponse.AllocGemStatsInfo {
+		data := AllocGemStatsFromOlt{}
+		data.AllocId = allocGemStatsInfo.AllocIdInfo.AllocId
+		data.AllocRxBytes = allocGemStatsInfo.AllocIdInfo.RxBytes
+		for _, gemStatsInfo := range allocGemStatsInfo.GemPortInfo {
+			data.GemPortStats = append(data.GemPortStats, GemPortStatsFromOlt{
+				GemId:     gemStatsInfo.GemId,
+				RxBytes:   gemStatsInfo.RxBytes,
+				RxPackets: gemStatsInfo.RxPackets,
+				TxBytes:   gemStatsInfo.TxBytes,
+				TxPackets: gemStatsInfo.TxPackets,
+			})
+		}
+		result := CommandResult{
+			Format:    format.Format(outputFormat),
+			OutputAs:  toOutputType(options.OutputAs),
+			NameLimit: options.NameLimit,
+			Data:      &data,
+		}
+		GenerateOutput(&result)
+	}
+
+	return nil
+}
diff --git a/internal/pkg/commands/events.go b/internal/pkg/commands/events.go
index cc149d6..22047f1 100644
--- a/internal/pkg/commands/events.go
+++ b/internal/pkg/commands/events.go
@@ -26,8 +26,8 @@
 	"time"
 
 	"github.com/Shopify/sarama"
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
+	"github.com/golang/protobuf/jsonpb" //nolint:staticcheck
+	"github.com/golang/protobuf/proto"  //nolint:staticcheck
 	"github.com/golang/protobuf/ptypes/timestamp"
 	flags "github.com/jessevdk/go-flags"
 	"github.com/opencord/voltctl/pkg/filter"
diff --git a/internal/pkg/commands/handler.go b/internal/pkg/commands/handler.go
index 0c6d32b..00a0aca 100644
--- a/internal/pkg/commands/handler.go
+++ b/internal/pkg/commands/handler.go
@@ -16,12 +16,13 @@
 package commands
 
 import (
-	"github.com/golang/protobuf/proto"
+	"io"
+
+	"github.com/golang/protobuf/proto" //nolint:staticcheck
 	"github.com/jhump/protoreflect/desc"
 	"github.com/jhump/protoreflect/dynamic"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
-	"io"
 )
 
 type RpcEventHandler struct {
@@ -54,7 +55,7 @@
 		return err
 	}
 
-	if h.Fields == nil || len(h.Fields) == 0 {
+	if len(h.Fields) == 0 {
 		return io.EOF
 	}
 
diff --git a/internal/pkg/commands/log.go b/internal/pkg/commands/log.go
index 56c27cd..2390e02 100644
--- a/internal/pkg/commands/log.go
+++ b/internal/pkg/commands/log.go
@@ -97,7 +97,7 @@
 	} `positional-args:"yes" required:"yes"`
 }
 
-//  EnableLogTracingOpts represents the supported CLI arguments for the log tracing enable command
+// EnableLogTracingOpts represents the supported CLI arguments for the log tracing enable command
 type EnableLogTracingOpts struct {
 	OutputOptions
 	Args struct {
@@ -105,7 +105,7 @@
 	} `positional-args:"yes" required:"yes"`
 }
 
-//  DisableLogTracingOpts represents the supported CLI arguments for the log tracing disable command
+// DisableLogTracingOpts represents the supported CLI arguments for the log tracing disable command
 type DisableLogTracingOpts struct {
 	OutputOptions
 	Args struct {
@@ -113,7 +113,7 @@
 	} `positional-args:"yes" required:"yes"`
 }
 
-//  ListLogTracingOpts represents the supported CLI arguments for the log tracing list command
+// ListLogTracingOpts represents the supported CLI arguments for the log tracing list command
 type ListLogTracingOpts struct {
 	ListOutputOptions
 	Args struct {
@@ -575,7 +575,7 @@
 
 	logLevelConfig, err = processComponentListArgs(toStringArray(options.Args.Component))
 	if err != nil {
-		return fmt.Errorf(err.Error())
+		return err
 	}
 
 	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().KvStoreConfig.Timeout)