[VOL-4123] Fix no flows being discarded by ofAgent

This commit fixes an issue in ofAgent where it fails to send
stats to ONOS if there are no flows/ no ports/ no port desc.  This
situation arises if the rw-core does not persist flows and is
restarted.

This fix was tested with a rw-core that does not persist flows,
meters and groups.  The rw-core was restarted after 512 ONUs were
already activated and had their flows pushed.  After the rw-core
retart, with this fix, the flows were pushed from ONOS.

Change-Id: I10ee627e4153134ec5a5d12d1dcd67f64213e83d
diff --git a/VERSION b/VERSION
index 9c6d629..fdd3be6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.1
+1.6.2
diff --git a/internal/pkg/openflow/stats.go b/internal/pkg/openflow/stats.go
index 1cd656e..1cc9926 100644
--- a/internal/pkg/openflow/stats.go
+++ b/internal/pkg/openflow/stats.go
@@ -343,7 +343,7 @@
 	if err != nil {
 		return nil, err
 	}
-	logger.Debugw(ctx, "logicalDeviceFlows", log.Fields{"flows": resp})
+	logger.Debugw(ctx, "logicalDeviceFlows", log.Fields{"logical-device-id": ofc.DeviceID, "num-flows": len(resp.Items)})
 	var flows []*ofp.FlowStatsEntry
 	for _, item := range resp.GetItems() {
 		entry := ofp.NewFlowStatsEntry()
@@ -387,23 +387,29 @@
 		flows = append(flows, entry)
 	}
 	var responses []*ofp.FlowStatsReply
+
 	chunkSize := ofc.flowsChunkSize
 	total := len(flows) / chunkSize
 	n := 0
 	for n <= total {
+		response := ofp.NewFlowStatsReply()
+		response.SetXid(request.GetXid())
+		response.SetVersion(request.GetVersion())
+		response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
 
 		limit := (n * chunkSize) + chunkSize
-
 		chunk := flows[n*chunkSize : min(limit, len(flows))]
 
 		if len(chunk) == 0 {
+			// Special case - no flows
+			if len(flows) == 0 {
+				logger.Debugw(ctx, "no-flows-present", log.Fields{"logical-device-id": ofc.DeviceID})
+				response.SetEntries(chunk)
+				responses = append(responses, response)
+			}
 			break
 		}
 
-		response := ofp.NewFlowStatsReply()
-		response.SetXid(request.GetXid())
-		response.SetVersion(4)
-		response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
 		if limit < len(flows) {
 			response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
 		}
@@ -607,24 +613,32 @@
 	}
 
 	var responses []*ofp.PortStatsReply
+
 	chunkSize := ofc.portsChunkSize
 	total := len(entries) / chunkSize
 	n := 0
 	for n <= total {
+		response := ofp.NewPortStatsReply()
+		response.SetXid(request.GetXid())
+		response.SetVersion(request.GetVersion())
+		response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
 
 		chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
 
 		if len(chunk) == 0 {
+			// handle the case of no ports
+			if len(entries) == 0 {
+				logger.Debugw(ctx, "no-ports-present", log.Fields{"logical-device-id": ofc.DeviceID})
+				response.SetEntries(chunk)
+				responses = append(responses, response)
+			}
 			break
 		}
 
-		response := ofp.NewPortStatsReply()
-		response.SetXid(request.GetXid())
-		response.SetVersion(request.GetVersion())
 		if total != n {
 			response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
 		}
-		response.SetEntries(entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))])
+		response.SetEntries(chunk)
 		responses = append(responses, response)
 		n++
 	}
@@ -667,21 +681,27 @@
 	}
 
 	var responses []*ofp.PortDescStatsReply
+
 	chunkSize := ofc.portsDescChunkSize
 	total := len(entries) / chunkSize
 	n := 0
 	for n <= total {
-
-		chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
-
-		if len(chunk) == 0 {
-			break
-		}
-
 		response := ofp.NewPortDescStatsReply()
 		response.SetVersion(request.GetVersion())
 		response.SetXid(request.GetXid())
 		response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
+
+		chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
+
+		if len(chunk) == 0 {
+			if len(entries) == 0 {
+				logger.Debugw(ctx, "no-ports-desc-present", log.Fields{"logical-device-id": ofc.DeviceID})
+				response.SetEntries(chunk)
+				responses = append(responses, response)
+			}
+			break
+		}
+
 		if total != n {
 			response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
 		}