VOL-2103 - Device reason update modifications

A new api is defined to update the reason attribute of Device in rw_core.

Change-Id: Icc4134498fc622d67d8e8b6f6d08f0968a8e9bd2
diff --git a/go.mod b/go.mod
index fa6a144..296baf4 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@
 	github.com/golang/protobuf v1.3.2
 	github.com/google/uuid v1.1.1
 	github.com/gyuho/goraph v0.0.0-20160328020532-d460590d53a9
-	github.com/opencord/voltha-lib-go v0.0.0-20191017201200-e73f91e306e9
+	github.com/opencord/voltha-lib-go v0.0.0-20191018190138-62f0709e8232
 	github.com/opencord/voltha-protos v1.0.3
 	github.com/stretchr/testify v1.4.0
 	google.golang.org/grpc v1.24.0
diff --git a/go.sum b/go.sum
index 60cb314..58978ba 100644
--- a/go.sum
+++ b/go.sum
@@ -192,8 +192,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 v0.0.0-20191017201200-e73f91e306e9 h1:/CA9esQ/L41vhvwCIDI+cLjrawry5+1fQWt/O91KFXU=
-github.com/opencord/voltha-lib-go v0.0.0-20191017201200-e73f91e306e9/go.mod h1:+bjwfm5bbP1j6liscpn3UFqbh6hHDkmLDWU3AdYLDY4=
+github.com/opencord/voltha-lib-go v0.0.0-20191018190138-62f0709e8232 h1:2+lgStiINTrNdCvyVHFmPoVpWO5/6RdeQF6oZqSlimc=
+github.com/opencord/voltha-lib-go v0.0.0-20191018190138-62f0709e8232/go.mod h1:+bjwfm5bbP1j6liscpn3UFqbh6hHDkmLDWU3AdYLDY4=
 github.com/opencord/voltha-protos v1.0.3 h1:9v+R/QGF1xK+HKTqFM0IqCABoGCAxC8iKH4VzNBJDto=
 github.com/opencord/voltha-protos v1.0.3/go.mod h1:myfFIkJdA+rCXmKdLImhh79MfabN4ZOKQ4grk32DnPQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/rw_core/core/adapter_request_handler.go b/rw_core/core/adapter_request_handler.go
index 5e76e27..168e9ca 100644
--- a/rw_core/core/adapter_request_handler.go
+++ b/rw_core/core/adapter_request_handler.go
@@ -1126,3 +1126,54 @@
 
 	return new(empty.Empty), nil
 }
+
+func (rhp *AdapterRequestHandlerProxy) DeviceReasonUpdate(args []*ic.Argument) (*empty.Empty, error) {
+	if len(args) < 2 {
+		log.Warn("DeviceReasonUpdate: invalid-number-of-args", log.Fields{"args": args})
+		err := errors.New("DeviceReasonUpdate: invalid-number-of-args")
+		return nil, err
+	}
+	deviceId := &voltha.ID{}
+	reason := &ic.StrType{}
+	transactionID := &ic.StrType{}
+	for _, arg := range args {
+		switch arg.Key {
+		case "device_id":
+			if err := ptypes.UnmarshalAny(arg.Value, deviceId); err != nil {
+				log.Warnw("cannot-unmarshal-device-id", log.Fields{"error": err})
+				return nil, err
+			}
+		case "device_reason":
+			if err := ptypes.UnmarshalAny(arg.Value, reason); err != nil {
+				log.Warnw("cannot-unmarshal-reason", log.Fields{"error": err})
+				return nil, err
+			}
+		case kafka.TransactionKey:
+			if err := ptypes.UnmarshalAny(arg.Value, transactionID); err != nil {
+				log.Warnw("cannot-unmarshal-transaction-ID", log.Fields{"error": err})
+				return nil, err
+			}
+		}
+	}
+	log.Debugw("DeviceReasonUpdate", log.Fields{"deviceId": deviceId.Id, "reason": reason.Val,
+		"transactionID": transactionID.Val})
+
+	// Try to grab the transaction as this core may be competing with another Core
+	if rhp.competeForTransaction() {
+		if txn, err := rhp.takeRequestOwnership(transactionID.Val, deviceId.Id); err != nil {
+			log.Debugw("DeviceReasonUpdate: Core did not process request", log.Fields{"transactionID": transactionID, "error": err})
+			return nil, err
+		} else {
+			defer txn.Close()
+		}
+	}
+
+	if rhp.TestMode { // Execute only for test cases
+		return nil, nil
+	}
+
+	// Run it in its own routine
+	go rhp.deviceMgr.updateDeviceReason(deviceId.Id, reason.Val)
+
+	return new(empty.Empty), nil
+}
diff --git a/rw_core/core/device_agent.go b/rw_core/core/device_agent.go
index 95e4f67..4a5274b 100755
--- a/rw_core/core/device_agent.go
+++ b/rw_core/core/device_agent.go
@@ -1328,3 +1328,19 @@
 
 	return nil
 }
