
#New libraries added by Huawei start.
from neutron.callbacks import registry
from neutron.callbacks import resources
#New libraries added by Huawei end.



class RpcCallbacks(type_tunnel.TunnelRpcCallbackMixin):

    def __init__(self, notifier, type_manager):
        self.setup_tunnel_callback_mixin(notifier, type_manager)
        super(RpcCallbacks, self).__init__()

    # A new  method added by Huawei starts.
    # used to notify Controller that vm is migrating
    # and get the segment id from Controller
    def get_dynamic_segment(self, plugin, port_context, host):
        segment_dict = {}
        self._set_segment(plugin, port_context, host, segment_dict)
        return segment_dict.get('segment')
    # A new method added by Huawei ends.
	
    # A new  method added by Huawei starts.
    # send the event of port_migration to huawei plugin,
    # notify Controller vm is migrating
    @staticmethod
    def _set_segment(plugin, port_context, host, segment_dict):
        # REVISIT(rawlin): add BridgeName as a nullable column to the Port
        # model and simply check here if it's set and insert it into the
        # vif_details.

        def set_segment_inner(segment):
            segment_dict['segment'] = segment

        port_migration_event = 'port_migration'
        registry.notify(
            resources.PORT, port_migration_event,
            set_segment_inner, plugin=plugin, port_context=port_context,
            host=host)
    # A new method added by Huawei ends.

    def _get_device_details(self, rpc_context, agent_id, host, device,
                            port_context):
        segment = port_context.bottom_bound_segment
        port = port_context.current
        plugin = directory.get_plugin()
        port_id = port_context.current['id']

        #New codes added by Huawei start.
        # modify segment = port_context.bottom_bound_segment
        # When vm is migrating, need to notify Controller and
        # get the segment id from Controller
        segment = None
        if host and host != port_context.host:
            try:
                segment = self.get_dynamic_segment(plugin, port_context, host)
            except Exception:
                LOG.error(_LE("Failed to get dynamic segment for device %s"),
                          device)
        if not segment:
            segment = port_context.bottom_bound_segment
        #New codes added by Huawei end.

        if not segment:
            LOG.warning(_LW("Device %(device)s requested by agent "
                            "%(agent_id)s on network %(network_id)s not "
                            "bound, vif_type: %(vif_type)s"),
                        {'device': device,
                         'agent_id': agent_id,
                         'network_id': port['network_id'],
                         'vif_type': port_context.vif_type})
            return {'device': device}

        if (not host or host == port_context.host):
            new_status = (n_const.PORT_STATUS_BUILD if port['admin_state_up']
                          else n_const.PORT_STATUS_DOWN)
            if port['status'] != new_status:
                plugin.update_port_status(rpc_context,
                                          port_id,
                                          new_status,
                                          host,
                                          port_context.network.current)

        network_qos_policy_id = port_context.network._network.get(
            qos_consts.QOS_POLICY_ID)
        entry = {'device': device,
                 'network_id': port['network_id'],
                 'port_id': port['id'],
                 'mac_address': port['mac_address'],
                 'admin_state_up': port['admin_state_up'],
                 'network_type': segment[api.NETWORK_TYPE],
                 'segmentation_id': segment[api.SEGMENTATION_ID],
                 'physical_network': segment[api.PHYSICAL_NETWORK],
                 'mtu': port_context.network._network.get('mtu'),
                 'fixed_ips': port['fixed_ips'],
                 'device_owner': port['device_owner'],
                 'allowed_address_pairs': port['allowed_address_pairs'],
                 'port_security_enabled': port.get(psec.PORTSECURITY, True),
                 'qos_policy_id': port.get(qos_consts.QOS_POLICY_ID),
                 'network_qos_policy_id': network_qos_policy_id,
                 'profile': port[portbindings.PROFILE]}
        LOG.debug("Returning: %s", entry)
        return entry
