VOL-172: Support configuration of  traffic descriptor profile for upstream BW allocation to ONU

 * As an operator, I should be able to configure traffic descriptor profiles for upstream BW configuration.
 * As an operator, I should be able to retrieve the configured traffic descriptor profiles.

Additional Notes:
 * xPON Handler and xPON Agent should be able to handle the traffic descriptor configuration.
 * This story does not have impact on adapters until the traffic descriptor is referenced by a TCONT
 * The traffic descriptor profiles should be saved to the database(in memory until config/restore feature is ready).
 * The impact to HA-proxy for load-balancing & distributing of workload is still TBD. As of now, it can be assumed that profiles are available to all VOLTHA instances.

VOL-173: Support configuration of TCONTs as per WT-385 and auto-allocation of alloc-ids

 * As an operator, I should be able to provision a TCONT for the ONU with an existing traffic descriptor profile
 * As an operator, I should be able to retrieve the provisioned TCONT
 * As an operator, I should be able to change the traffic descriptor profile for a TCONT

Additional Notes:

 * alloc-ids should be allocated for the TCONT
 * generic IAdapter interface to be provided that will be used by OLT and ONU adapters for TCONT/alloc-id/BW configuration
 * In the best interest of schedules/timing, in the first step(e.g. POC-3 & trial), assume the queueing model to be supported (to be detailed)  (i.e. no configuration of queueing model)
 * The concerned ONU should receive upstream grants upon provisioning of  TCONT for the ONU

VOL-174: Support configuration of GEMs as per WT-385 and auto-allocation of gemport-ids

 * As an operator, I should be able to provision a GEMPORT object for the ONU and assign to a UNI
 * As an operator, I should be able to retrieve the provisioned GEMPORT

Additional Notes:

 * gemport-ids should be auto-allocated for the GEMPORT object
 * generic IAdapter interface to be provided that will be used by OLT and ONU adapters for GEM port configuration
 * In the best interest of schedules/timing, in the first step(e.g. POC-3 & trial), assume the queueing model to be supported (to be detailed) (i.e. no configuration of queueing model)
 * The concerned OLT and ONU should be configured with the allocated gemport-ids

Change-Id: I7d798dca392826d067cadb3f5eff641470e38d85
diff --git a/voltha/core/xpon_agent.py b/voltha/core/xpon_agent.py
index 2dce5ea..70e2bc0 100644
--- a/voltha/core/xpon_agent.py
+++ b/voltha/core/xpon_agent.py
@@ -508,6 +508,17 @@
                     'xpon-agent-creating-ont-ani-at-onu-device:',
                     onu_device_id=onu_device.id, ont_ani=ont_ani)
                 self.create_interface_in_device(onu_device, ont_ani)
+            tconts = self.core.get_proxy('/').get('/tconts')
+            for tcont in tconts:
+                if self.get_parent_data(tcont).name == data.name:
+                    log.info(
+                        'xpon-agent-creating-tcont-at-olt-device:',
+                        olt_device_id=olt_device.id, tcont=tcont)
+                    self.create_interface_in_device(olt_device, tcont)
+                    log.info(
+                        'xpon-agent-creating-tcont-at-onu-device:',
+                        onu_device_id=onu_device.id, tcont=tcont)
+                    self.create_interface_in_device(onu_device, tcont)
             v_enets = self.core.get_proxy('/').get('/v_enets')
             for v_enet in v_enets:
                 if self.get_parent_data(v_enet).name == data.name:
@@ -519,11 +530,19 @@
                         'xpon-agent-creating-v-enet-at-onu-device:',
                         onu_device_id=onu_device.id, v_enet=v_enet)
                     self.create_interface_in_device(onu_device, v_enet)
-            '''
-            @TODO: Add creation of Traffic Descriptor Profile, TCont, and
-                   Gemport. Creation of all interfaces must be remodeled
-                   utilizing interface stack's parent-child relationship.
-            '''
+                    gemports = self.core.get_proxy('/').get('/gemports')
+                    for gemport in gemports:
+                        if self.get_parent_data(gemport).name == v_enet.name:
+                            log.info(
+                                'xpon-agent-creating-gemport-at-olt-device:',
+                                olt_device_id=olt_device.id, gemport=gemport)
+                            self.create_interface_in_device(olt_device,
+                                                            gemport)
+                            log.info(
+                                'xpon-agent-creating-gemport-at-onu-device:',
+                                onu_device_id=onu_device.id, gemport=gemport)
+                            self.create_interface_in_device(onu_device,
+                                                            gemport)
         except KeyError:
             log.info(
                 'xpon-agent-create-onu-interfaces-no-ont-ani-link-exists')
