[VOL-1703]:
While adding flow for a device, adapter makes sync call to core to fetch
the OLT device structure. The NNI Intf ID was then fetched from the OLT
device structure.
This sync call during flow processing takes more seconds (2-3~ secs),
but core has default timeout 500ms and used to timeout. On failure it
used to re-initiate the whole procedure again. This was going on in an
endless loop.
To fix this problem, the NNI Intf ID is cached locally in the adapter,
and there is no query initiated to Core.

Change-Id: I0f9a333f44ec528517d23342c5eb7fdf1affd2e2
diff --git a/adaptercore/device_handler.go b/adaptercore/device_handler.go
index 20eb783..5fddcf7 100644
--- a/adaptercore/device_handler.go
+++ b/adaptercore/device_handler.go
@@ -51,8 +51,6 @@
 	coreProxy     *com.CoreProxy
 	AdapterProxy  *com.AdapterProxy
 	openOLT       *OpenOLT
-	nniPort       *voltha.Port
-	ponPort       *voltha.Port
 	exitChannel   chan int
 	lockDevice    sync.RWMutex
 	Client        oop.OpenoltClient
@@ -62,6 +60,7 @@
 	resourceMgr   *rsrcMgr.OpenOltResourceMgr
 	discOnus      map[string]bool
 	onus          map[string]*OnuDevice
+	nniIntfId     int
 }
 
 type OnuDevice struct {
@@ -100,6 +99,10 @@
 	dh.discOnus = make(map[string]bool)
 	dh.lockDevice = sync.RWMutex{}
 	dh.onus = make(map[string]*OnuDevice)
+	// The nniIntfId is initialized to -1 (invalid) and set to right value
+	// when the first IntfOperInd with status as "up" is received for
+	// any one of the available NNI port on the OLT device.
+	dh.nniIntfId = -1
 
 	//TODO initialize the support classes.
 	return &dh
@@ -173,7 +176,13 @@
 	log.Debugw("Sending port update to core", log.Fields{"port": port})
 	// Synchronous call to update device - this method is run in its own go routine
 	if err := dh.coreProxy.PortCreated(nil, dh.device.Id, port); err != nil {
-		log.Errorw("error-creating-nni-port", log.Fields{"deviceId": dh.device.Id, "error": err})
+		log.Errorw("error-creating-port", log.Fields{"deviceId": dh.device.Id, "portType": portType, "error": err})
+		return
+	}
+	// Once we have successfully added the NNI port to the core, if the
+	// locally cached nniIntfId is set to invalid (-1), set it to the right value.
+	if portType == voltha.Port_ETHERNET_NNI && dh.nniIntfId == -1 {
+		dh.nniIntfId = int(intfId)
 	}
 }
 
diff --git a/adaptercore/openolt_flowmgr.go b/adaptercore/openolt_flowmgr.go
index 570fff6..19abc26 100644
--- a/adaptercore/openolt_flowmgr.go
+++ b/adaptercore/openolt_flowmgr.go
@@ -380,11 +380,7 @@
 		return
 	}
 	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
-	networkIntfId, err := f.getNniIntfID()
-	if err != nil {
-		log.Error("Error in getting NNI interface ID, Failed to add HSIA flow")
-		return
-	}
+	networkIntfId := f.deviceHandler.nniIntfId
 	flow := openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
 		UniId:         int32(uniId),
@@ -447,11 +443,7 @@
 		log.Error("Error in making action protobuf for ul flow")
 		return
 	}
-	networkIntfId, err := f.getNniIntfID()
-	if err != nil {
-		log.Error("Error in getting NNI interface ID, Failed to add DHCP Trap Flow")
-		return
-	}
+	networkIntfId := f.deviceHandler.nniIntfId
 
 	dhcpFlow = openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
@@ -520,11 +512,7 @@
 		return
 	}
 	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
-	networkIntfId, err := f.getNniIntfID()
-	if err != nil {
-		log.Error("Error in getting NNI interface ID, Failed to add EAPOL Flow")
-		return
-	}
+	networkIntfId := f.deviceHandler.nniIntfId
 	upstreamFlow = openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
 		UniId:         int32(uniId),
@@ -1224,11 +1212,7 @@
 	uniId := -1
 	gemPortId := -1
 	allocId := -1
-	networkInterfaceId, err := f.getNniIntfID()
-	if err != nil {
-		log.Error("Error in getting NNI interface ID, Failed to add DHCP Trap flow on NNI")
-		return
-	}
+	networkInterfaceId := f.deviceHandler.nniIntfId
 	flowStoreCookie := getFlowStoreCookie(classifier, uint32(0))
 	if present := f.resourceMgr.IsFlowCookieOnKVStore(uint32(networkInterfaceId), uint32(onuId), uint32(uniId), flowStoreCookie); present {
 		log.Debug("Flow-exists--not-re-adding")
@@ -1276,22 +1260,3 @@
 	}
 	return
 }
-
-func (f *OpenOltFlowMgr) getNniIntfID() (int32, error) {
-	device, err := f.deviceHandler.coreProxy.GetDevice(nil, f.deviceHandler.deviceId, f.deviceHandler.deviceId)
-	if err != nil {
-		log.Errorw("Failed to get device", log.Fields{"device-id": f.deviceHandler.deviceId})
-		return -1, err
-	}
-	var portNum uint32
-	for _, port := range device.Ports {
-		if port.Type == voltha.Port_ETHERNET_NNI {
-			portNum = port.PortNo
-			break
-		}
-	}
-
-	nniIntfId := IntfIdFromNniPortNum(portNum)
-	log.Debugw("NNI interface Id", log.Fields{"intf-id": nniIntfId})
-	return int32(nniIntfId), nil
-}