VOL-1845 : Support for delete device in openolt adapter

           This commit is for the handling of delete device.

           The changes are done to handle the request for delete
           device. This includes the clearing of all data related
           to the device in KV store and reboot of device to reset
           the device.

           This commit has dependency in voltha-go so that needs to
           be merged first. Please refer this review link
           https://gerrit.opencord.org/#/c/15084/

           Updated to dep ensure above voltha-go patch set.  Also typo
           and make lint/sca fixes.

Change-Id: I53f16022c6902d498dad30e9b7d0ff50bf156347
diff --git a/Gopkg.lock b/Gopkg.lock
index a3bcdfd..11f90bd 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -226,10 +226,12 @@
   version = "v1.1.2"
 
 [[projects]]
-  digest = "1:b30281898441857fadb7fa63751557615727d2d9dabc2e0a982a366594504f12"
+  branch = "master"
+  digest = "1:9302a6372545bf96d2aaa1f6ce2eb9f6bf815f582bd63753cc378de6405f85a0"
   name = "github.com/opencord/voltha-go"
   packages = [
     "adapters",
+    "adapters/adapterif",
     "adapters/common",
     "common/log",
     "common/ponresourcemanager",
@@ -240,8 +242,7 @@
     "rw_core/utils",
   ]
   pruneopts = "UT"
-  revision = "23a112405b76f12b432e7439e9748daba6c06e9b"
-  version = "2.1.1"
+  revision = "84169b5c5b9913aa612f3145b2a39c288ecd53d1"
 
 [[projects]]
   digest = "1:78a853c38b4935f01a99fbb41edbb4382a23586f929ecf02dd80d4452f2e3c0d"
diff --git a/Gopkg.toml b/Gopkg.toml
index a86a5f1..b400baf 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -34,7 +34,7 @@
   version = "1.3.1"
 
 [[constraint]]
-  version = "2.1.1"
+  branch = "master"
   name = "github.com/opencord/voltha-go"
 
 [[constraint]]
diff --git a/adaptercore/device_handler.go b/adaptercore/device_handler.go
index 287f927..52e4afd 100644
--- a/adaptercore/device_handler.go
+++ b/adaptercore/device_handler.go
@@ -275,6 +275,10 @@
 		}
 		if err != nil {
 			log.Infow("Failed to read from indications", log.Fields{"err": err})
+			if dh.adminState == "deleted" {
+				log.Debug("Device deleted stoping the read indication thread")
+				break
+			}
 			dh.transitionMap.Handle(DeviceDownInd)
 			dh.transitionMap.Handle(DeviceInit)
 			break
@@ -1055,6 +1059,113 @@
 	return nil
 }
 