+
+func (agent *DeviceAgent) updateDeviceReason(reason string) error {
+	agent.lockDevice.Lock()
+	defer agent.lockDevice.Unlock()
+	// Work only on latest data
+	if storeDevice, err := agent.getDeviceWithoutLock(); err != nil {
+		return status.Errorf(codes.NotFound, "%s", agent.deviceId)
+	} else {
+		// clone the device
+		cloned := proto.Clone(storeDevice).(*voltha.Device)
+		cloned.Reason = reason
+		log.Debugw("updateDeviceReason", log.Fields{"deviceId": cloned.Id, "reason": cloned.Reason})
+		// Store the device
+		return agent.updateDeviceInStoreWithoutLock(cloned, false, "")
+	}
+}
diff --git a/rw_core/core/device_manager.go b/rw_core/core/device_manager.go
index bb36966..9434dcf 100755
--- a/rw_core/core/device_manager.go
+++ b/rw_core/core/device_manager.go
@@ -1413,3 +1413,11 @@
 	//TODO CLI always get successful response
 	sendResponse(ctx, ch, res)
 }
+
+func (dMgr *DeviceManager) updateDeviceReason(deviceId string, reason string) error {
+	log.Debugw("updateDeviceReason", log.Fields{"deviceid": deviceId, "reason": reason})
+	if agent := dMgr.getDeviceAgent(deviceId); agent != nil {
+		return agent.updateDeviceReason(reason)
+	}
+	return status.Errorf(codes.NotFound, "%s", deviceId)
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/pkg/adapters/adapterif/core_proxy_if.go b/vendor/github.com/opencord/voltha-lib-go/pkg/adapters/adapterif/core_proxy_if.go
index 26d021f..196f356 100644
--- a/vendor/github.com/opencord/voltha-lib-go/pkg/adapters/adapterif/core_proxy_if.go
+++ b/vendor/github.com/opencord/voltha-lib-go/pkg/adapters/adapterif/core_proxy_if.go
@@ -46,4 +46,5 @@
 	GetChildDevice(ctx context.Context, parentDeviceID string, kwargs map[string]interface{}) (*voltha.Device, error)
 	GetChildDevices(ctx context.Context, parentDeviceID string) (*voltha.Devices, error)
 	SendPacketIn(ctx context.Context, deviceID string, port uint32, pktPayload []byte) error
+	DeviceReasonUpdate(ctx context.Context, deviceID string, deviceReason string) error
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c0ad304..2874a69 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -62,7 +62,7 @@
 github.com/mitchellh/go-homedir
 # github.com/mitchellh/mapstructure v1.1.2
 github.com/mitchellh/mapstructure
-# github.com/opencord/voltha-lib-go v0.0.0-20191017201200-e73f91e306e9
+# github.com/opencord/voltha-lib-go v0.0.0-20191018190138-62f0709e8232
 github.com/opencord/voltha-lib-go/pkg/log
 github.com/opencord/voltha-lib-go/pkg/db/kvstore
 github.com/opencord/voltha-lib-go/pkg/grpc