VOL-1623-meter support and handling  techprofile and fix for flow delete , now migrated to onosproject/onos:1.13.9-rc4

Change in flowupdate API towards adapters

Remove meter_get API from adapter to core

Added dependent vendor library files downloaded  by "dep-ensure -update"

Added techprofile changes in the single commit

Review comments are addressed

submiting patch for  integration tests for meter changes and modifications in unit test for updated flow decomposer logic
  - submitting on behalf of "Salman.Siddiqui@radisys.com"

Load test for meter updated and other flow management test cases with meter
- Performed load test for 1K meters serially and parallely and added more TC in flow management

Rebased

Load test for meter updated and other flow management test cases with meter
- Performed load test for 1K meters serially and parallely and added more TC in flow management
- submitting on behalf of "Salman.Siddiqui@radisys.com"

pulled latest protos

verified EAPOL/DHCP/HSIA data with Edgecore OLT & TW ONT kit for one subcriber
verified delete/re-add is working end to end for the same subscriber

Change-Id: Idb232b7a0f05dc0c7e68266ac885740a3adff317
diff --git a/python/ofagent/of_protocol_handler.py b/python/ofagent/of_protocol_handler.py
index 604ce3c..e90ca5b 100755
--- a/python/ofagent/of_protocol_handler.py
+++ b/python/ofagent/of_protocol_handler.py
@@ -29,6 +29,10 @@
 
     ofp_version = [4]  # OFAgent supported versions
 
+    MAX_METER_IDS = 4294967295
+    MAX_METER_BANDS = 255
+    MAX_METER_COLORS = 255
+
     def __init__(self, datapath_id, device_id, agent, cxn, rpc):
         """
         The upper half of the OpenFlow protocol, focusing on message
@@ -128,6 +132,30 @@
         elif self.role == ofp.OFPCR_ROLE_SLAVE:
            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
 
+
+    def handle_meter_mod_request(self, req):
+        log.info('Received  handle_meter_mod_request', request=req)
+        if self.role == ofp.OFPCR_ROLE_MASTER or self.role == ofp.OFPCR_ROLE_EQUAL:
+            try:
+                grpc_req = to_grpc(req)
+            except Exception, e:
+                log.exception('failed-to-convert-meter-mod-request', e=e)
+            else:
+                return self.rpc.update_meter_mod_table(self.device_id, grpc_req)
+
+        elif self.role == ofp.OFPCR_ROLE_SLAVE:
+            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
+
+    @inlineCallbacks
+    def handle_meter_stats_request(self, req):
+        log.info('Received  handle_meter_stats_request', request=req)
+        try:
+            meters = yield self.rpc.list_meters(self.device_id)
+            self.cxn.send(ofp.message.meter_stats_reply(
+                xid=req.xid, entries=[to_loxi(m.stats) for m in meters]))
+        except Exception, e:
+            log.exception("failed-meter-stats-request", req=req, e=e)
+
     def handle_get_async_request(self, req):
         raise NotImplementedError()
 
@@ -144,10 +172,6 @@
         elif self.role == ofp.OFPCR_ROLE_SLAVE:
            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
 
-
-    def handle_meter_mod_request(self, req):
-        raise NotImplementedError()
-
     def handle_role_request(self, req):
         if req.role == ofp.OFPCR_ROLE_MASTER or req.role == ofp.OFPCR_ROLE_SLAVE:
             if self.agent.generation_is_defined and (
@@ -238,16 +262,17 @@
     def handle_group_features_request(self, req):
         raise NotImplementedError()
 
-    def handle_meter_stats_request(self, req):
-        meter_stats = []  # see https://jira.opencord.org/browse/CORD-825
-        self.cxn.send(ofp.message.meter_stats_reply(
-            xid=req.xid, entries=meter_stats))
-
     def handle_meter_config_request(self, req):
         raise NotImplementedError()
 
     def handle_meter_features_request(self, req):
-        self.cxn.send(ofp.message.bad_request_error_msg())
+        feature = ofp.meter_features(max_meter=OpenFlowProtocolHandler.MAX_METER_IDS,
+                                     band_types=ofp.OFPMBT_DROP,
+                                     capabilities=ofp.OFPMF_KBPS,
+                                     max_bands=OpenFlowProtocolHandler.MAX_METER_BANDS,
+                                     max_color=OpenFlowProtocolHandler.MAX_METER_COLORS)
+        self.cxn.send(ofp.message.meter_features_stats_reply(xid=req.xid, flags=None,
+                                                             features=feature))
 
     @inlineCallbacks
     def handle_port_stats_request(self, req):