[VOL-3085]Implement UpdatePmConfig api for voltha-openolt-adapter

Change-Id: Id1f2ae30d7f0d8f4aa4516b96809cf4a1e116dd1
diff --git a/go.mod b/go.mod
index 675fe88..fc93065 100755
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@
 	github.com/cenkalti/backoff/v3 v3.1.1
 	github.com/gogo/protobuf v1.3.1
 	github.com/golang/protobuf v1.3.2
-	github.com/opencord/voltha-lib-go/v3 v3.1.13
+	github.com/opencord/voltha-lib-go/v3 v3.1.14
 	github.com/opencord/voltha-protos/v3 v3.3.6
 	go.etcd.io/etcd v0.0.0-20190930204107-236ac2a90522
 	google.golang.org/grpc v1.25.1
diff --git a/go.sum b/go.sum
index 4bfcffa..cc55fe6 100644
--- a/go.sum
+++ b/go.sum
@@ -202,8 +202,8 @@
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
 github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/opencord/voltha-lib-go/v3 v3.1.13 h1:kgf2aMkiUR5IbJpQ/E7pMNcwR2KxhLchP26CSyY+rbY=
-github.com/opencord/voltha-lib-go/v3 v3.1.13/go.mod h1:26TG6ABl+ppP754YWhhgao9wKNL3SuUf/KztQcJFqrQ=
+github.com/opencord/voltha-lib-go/v3 v3.1.14 h1:ErtQcdZowg5kuMOnLHRZNJl6A9c8u1XhZJWbPfzHnGQ=
+github.com/opencord/voltha-lib-go/v3 v3.1.14/go.mod h1:26TG6ABl+ppP754YWhhgao9wKNL3SuUf/KztQcJFqrQ=
 github.com/opencord/voltha-protos/v3 v3.3.3 h1:OO0H+YMxjLFQifoYXwBp1JN5rpEVMQnhGGEdP6pLrY0=
 github.com/opencord/voltha-protos/v3 v3.3.3/go.mod h1:nl1ETp5Iw3avxOaKD8BJlYY5wYI4KeV95aT1pL63nto=
 github.com/opencord/voltha-protos/v3 v3.3.6 h1:en9k9R2RmPIB8mW/sK2iK11JTw78gJpVf4/wM2cV+Ow=
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 39775a0..a5b131d 100644
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -703,6 +703,10 @@
 		}
 	}()
 	go dh.updateLocalDevice()
+
+	if device.PmConfigs != nil {
+		dh.UpdatePmConfig(device.PmConfigs)
+	}
 	return nil
 }
 
@@ -777,13 +781,12 @@
 
 func startCollector(dh *DeviceHandler) {
 	logger.Debugf("starting-collector")
-	freq := dh.metrics.ToPmConfigs().DefaultFreq
 	for {
 		select {
 		case <-dh.stopCollector:
 			logger.Debugw("stopping-collector-for-olt", log.Fields{"deviceID:": dh.device.Id})
 			return
-		case <-time.After(time.Duration(freq) * time.Second):
+		case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
 
 			ports := make([]*voltha.Port, len(dh.device.Ports))
 			copy(ports, dh.device.Ports)
@@ -1361,6 +1364,25 @@
 	}
 }
 
+// UpdatePmConfig updates the pm metrics.
+func (dh *DeviceHandler) UpdatePmConfig(pmConfigs *voltha.PmConfigs) {
+
+	logger.Infow("update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
+
+	if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
+		dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
+		logger.Debugf("frequency-updated")
+	}
+
+	if pmConfigs.Grouped == false {
+		metrics := dh.metrics.GetSubscriberMetrics()
+		for _, m := range pmConfigs.Metrics {
+			metrics[m.Name].Enabled = m.Enabled
+
+		}
+	}
+}
+
 //UpdateFlowsIncrementally updates the device flow
 func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
 	logger.Debugw("received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
diff --git a/internal/pkg/core/openolt.go b/internal/pkg/core/openolt.go
index 36a609e..3704945 100644
--- a/internal/pkg/core/openolt.go
+++ b/internal/pkg/core/openolt.go
@@ -289,7 +289,12 @@
 
 //Update_pm_config returns PmConfigs nil or error
 func (oo *OpenOLT) Update_pm_config(device *voltha.Device, pmConfigs *voltha.PmConfigs) error {
-	return olterrors.ErrNotImplemented
+	logger.Debugw("Update_pm_config", log.Fields{"device-id": device.Id, "pm-configs": pmConfigs})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		handler.UpdatePmConfig(pmConfigs)
+		return nil
+	}
+	return olterrors.NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil)
 }
 
 //Receive_packet_out sends packet out to the device
