<commit_before># Copyright (c) 2014 OpenStack Foundation.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from keystoneauth1 import loading as ks_loading
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants
from neutron_lib import context
from neutron_lib import exceptions as exc
from neutron_lib.plugins import directory
from novaclient import api_versions
from novaclient import client as nova_client
from novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
from sqlalchemy.orm import attributes as sql_attr

from neutron._i18n import _LE, _LI, _LW
from neutron.notifiers import batch_notifier


LOG = logging.getLogger(__name__)

VIF_UNPLUGGED = 'network-vif-unplugged'
VIF_PLUGGED = 'network-vif-plugged'
VIF_DELETED = 'network-vif-deleted'
NEUTRON_NOVA_EVENT_STATUS_MAP = {constants.PORT_STATUS_ACTIVE: 'completed',
                                 constants.PORT_STATUS_ERROR: 'failed',
                                 constants.PORT_STATUS_DOWN: 'completed'}
NOVA_API_VERSION = "2.1"


@registry.has_registry_receivers
class Notifier(object):

    _instance = None

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    def __init__(self):
        auth = ks_loading.load_auth_from_conf_options(cfg.CONF, 'nova')

        session = ks_loading.load_session_from_conf_options(
            cfg.CONF,
            'nova',
            auth=auth)

        extensions = [
            ext for ext in nova_client.discover_extensions(NOVA_API_VERSION,
                                                           only_contrib=True)
            if ext.name == "server_external_events"]
        self.nclient = nova_client.Client(
            api_versions.APIVersion(NOVA_API_VERSION),
            session=session,
            region_name=cfg.CONF.nova.region_name,
            endpoint_type=cfg.CONF.nova.endpoint_type,
            extensions=extensions)
        self.batch_notifier = batch_notifier.BatchNotifier(
            cfg.CONF.send_events_interval, self.send_events)

    def _is_compute_port(self, port):
        try:
            if (port['device_id'] and uuidutils.is_uuid_like(port['device_id'])
                    and port['device_owner'].startswith(
                        constants.DEVICE_OWNER_COMPUTE_PREFIX)):
                return True
        except (KeyError, AttributeError):
            pass
        return False

    def _get_network_changed_event(self, device_id):
        return {'name': 'network-changed',
                'server_uuid': device_id}

    def _get_port_delete_event(self, port):
        return {'server_uuid': port['device_id'],
                'name': VIF_DELETED,
                'tag': port['id']}

    @registry.receives(resources.PORT, events.BEFORE_RESPONSE)
    @registry.receives(resources.FLOATING_IP, events.BEFORE_RESPONSE)
    def _send_nova_notification(self, resource, event, trigger,
                                action=None, original=None, data=None,
                                **kwargs):
        self.send_network_change(action, original, data)

    def send_network_change(self, action, original_obj,
                            returned_obj):
        """Called when a network change is made that nova cares about.
<commit_msg>Fix usage of registry.receives in Nova notifier<commit_after># Copyright (c) 2014 OpenStack Foundation.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from keystoneauth1 import loading as ks_loading
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants
from neutron_lib import context
from neutron_lib import exceptions as exc
from neutron_lib.plugins import directory
from novaclient import api_versions
from novaclient import client as nova_client
from novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
from sqlalchemy.orm import attributes as sql_attr

from neutron._i18n import _LE, _LI, _LW
from neutron.notifiers import batch_notifier


LOG = logging.getLogger(__name__)

VIF_UNPLUGGED = 'network-vif-unplugged'
VIF_PLUGGED = 'network-vif-plugged'
VIF_DELETED = 'network-vif-deleted'
NEUTRON_NOVA_EVENT_STATUS_MAP = {constants.PORT_STATUS_ACTIVE: 'completed',
                                 constants.PORT_STATUS_ERROR: 'failed',
                                 constants.PORT_STATUS_DOWN: 'completed'}
NOVA_API_VERSION = "2.1"


@registry.has_registry_receivers
class Notifier(object):

    _instance = None

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    def __init__(self):
        auth = ks_loading.load_auth_from_conf_options(cfg.CONF, 'nova')

        session = ks_loading.load_session_from_conf_options(
            cfg.CONF,
            'nova',
            auth=auth)

        extensions = [
            ext for ext in nova_client.discover_extensions(NOVA_API_VERSION,
                                                           only_contrib=True)
            if ext.name == "server_external_events"]
        self.nclient = nova_client.Client(
            api_versions.APIVersion(NOVA_API_VERSION),
            session=session,
            region_name=cfg.CONF.nova.region_name,
            endpoint_type=cfg.CONF.nova.endpoint_type,
            extensions=extensions)
        self.batch_notifier = batch_notifier.BatchNotifier(
            cfg.CONF.send_events_interval, self.send_events)

    def _is_compute_port(self, port):
        try:
            if (port['device_id'] and uuidutils.is_uuid_like(port['device_id'])
                    and port['device_owner'].startswith(
                        constants.DEVICE_OWNER_COMPUTE_PREFIX)):
                return True
        except (KeyError, AttributeError):
            pass
        return False

    def _get_network_changed_event(self, device_id):
        return {'name': 'network-changed',
                'server_uuid': device_id}

    def _get_port_delete_event(self, port):
        return {'server_uuid': port['device_id'],
                'name': VIF_DELETED,
                'tag': port['id']}

    @registry.receives(resources.PORT, [events.BEFORE_RESPONSE])
    @registry.receives(resources.FLOATING_IP, [events.BEFORE_RESPONSE])
    def _send_nova_notification(self, resource, event, trigger,
                                action=None, original=None, data=None,
                                **kwargs):
        self.send_network_change(action, original, data)

    def send_network_change(self, action, original_obj,
                            returned_obj):
        """Called when a network change is made that nova cares about.

{'fraction_non_alphanumeric': 0.07266222551196644, 'fraction_numerical': 0.0032075006168270415, 'mean_word_length': 2.685, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4763829', 'n_tokens_mistral': 2296, 'n_tokens_neox': 2247, 'n_words': 610}