+func (dh *DeviceHandler) clearUNIData(onu *OnuDevice, uniPorts []*voltha.Port) error {
+	var uniID uint32
+	var err error
+	for _, port := range uniPorts {
+		if port.Type == voltha.Port_ETHERNET_UNI {
+			uniID = UniIDFromPortNum(port.PortNo)
+			/* Delete tech-profile instance from the KV store */
+			if err = dh.flowMgr.DeleteTechProfileInstance(onu.intfID, onu.onuID, uniID, onu.serialNumber); err != nil {
+				log.Debugw("Failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.onuID})
+			}
+			log.Debugw("Deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.onuID})
+			flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(onu.intfID, onu.onuID, uniID)
+			for _, flowID := range flowIDs {
+				dh.resourceMgr.FreeFlowID(onu.intfID, int32(onu.onuID), int32(uniID), flowID)
+			}
+			dh.resourceMgr.FreePONResourcesForONU(onu.intfID, onu.onuID, uniID)
+			if err = dh.resourceMgr.RemoveTechProfileIDForOnu(onu.intfID, onu.onuID, uniID); err != nil {
+				log.Debugw("Failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.onuID})
+			}
+			log.Debugw("Removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.onuID})
+			if err = dh.resourceMgr.RemoveMeterIDForOnu("upstream", onu.intfID, onu.onuID, uniID); err != nil {
+				log.Debugw("Failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.onuID})
+			}
+			log.Debugw("Removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.onuID})
+			if err = dh.resourceMgr.RemoveMeterIDForOnu("downstream", onu.intfID, onu.onuID, uniID); err != nil {
+				log.Debugw("Failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.onuID})
+			}
+			log.Debugw("Removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.onuID})
+		}
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) clearNNIData() error {
+	nniUniID := -1
+	nniOnuID := -1
+	flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(uint32(dh.nniIntfID), uint32(nniOnuID), uint32(nniUniID))
+	log.Debugw("Current flow ids for nni", log.Fields{"flow-ids": flowIDs})
+	for _, flowID := range flowIDs {
+		dh.resourceMgr.FreeFlowID(uint32(dh.nniIntfID), -1, -1, uint32(flowID))
+	}
+	//Free the flow-ids for the NNI port
+	dh.resourceMgr.FreePONResourcesForONU(uint32(dh.nniIntfID), uint32(nniOnuID), uint32(nniUniID))
+	/* Free ONU IDs for each pon port
+	   intfIDToONUIds is a map of intf-id: [onu-ids]*/
+	intfIDToONUIds := make(map[uint32][]uint32)
+	for _, onu := range dh.onus {
+		intfIDToONUIds[onu.intfID] = append(intfIDToONUIds[onu.intfID], onu.onuID)
+	}
+	for intfID, onuIds := range intfIDToONUIds {
+		dh.resourceMgr.FreeonuID(intfID, onuIds)
+	}
+	return nil
+}
+
+// DeleteDevice deletes the device instance from openolt handler array.  Also clears allocated resource manager resources.  Also reboots the OLT hardware!
+func (dh *DeviceHandler) DeleteDevice(device *voltha.Device) error {
+	log.Debug("Function entry delete device")
+	dh.lockDevice.Lock()
+	dh.adminState = "deleted"
+	dh.lockDevice.Unlock()
+	/* Clear the KV store data associated with the all the UNI ports
+	   This clears up flow data and also resource map data for various
+	   other pon resources like alloc_id and gemport_id
+	*/
+	for _, onu := range dh.onus {
+		childDevice, err := dh.coreProxy.GetDevice(nil, dh.deviceID, onu.deviceID)
+		if err != nil {
+			log.Debug("Failed to get onu device")
+			continue
+		}
+		uniPorts := childDevice.Ports
+		log.Debugw("onu-uni-ports", log.Fields{"onu-ports": uniPorts})
+		if err := dh.clearUNIData(onu, uniPorts); err != nil {
+			log.Debugw("Failed to clear data for onu", log.Fields{"onu-device": onu})
+		}
+	}
+	/* Clear the flows from KV store associated with NNI port.
+	   There are mostly trap rules from NNI port (like LLDP)
+	*/
+	if err := dh.clearNNIData(); err != nil {
+		log.Debugw("Failed to clear data for NNI port", log.Fields{"device-id": dh.deviceID})
+	}
+	/* Clear the resource pool for each PON port*/
+	if err := dh.resourceMgr.Delete(); err != nil {
+		log.Debug("Failed-to-remove-device-from-Resource-mananger-KV-store")
+	}
+	/*Delete ONU map for the device*/
+	for onu := range dh.onus {
+		delete(dh.onus, onu)
+	}
+	log.Debug("Removed-device-from-Resource-manager-KV-store")
+	//Reset the state
+	if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
+		log.Errorw("Failed-to-reboot-olt ", log.Fields{"err": err})
+		return err
+	}
+	cloned := proto.Clone(device).(*voltha.Device)
+	cloned.OperStatus = voltha.OperStatus_UNKNOWN
+	cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
+	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
+		log.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": err})
+		return err
+	}
+	return nil
+}
+
 //RebootDevice reboots the given device
 func (dh *DeviceHandler) RebootDevice(device *voltha.Device) error {
 	if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
diff --git a/adaptercore/openolt.go b/adaptercore/openolt.go
index 3d10a6f..0da66ff 100644
--- a/adaptercore/openolt.go
+++ b/adaptercore/openolt.go
@@ -240,7 +240,16 @@
 
 //Delete_device unimplemented
 func (oo *OpenOLT) Delete_device(device *voltha.Device) error {
-	return errors.New("unImplemented")
+	log.Infow("delete-device", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		if err := handler.DeleteDevice(device); err != nil {
+			log.Errorw("failed-to-handle-delete-device", log.Fields{"device-id": device.Id})
+		}
+		oo.deleteDeviceHandlerToMap(handler)
+		return nil
+	}
+	log.Errorw("device-handler-not-set", log.Fields{"deviceId": device.Id})
+	return errors.New("device-handler-not-found")
 }
 
 //Get_device_details unimplemented
diff --git a/adaptercore/openolt_flowmgr.go b/adaptercore/openolt_flowmgr.go
index 4b3be6a..55fd1df 100644
--- a/adaptercore/openolt_flowmgr.go
+++ b/adaptercore/openolt_flowmgr.go
@@ -889,6 +889,17 @@
 	return f.techprofile[intfID].GetTechProfileInstanceKVPath(TpID, uni)
 }
 
+// DeleteTechProfileInstance removes the tech profile instance from persistent storage
+func (f *OpenOltFlowMgr) DeleteTechProfileInstance(intfID uint32, onuID uint32, uniID uint32, sn string) error {
+	tpID := f.resourceMgr.GetTechProfileIDForOnu(intfID, onuID, uniID)
+	uniPortName := fmt.Sprintf("pon-{%d}/onu-{%d}/uni-{%d}", intfID, onuID, uniID)
+	if err := f.techprofile[intfID].DeleteTechProfileInstance(tpID, uniPortName); err != nil {
+		log.Debugw("Failed-to-delete-tp-instance-from-kv-store", log.Fields{"tp-id": tpID, "uni-port-name": uniPortName})
+		return err
+	}
+	return nil
+}
+
 func getFlowStoreCookie(classifier map[string]interface{}, gemPortID uint32) uint64 {
 	if len(classifier) == 0 { // should never happen
 		log.Error("Invalid classfier object")
@@ -994,7 +1005,7 @@
 
 	if err != nil {
 		log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": deviceFlow})
-		f.resourceMgr.FreeFlowID(intfID, uint32(deviceFlow.OnuId), uint32(deviceFlow.UniId), deviceFlow.FlowId)
+		f.resourceMgr.FreeFlowID(intfID, deviceFlow.OnuId, deviceFlow.UniId, deviceFlow.FlowId)
 		return false
 	}
 	log.Debugw("Flow added to device successfully ", log.Fields{"flow": *deviceFlow})
@@ -1109,7 +1120,7 @@
 		f.updateFlowInfoToKVStore(int32(ponIntf), int32(onuID), int32(uniID), flowID, &updatedFlows)
 		if len(updatedFlows) == 0 {
 			log.Debugw("Releasing flow Id to resource manager", log.Fields{"ponIntf": ponIntf, "onuId": onuID, "uniId": uniID, "flowId": flowID})
-			f.resourceMgr.FreeFlowID(ponIntf, onuID, uniID, flowID)
+			f.resourceMgr.FreeFlowID(ponIntf, int32(onuID), int32(uniID), flowID)
 		}
 	}
 	flowIds := f.resourceMgr.GetCurrentFlowIDsForOnu(ponIntf, onuID, uniID)
diff --git a/adaptercore/resourcemanager/resourcemanager.go b/adaptercore/resourcemanager/resourcemanager.go
index bb78ebd..4b0220b 100755
--- a/adaptercore/resourcemanager/resourcemanager.go
+++ b/adaptercore/resourcemanager/resourcemanager.go
@@ -336,27 +336,38 @@
 	ponRMgr.UpdateRanges(ponrmgr.UNI_ID_START_IDX, 0, ponrmgr.UNI_ID_END_IDX /* TODO =OpenOltPlatform.MAX_UNIS_PER_ONU-1*/, 1, "", 0, nil)
 }
 
-/* TODO
-def __del__(self):
-        self.log.info("clearing-device-resource-pool")
-        for key, resource_mgr in self.resource_mgrs.iteritems():
-            resource_mgr.clear_device_resource_pool()
+// Delete clears used resources for the particular olt device being deleted
+func (RsrcMgr *OpenOltResourceMgr) Delete() error {
+	/* TODO
+	   def __del__(self):
+	           self.log.info("clearing-device-resource-pool")
+	           for key, resource_mgr in self.resource_mgrs.iteritems():
+	               resource_mgr.clear_device_resource_pool()
 
-    def assert_pon_id_limit(self, pon_intf_id):
-        assert pon_intf_id in self.resource_mgrs
+	       def assert_pon_id_limit(self, pon_intf_id):
+	           assert pon_intf_id in self.resource_mgrs
 
-    def assert_onu_id_limit(self, pon_intf_id, onu_id):
-        self.assert_pon_id_limit(pon_intf_id)
-        self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID)
+	       def assert_onu_id_limit(self, pon_intf_id, onu_id):
+	           self.assert_pon_id_limit(pon_intf_id)
+	           self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID)
 
-    @property
-    def max_uni_id_per_onu(self):
-        return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni
+	       @property
+	       def max_uni_id_per_onu(self):
+	           return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni
 
-    def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id):
-        self.assert_onu_id_limit(pon_intf_id, onu_id)
-        self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID)
-*/
+	       def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id):
+	           self.assert_onu_id_limit(pon_intf_id, onu_id)
+	           self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID)
+	*/
+	for _, rsrcMgr := range RsrcMgr.ResourceMgrs {
+		if err := rsrcMgr.ClearDeviceResourcePool(); err != nil {
+			log.Debug("Failed to clear device resource pool")
+			return err
+		}
+	}
+	log.Debug("Cleared device resource pool")
+	return nil
+}
 
 // GetONUID returns the available OnuID for the given pon-port
 func (RsrcMgr *OpenOltResourceMgr) GetONUID(ponIntfID uint32) (uint32, error) {
@@ -374,7 +385,7 @@
 		return ONUID[0], err
 	}
 	if ONUID != nil {
-		RsrcMgr.ResourceMgrs[ponIntfID].InitResourceMap(fmt.Sprintf("%d,%d", ponIntfID, ONUID))
+		RsrcMgr.ResourceMgrs[ponIntfID].InitResourceMap(fmt.Sprintf("%d,%d", ponIntfID, ONUID[0]))
 		return ONUID[0], err
 	}
 
@@ -603,8 +614,8 @@
 }
 
 // FreeFlowID returns the free flow id for a given interface, onu id and uni id
-func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(IntfID uint32, onuID uint32,
-	uniID uint32, FlowID uint32) {
+func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(IntfID uint32, onuID int32,
+	uniID int32, FlowID uint32) {
 	var IntfONUID string
 	var err error
 	IntfONUID = fmt.Sprintf("%d,%d,%d", IntfID, onuID, uniID)
@@ -656,10 +667,11 @@
 	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(intfID,
 		ponrmgr.FLOW_ID,
 		FlowIDs)
-	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(intfID,
-		ponrmgr.ONU_ID,
-		onuIDs)
-
+	if int32(onuID) >= 0 {
+		RsrcMgr.ResourceMgrs[intfID].FreeResourceID(intfID,
+			ponrmgr.ONU_ID,
+			onuIDs)
+	}
 	// Clear resource map associated with (pon_intf_id, gemport_id) tuple.
 	RsrcMgr.ResourceMgrs[intfID].RemoveResourceMap(IntfOnuIDUniID)
 
diff --git a/vendor/github.com/opencord/voltha-go/adapters/adapterif/adapter_proxy_if.go b/vendor/github.com/opencord/voltha-go/adapters/adapterif/adapter_proxy_if.go
new file mode 100644
index 0000000..26b1448
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-go/adapters/adapterif/adapter_proxy_if.go
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package adapterif
+
+import (
+	"context"
+
+	"github.com/golang/protobuf/proto"
+	ic "github.com/opencord/voltha-protos/go/inter_container"
+)
+
+// AdapterProxy interface for AdapterProxy implementation.
+type AdapterProxy interface {
+	SendInterAdapterMessage(ctx context.Context,
+		msg proto.Message,
+		msgType ic.InterAdapterMessageType_Types,
+		fromAdapter string,
+		toAdapter string,
+		toDeviceID string,
+		proxyDeviceID string,
+		messageID string) error
+}
diff --git a/vendor/github.com/opencord/voltha-go/adapters/adapterif/core_proxy_if.go b/vendor/github.com/opencord/voltha-go/adapters/adapterif/core_proxy_if.go
new file mode 100644
index 0000000..26d021f
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-go/adapters/adapterif/core_proxy_if.go
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package adapterif
+
+import (
+	"context"
+
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+// CoreProxy interface for voltha-go coreproxy.
+type CoreProxy interface {
+	UpdateCoreReference(deviceID string, coreReference string)
+	DeleteCoreReference(deviceID string)
+	// getCoreTopic(deviceID string) kafka.Topic
+	//GetAdapterTopic(args ...string) kafka.Topic
+	// getAdapterTopic(args ...string) kafka.Topic
+	RegisterAdapter(ctx context.Context, adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) error
+	DeviceUpdate(ctx context.Context, device *voltha.Device) error
+	PortCreated(ctx context.Context, deviceID string, port *voltha.Port) error
+	PortsStateUpdate(ctx context.Context, deviceID string, operStatus voltha.OperStatus_OperStatus) error
+	DeleteAllPorts(ctx context.Context, deviceID string) error
+	DeviceStateUpdate(ctx context.Context, deviceID string,
+		connStatus voltha.ConnectStatus_ConnectStatus, operStatus voltha.OperStatus_OperStatus) error
+
+	ChildDeviceDetected(ctx context.Context, parentDeviceID string, parentPortNo int,
+		childDeviceType string, channelID int, vendorID string, serialNumber string, onuID int64) (*voltha.Device, error)
+
+	ChildDevicesLost(ctx context.Context, parentDeviceID string) error
+	ChildDevicesDetected(ctx context.Context, parentDeviceID string) error
+	GetDevice(ctx context.Context, parentDeviceID string, deviceID string) (*voltha.Device, error)
+	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
+}
diff --git a/vendor/github.com/opencord/voltha-go/adapters/adapterif/events_proxy_if.go b/vendor/github.com/opencord/voltha-go/adapters/adapterif/events_proxy_if.go
new file mode 100644
index 0000000..00a86a5
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-go/adapters/adapterif/events_proxy_if.go
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package adapterif
+
+import (
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+// EventProxy interface for eventproxy
+type EventProxy interface {
+	SendDeviceEvent(deviceEvent *voltha.DeviceEvent, category EventCategory,
+		subCategory EventSubCategory, raisedTs int64) error
+}
+
+const (
+	EventTypeVersion = "0.1"
+)
+
+type (
+	EventType        = voltha.EventType_EventType
+	EventCategory    = voltha.EventCategory_EventCategory
+	EventSubCategory = voltha.EventSubCategory_EventSubCategory
+)
diff --git a/vendor/github.com/opencord/voltha-go/adapters/common/events_proxy.go b/vendor/github.com/opencord/voltha-go/adapters/common/events_proxy.go
index 1f14b3a..34fcde7 100644
--- a/vendor/github.com/opencord/voltha-go/adapters/common/events_proxy.go
+++ b/vendor/github.com/opencord/voltha-go/adapters/common/events_proxy.go
@@ -19,22 +19,14 @@
 import (
 	"errors"
 	"fmt"
-	"github.com/opencord/voltha-go/common/log"
-	"github.com/opencord/voltha-go/kafka"
-	"github.com/opencord/voltha-protos/go/voltha"
 	"strconv"
 	"strings"
 	"time"
-)
 
-const (
-	EventTypeVersion = "0.1"
-)
-
-type (
-	EventType        = voltha.EventType_EventType
-	EventCategory    = voltha.EventCategory_EventCategory
-	EventSubCategory = voltha.EventSubCategory_EventSubCategory
+	"github.com/opencord/voltha-go/adapters/adapterif"
+	"github.com/opencord/voltha-go/common/log"
+	"github.com/opencord/voltha-go/kafka"
+	"github.com/opencord/voltha-protos/go/voltha"
 )
 
 type EventProxy struct {
@@ -68,7 +60,7 @@
 	return fmt.Sprintf("Voltha.openolt.%s.%s", eventName, strconv.FormatInt(time.Now().UnixNano(), 10))
 }
 
-func (ep *EventProxy) getEventHeader(eventName string, category EventCategory, subCategory EventSubCategory, eventType EventType, raisedTs int64) *voltha.EventHeader {
+func (ep *EventProxy) getEventHeader(eventName string, category adapterif.EventCategory, subCategory adapterif.EventSubCategory, eventType adapterif.EventType, raisedTs int64) *voltha.EventHeader {
 	var header voltha.EventHeader
 	if strings.Contains(eventName, "_") {
 		eventName = strings.Join(strings.Split(eventName, "_")[:len(strings.Split(eventName, "_"))-2], "_")
@@ -80,14 +72,14 @@
 	header.Category = category
 	header.SubCategory = subCategory
 	header.Type = eventType
-	header.TypeVersion = EventTypeVersion
+	header.TypeVersion = adapterif.EventTypeVersion
 	header.RaisedTs = float32(raisedTs)
 	header.ReportedTs = float32(time.Now().UnixNano())
 	return &header
 }
 
 /* Send out device events*/
-func (ep *EventProxy) SendDeviceEvent(deviceEvent *voltha.DeviceEvent, category EventCategory, subCategory EventSubCategory, raisedTs int64) error {
+func (ep *EventProxy) SendDeviceEvent(deviceEvent *voltha.DeviceEvent, category adapterif.EventCategory, subCategory adapterif.EventSubCategory, raisedTs int64) error {
 	if deviceEvent == nil {
 		log.Error("Recieved empty device event")
 		return errors.New("Device event nil")
diff --git a/vendor/github.com/opencord/voltha-go/adapters/common/request_handler.go b/vendor/github.com/opencord/voltha-go/adapters/common/request_handler.go
index b18f1d1..55e04d7 100644
--- a/vendor/github.com/opencord/voltha-go/adapters/common/request_handler.go
+++ b/vendor/github.com/opencord/voltha-go/adapters/common/request_handler.go
@@ -20,6 +20,7 @@
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes/empty"
 	"github.com/opencord/voltha-go/adapters"
+	"github.com/opencord/voltha-go/adapters/adapterif"
 	"github.com/opencord/voltha-go/common/log"
 	"github.com/opencord/voltha-go/kafka"
 	ic "github.com/opencord/voltha-protos/go/inter_container"
@@ -33,10 +34,10 @@
 	TestMode       bool
 	coreInstanceId string
 	adapter        adapters.IAdapter
-	coreProxy      *CoreProxy
+	coreProxy      adapterif.CoreProxy
 }
 
-func NewRequestHandlerProxy(coreInstanceId string, iadapter adapters.IAdapter, cProxy *CoreProxy) *RequestHandlerProxy {
+func NewRequestHandlerProxy(coreInstanceId string, iadapter adapters.IAdapter, cProxy adapterif.CoreProxy) *RequestHandlerProxy {
 	var proxy RequestHandlerProxy
 	proxy.coreInstanceId = coreInstanceId
 	proxy.adapter = iadapter
diff --git a/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
index b4f9130..74734f0 100755
--- a/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
+++ b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
@@ -395,6 +395,69 @@
 	return err
 }
 
+func (PONRMgr *PONResourceManager) ClearDeviceResourcePool() error {
+
+	//Clear resource pool for all PON ports.
+
+	log.Debug("Clear resource ranges")
+
+	for _, Intf := range PONRMgr.IntfIDs {
+		SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
+		if SharedPoolID != 0 {
+			Intf = SharedPoolID
+		}
+		if status := PONRMgr.ClearResourceIDPool(Intf, ONU_ID); status != true {
+			log.Error("Failed to clear ONU ID resource pool")
+			return errors.New("Failed to clear ONU ID resource pool")
+		}
+		if SharedPoolID != 0 {
+			break
+		}
+	}
+
+	for _, Intf := range PONRMgr.IntfIDs {
+		SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
+		if SharedPoolID != 0 {
+			Intf = SharedPoolID
+		}
+		if status := PONRMgr.ClearResourceIDPool(Intf, ALLOC_ID); status != true {
+			log.Error("Failed to clear ALLOC ID resource pool ")
+			return errors.New("Failed to clear ALLOC ID resource pool")
+		}
+		if SharedPoolID != 0 {
+			break
+		}
+	}
+	for _, Intf := range PONRMgr.IntfIDs {
+		SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
+		if SharedPoolID != 0 {
+			Intf = SharedPoolID
+		}
+		if status := PONRMgr.ClearResourceIDPool(Intf, GEMPORT_ID); status != true {
+			log.Error("Failed to clear GEMPORT ID resource pool")
+			return errors.New("Failed to clear GEMPORT ID resource pool")
+		}
+		if SharedPoolID != 0 {
+			break
+		}
+	}
+
+	for _, Intf := range PONRMgr.IntfIDs {
+		SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
+		if SharedPoolID != 0 {
+			Intf = SharedPoolID
+		}
+		if status := PONRMgr.ClearResourceIDPool(Intf, FLOW_ID); status != true {
+			log.Error("Failed to clear FLOW ID resource pool")
+			return errors.New("Failed to clear FLOW ID resource pool")
+		}
+		if SharedPoolID != 0 {
+			break
+		}
+	}
+	return nil
+}
+
 func (PONRMgr *PONResourceManager) InitResourceIDPool(Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
 
 	/*Initialize Resource ID pool for a given Resource Type on a given PON Port
diff --git a/vendor/github.com/opencord/voltha-go/db/kvstore/client.go b/vendor/github.com/opencord/voltha-go/db/kvstore/client.go
index 937eefe..67c9219 100644
--- a/vendor/github.com/opencord/voltha-go/db/kvstore/client.go
+++ b/vendor/github.com/opencord/voltha-go/db/kvstore/client.go
@@ -77,7 +77,7 @@
 	return evnt
 }
 
-// Client represents the set of APIs  a KV Client must implement
+// Client represents the set of APIs a KV Client must implement
 type Client interface {
 	List(key string, timeout int, lock ...bool) (map[string]*KVPair, error)
 	Get(key string, timeout int, lock ...bool) (*KVPair, error)
@@ -90,6 +90,7 @@
 	Watch(key string) chan *Event
 	AcquireLock(lockName string, timeout int) error
 	ReleaseLock(lockName string) error
+	IsConnectionUp(timeout int) bool // timeout in second
 	CloseWatch(key string, ch chan *Event)
 	Close()
 }
diff --git a/vendor/github.com/opencord/voltha-go/db/kvstore/consulclient.go b/vendor/github.com/opencord/voltha-go/db/kvstore/consulclient.go
index 4b25b5f..c4fa0af 100644
--- a/vendor/github.com/opencord/voltha-go/db/kvstore/consulclient.go
+++ b/vendor/github.com/opencord/voltha-go/db/kvstore/consulclient.go
@@ -63,6 +63,12 @@
 	return &ConsulClient{consul: consul, doneCh: &doneCh, watchedChannelsContext: wChannelsContext, keyReservations: reservations}, nil
 }
 
+// IsConnectionUp returns whether the connection to the Consul KV store is up
+func (c *ConsulClient) IsConnectionUp(timeout int) bool {
+	log.Error("Unimplemented function")
+	return false
+}
+
 // List returns an array of key-value pairs with key as a prefix.  Timeout defines how long the function will
 // wait for a response
 func (c *ConsulClient) List(key string, timeout int, lock ...bool) (map[string]*KVPair, error) {
diff --git a/vendor/github.com/opencord/voltha-go/db/kvstore/etcdclient.go b/vendor/github.com/opencord/voltha-go/db/kvstore/etcdclient.go
index 7f6940a..f19f365 100644
--- a/vendor/github.com/opencord/voltha-go/db/kvstore/etcdclient.go
+++ b/vendor/github.com/opencord/voltha-go/db/kvstore/etcdclient.go
@@ -59,6 +59,16 @@
 		lockToSessionMap: lockSessionMap}, nil
 }
 
+// IsConnectionUp returns whether the connection to the Etcd KV store is up.  If a timeout occurs then
+// it is assumed the connection is down or unreachable.
+func (c *EtcdClient) IsConnectionUp(timeout int) bool {
+	// Let's try to get a non existent key.  If the connection is up then there will be no error returned.
+	if _, err := c.Get("non-existent-key", timeout); err != nil {
+		return false
+	}
+	return true
+}
+
 // List returns an array of key-value pairs with key as a prefix.  Timeout defines how long the function will
 // wait for a response
 func (c *EtcdClient) List(key string, timeout int, lock ...bool) (map[string]*KVPair, error) {
diff --git a/vendor/github.com/opencord/voltha-go/db/model/node.go b/vendor/github.com/opencord/voltha-go/db/model/node.go
index fcd3b5f..c9815fa 100644
--- a/vendor/github.com/opencord/voltha-go/db/model/node.go
+++ b/vendor/github.com/opencord/voltha-go/db/model/node.go
@@ -457,7 +457,7 @@
 	n.mutex.Lock()
 	defer n.mutex.Unlock()
 
-	log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid": txid, "makeBranch": makeBranch})
+	log.Debugw("node-update-request", log.Fields{"path": path, "strict": strict, "txid": txid})
 
 	for strings.HasPrefix(path, "/") {
 		path = path[1:]
@@ -626,7 +626,7 @@
 	n.mutex.Lock()
 	defer n.mutex.Unlock()
 
-	log.Debugw("node-add-request", log.Fields{"path": path, "txid": txid, "makeBranch": makeBranch})
+	log.Debugw("node-add-request", log.Fields{"path": path, "txid": txid})
 
 	for strings.HasPrefix(path, "/") {
 		path = path[1:]
diff --git a/vendor/github.com/opencord/voltha-go/kafka/sarama_client.go b/vendor/github.com/opencord/voltha-go/kafka/sarama_client.go
index 0576da9..8037002 100755
--- a/vendor/github.com/opencord/voltha-go/kafka/sarama_client.go
+++ b/vendor/github.com/opencord/voltha-go/kafka/sarama_client.go
@@ -228,6 +228,13 @@
 
 	var err error
 
+	// Add a cleanup in case of failure to startup
+	defer func() {
+		if err != nil {
+			sc.Stop()
+		}
+	}()
+
 	// Create the Cluster Admin
 	if err = sc.createClusterAdmin(); err != nil {
 		log.Errorw("Cannot-create-cluster-admin", log.Fields{"error": err})