diff --git a/internal/pkg/core/openolt_test.go b/internal/pkg/core/openolt_test.go
index 704c0b5..323ec8c 100644
--- a/internal/pkg/core/openolt_test.go
+++ b/internal/pkg/core/openolt_test.go
@@ -896,14 +896,13 @@
 		args    args
 		wantErr error
 	}{
-		{"update_pm_config-1", &fields{}, args{}, olterrors.ErrNotImplemented},
-		{"update_pm_config-2", &fields{}, args{}, olterrors.ErrNotImplemented},
-		{"update_pm_config-3", &fields{}, args{}, olterrors.ErrNotImplemented},
+		{"update_pm_config-1", mockOlt(), args{device: mockDevice(), pmConfigs: &voltha.PmConfigs{DefaultFreq: 150, Grouped: false, FreqOverride: false}}, nil},
+		{"update_pm_config-2", &fields{}, args{device: mockDevice(), pmConfigs: &voltha.PmConfigs{DefaultFreq: 150, Grouped: false, FreqOverride: false}}, olterrors.NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			oo := testOltObject(tt.fields)
-			if err := oo.Update_pm_config(tt.args.device, tt.args.pmConfigs); err != tt.wantErr {
+			if err := oo.Update_pm_config(tt.args.device, tt.args.pmConfigs); !reflect.DeepEqual(err, tt.wantErr) {
 				t.Errorf("Update_pm_config() error = %v, wantErr %v", err, tt.wantErr)
 			}
 
diff --git a/internal/pkg/core/statsmanager.go b/internal/pkg/core/statsmanager.go
index 3512f89..c7bd546 100755
--- a/internal/pkg/core/statsmanager.go
+++ b/internal/pkg/core/statsmanager.go
@@ -285,32 +285,40 @@
 	mutex.Lock()
 	cm := StatMgr.Device.portStats.NorthBoundPort[nniID]
 	mutex.Unlock()
-	metricName := StatMgr.Device.metrics.GetSubscriberMetrics()
+	metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
 
-	if metricName != nil && len(metricName) > 0 {
-		for mName := range metricName {
-			switch mName {
-			case "rx_bytes":
-				nnival["RxBytes"] = float32(cm.RxBytes)
-			case "rx_packets":
-				nnival["RxPackets"] = float32(cm.RxPackets)
-			case "rx_ucast_packets":
-				nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
-			case "rx_mcast_packets":
-				nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
-			case "rx_bcast_packets":
-				nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
-			case "tx_bytes":
-				nnival["TxBytes"] = float32(cm.TxBytes)
-			case "tx_packets":
-				nnival["TxPackets"] = float32(cm.TxPackets)
-			case "tx_mcast_packets":
-				nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
-			case "tx_bcast_packets":
-				nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
+	var metrics []string
+
+	if metricNames != nil && len(metricNames) > 0 {
+		for metric := range metricNames {
+			if metricNames[metric].Enabled {
+				metrics = append(metrics, metric)
 			}
 		}
 	}
+
+	for _, mName := range metrics {
+		switch mName {
+		case "rx_bytes":
+			nnival["RxBytes"] = float32(cm.RxBytes)
+		case "rx_packets":
+			nnival["RxPackets"] = float32(cm.RxPackets)
+		case "rx_ucast_packets":
+			nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
+		case "rx_mcast_packets":
+			nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
+		case "rx_bcast_packets":
+			nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
+		case "tx_bytes":
+			nnival["TxBytes"] = float32(cm.TxBytes)
+		case "tx_packets":
+			nnival["TxPackets"] = float32(cm.TxPackets)
+		case "tx_mcast_packets":
+			nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
+		case "tx_bcast_packets":
+			nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
+		}
+	}
 	return nnival
 }
 
@@ -321,39 +329,41 @@
 	mutex.Lock()
 	cm := StatMgr.Device.portStats.SouthBoundPort[pID]
 	mutex.Unlock()
-	metricName := StatMgr.Device.metrics.GetSubscriberMetrics()
+	metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
 
-	if metricName != nil && len(metricName) > 0 {
-		for mName := range metricName {
-			switch mName {
-			case "rx_bytes":
-				ponval["RxBytes"] = float32(cm.RxBytes)
-			case "rx_packets":
-				ponval["RxPackets"] = float32(cm.RxPackets)
-			// these are not supported in OpenOlt Agent now
-			// will return zero until supported
-			case "rx_ucast_packets":
-				ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
-			case "rx_mcast_packets":
-				ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
-			case "rx_bcast_packets":
-				ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
-			// End will return zero until supported
-			case "tx_bytes":
-				ponval["TxBytes"] = float32(cm.TxBytes)
-			case "tx_packets":
-				ponval["TxPackets"] = float32(cm.TxPackets)
-			// these are not supported in OpenOlt Agent now
-			// will return zero until supported
-			case "tx_ucast_packets":
-				ponval["TxUcastPackets"] = float32(cm.TxUcastPackets)
-			case "tx_mcast_packets":
-				ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
-			case "tx_bcast_packets":
-				ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
+	var metrics []string
+
+	if metricNames != nil && len(metricNames) > 0 {
+		for metric := range metricNames {
+			if metricNames[metric].Enabled {
+				metrics = append(metrics, metric)
 			}
 		}
 	}
+
+	for _, mName := range metrics {
+		switch mName {
+		case "rx_bytes":
+			ponval["RxBytes"] = float32(cm.RxBytes)
+		case "rx_packets":
+			ponval["RxPackets"] = float32(cm.RxPackets)
+		case "rx_ucast_packets":
+			ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
+		case "rx_mcast_packets":
+			ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
+		case "rx_bcast_packets":
+			ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
+		case "tx_bytes":
+			ponval["TxBytes"] = float32(cm.TxBytes)
+		case "tx_packets":
+			ponval["TxPackets"] = float32(cm.TxPackets)
+		case "tx_mcast_packets":
+			ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
+		case "tx_bcast_packets":
+			ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
+		}
+	}
+
 	return ponval
 }
 
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics/performance_metrics.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics/performance_metrics.go
index b5d9369..322126b 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics/performance_metrics.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics/performance_metrics.go
@@ -58,6 +58,11 @@
 	}
 }
 
+// UpdateFrequency will update the frequency.
+func (pm *PmMetrics) UpdateFrequency(frequency uint32) {
+	pm.frequency = frequency
+}
+
 // Metrics will store the PMMetric params
 func Metrics(pmNames []string) PmMetricsOption {
 	return func(args *PmMetrics) {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 630585a..fb79d01 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -67,7 +67,7 @@
 github.com/mitchellh/go-homedir
 # github.com/mitchellh/mapstructure v1.1.2
 github.com/mitchellh/mapstructure
-# github.com/opencord/voltha-lib-go/v3 v3.1.13
+# github.com/opencord/voltha-lib-go/v3 v3.1.14
 github.com/opencord/voltha-lib-go/v3/pkg/adapters
 github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif
 github.com/opencord/voltha-lib-go/v3/pkg/adapters/common