
#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, **kwargs):
        """Agent requests device details."""

        if not port_context:
            LOG.warning(_LW("Device %(device)s requested by agent "
                            "%(agent_id)s not found in database"),
                        {'device': device, 'agent_id': agent_id})
            return {'device': device}

        #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. 

        port = port_context.current
        # caching information about networks for future use
        if cached_networks is not None:
            if port['network_id'] not in cached_networks:
                cached_networks[port['network_id']] = (
                    port_context.network.current)

        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}

        return entry