@@ -543,19 +562,20 @@
         self.remove_interface_in_device(olt_device, data)
         log.info(
             'xpon-agent-removing-channel-pair:',
-            olt_device_id=olt_device.id, data=channel_pair)
+            olt_device_id=olt_device.id, channel_pair=channel_pair)
         self.remove_interface_in_device(olt_device, channel_pair)
         channel_partition = self.get_parent_data(channel_pair)
         if channel_partition is not None:
             log.info(
                 'xpon-agent-removing-channel-partition:',
-                olt_device_id=olt_device.id, data=channel_partition)
+                olt_device_id=olt_device.id,
+                channel_partition=channel_partition)
             self.remove_interface_in_device(olt_device, channel_partition)
         channel_group = self.get_parent_data(channel_partition)
         if channel_group is not None:
             log.info(
                 'xpon-agent-removing-channel-group:',
-                olt_device_id=olt_device.id, data=channel_group)
+                olt_device_id=olt_device.id, channel_group=channel_group)
             self.remove_interface_in_device(olt_device, channel_group)
 
     def remove_onu_interfaces(self, olt_device, data):
@@ -563,14 +583,25 @@
         for v_ont_ani in v_ont_anis:
             if self.get_link_data(v_ont_ani, 'olt').name == data.name:
                 onu_device = self.get_device(v_ont_ani, 'onu')
-                '''
-                @TODO: Add remove of Traffic Descriptor Profile, TCont, and
-                       Gemport. Remove of all interfaces must be remodeled
-                       utilizing interface stack's parent-child relationship.
-                '''
                 v_enets = self.core.get_proxy('/').get('/v_enets')
                 for v_enet in v_enets:
                     if self.get_parent_data(v_enet).name == v_ont_ani.name:
+                        gemports = self.core.get_proxy('/').get('/gemports')
+                        for gemport in gemports:
+                            if self.get_parent_data(gemport).name == \
+                                v_enet.name:
+                                log.info(
+                                    'xpon-agent-remove-gemport-at-onu-device:',
+                                    onu_device_id=onu_device.id,
+                                    gemport=gemport)
+                                self.remove_interface_in_device(onu_device,
+                                                                gemport)
+                                log.info(
+                                    'xpon-agent-remove-gemport-at-olt-device:',
+                                    olt_device_id=olt_device.id,
+                                    gemport=gemport)
+                                self.remove_interface_in_device(olt_device,
+                                                                gemport)
                         log.info(
                             'xpon-agent-removing-v-enet-at-onu-device:',
                             onu_device_id=onu_device.id, data=v_enet)
@@ -579,6 +610,17 @@
                             'xpon-agent-removing-v-enet-at-olt-device:',
                             olt_device_id=olt_device.id, data=v_enet)
                         self.remove_interface_in_device(olt_device, v_enet)
+                tconts = self.core.get_proxy('/').get('/tconts')
+                for tcont in tconts:
+                    if self.get_parent_data(tcont).name == v_ont_ani.name:
+                        log.info(
+                            'xpon-agent-removing-tcont-at-onu-device:',
+                            onu_device_id=onu_device.id, tcont=tcont)
+                        self.remove_interface_in_device(onu_device, tcont)
+                        log.info(
+                            'xpon-agent-removing-tcont-at-olt-device:',
+                            olt_device_id=olt_device.id, tcont=tcont)
+                        self.remove_interface_in_device(olt_device, tcont)
                 try:
                     ont_ani = self.core.get_proxy('/').get(
                         '/ont_anis/{}'.format(v_ont_ani.name))
diff --git a/voltha/core/xpon_handler.py b/voltha/core/xpon_handler.py
index 674b888..18b6062 100644
--- a/voltha/core/xpon_handler.py
+++ b/voltha/core/xpon_handler.py
@@ -116,8 +116,6 @@
             assert isinstance(request, ChannelgroupConfig)
             assert self.validate_interface(request, context)
             channelgroup = self.get_channel_group_config(request, context)
-            assert channelgroup.name == request.name
-
             request.cg_index = channelgroup.cg_index
             path = '/channel_groups/{}'.format(request.name)
             log.debug('updating-channel-group', name=request.name)
@@ -158,9 +156,6 @@
                 'Channel Group -- \'{}\' is referenced by Channel Pair'\
                 .format(request.name)
             channelgroup = self.get_channel_group_config(request, context)
-            assert channelgroup.name == request.name, \
-                'Unable to find specified Channel Group -- \'{}\''\
-                .format(request.name)
             path = '/channel_groups/{}'.format(request.name)
             log.debug('removing-channel-group', name=request.name)
             self.root.remove(path)