<commit_before>#    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 oslo_log import log as logging
import oslo_messaging as messaging

from gbpservice.nfp.core.main import Event
from gbpservice.nfp.core.rpc import RpcAgent
from gbpservice.nfp.common import topics as nsf_topics
from gbpservice.nfp.db import nfp_db as nfp_db
from gbpservice.nfp.db import api as nfp_db_api
from gbpservice.nfp.lib import extension_manager as ext_mgr
from gbpservice.nfp.lifecycle_manager.openstack import openstack_driver
#from gbpservice.nfp.lifecycle_manager.compute.drivers import (
#    nova_driver)
'''from gbpservice.nfp.lifecycle_manager.drivers import (
    haproxy_lifecycle_driver)
from gbpservice.nfp.lifecycle_manager.drivers import (
    vyos_lifecycle_driver)
'''
from neutron.common import rpc as n_rpc
from neutron import context as n_context

LOG = logging.getLogger(__name__)


def rpc_init(controller, config):
    rpcmgr = RpcHandler(config, controller)
    agent = RpcAgent(
        controller,
        host=config.host,
        topic=nsf_topics.NFP_CONFIGURATOR_DLCM_TOPIC,
        manager=rpcmgr)
    controller.register_rpc_agents([agent])


def events_init(controller, config):
    device_lifecycle_mgr_obj = DeviceLifeCycleManager(controller, config)
    evs = [
        Event(id='CREATE_NETWORK_FUNCTION_DEVICE',
              handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_SPAWNING', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_UP', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_HEALTHY', handler=device_lifecycle_mgr_obj),
        Event(id='CONFIGURE_DEVICE', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_CONFIGURED', handler=device_lifecycle_mgr_obj),

        Event(id='DELETE_NETWORK_FUNCTION_DEVICE',
              handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_CONFIGURATION', handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_CONFIGURATION_COMPLETED',
              handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_DEVICE', handler=device_lifecycle_mgr_obj),

        Event(id='DEVICE_NOT_UP', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_NOT_REACHABLE', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_CONFIGURATION_FAILED',
              handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_ERROR', handler=device_lifecycle_mgr_obj),
        ]
    controller.register_events(evs)


def module_init(controller, config):
    events_init(controller, config)
    rpc_init(controller, config)
    LOG.info(_("DLCM: module_init"))


class RpcHandler(object):
    RPC_API_VERSION = '1.0'

    def __init__(self, conf, controller):
        super(RpcHandler, self).__init__()
        self.conf = conf
        self._controller = controller
        self.rpc_event_mapping = {'healthmonitor': ['DEVICE_HEALTHY',
                                                   'DEVICE_NOT_REACHABLE'],
                                  'interfaces':    ['DEVICE_CONFIGURED',
                                                   'DEVICE_CONFIGURED_FAILED'],
                                  'routes':        ['DEVICE_CONFIGURED',
                                                   'DEVICE_CONFIGURED_FAILED'],
                                  }

    # RPC APIs status notification from Configurator
    def network_function_device_notification(self, context, notification_data):
        #context = kwargs.get('context')
        #notification_data = kwargs.get('notification_data')
        responses = notification_data.get('kwargs')

        for response in responses:
            resource = response.get('resource')
            request_info = response.get('request_info')
            result = response.get('result')

            if resource == 'healthmonitor':
                LOG.info(_("healthmonitor not implemented yet, so ignoring for now."))
                return None

            event_id = self.rpc_event_mapping[resource][0]
            if result != 'success':
                event_id = self.rpc_event_mapping[resource][1]
                break

        event_data = request_info
        self._create_event(event_id=event_id,
                           event_data=event_data)


class DeviceLifeCycleManager(object):
    def __init__(self, controller, config):
        self._controller = controller
        self.config = config

    def event_method_mapping(self, state, device_lifecycle_handler):
        state_machine = {
            "CREATE_NETWORK_FUNCTION_DEVICE": (
                device_lifecycle_handler.create_network_function_device),
            "DEVICE_SPAWNING": device_lifecycle_handler.check_device_is_up,
            #"DEVICE_UP": device_lifecycle_handler.perform_health_check,
            #"DEVICE_HEALTHY": (
            #            device_lifecycle_handler.plug_interfaces),
            "DEVICE_UP": device_lifecycle_handler.plug_interfaces,
            "CONFIGURE_DEVICE": (
                        device_lifecycle_handler.create_device_configuration),
            "DEVICE_CONFIGURED": (<commit_msg>Bug fixes while integration in DLCM<commit_after>#    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 oslo_log import log as logging
import oslo_messaging as messaging

from gbpservice.nfp.core.main import Event
from gbpservice.nfp.core.rpc import RpcAgent
from gbpservice.nfp.common import topics as nsf_topics
from gbpservice.nfp.db import nfp_db as nfp_db
from gbpservice.nfp.db import api as nfp_db_api
from gbpservice.nfp.lib import extension_manager as ext_mgr
from gbpservice.nfp.lifecycle_manager.openstack import openstack_driver
#from gbpservice.nfp.lifecycle_manager.compute.drivers import (
#    nova_driver)
'''from gbpservice.nfp.lifecycle_manager.drivers import (
    haproxy_lifecycle_driver)
from gbpservice.nfp.lifecycle_manager.drivers import (
    vyos_lifecycle_driver)
'''
from neutron.common import rpc as n_rpc
from neutron import context as n_context

LOG = logging.getLogger(__name__)


def rpc_init(controller, config):
    rpcmgr = RpcHandler(config, controller)
    agent = RpcAgent(
        controller,
        host=config.host,
        topic=nsf_topics.NFP_CONFIGURATOR_DLCM_TOPIC,
        manager=rpcmgr)
    controller.register_rpc_agents([agent])


def events_init(controller, config):
    device_lifecycle_mgr_obj = DeviceLifeCycleManager(controller, config)
    evs = [
        Event(id='CREATE_NETWORK_FUNCTION_DEVICE',
              handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_SPAWNING', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_UP', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_HEALTHY', handler=device_lifecycle_mgr_obj),
        Event(id='CONFIGURE_DEVICE', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_CONFIGURED', handler=device_lifecycle_mgr_obj),

        Event(id='DELETE_NETWORK_FUNCTION_DEVICE',
              handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_CONFIGURATION', handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_CONFIGURATION_COMPLETED',
              handler=device_lifecycle_mgr_obj),
        Event(id='DELETE_DEVICE', handler=device_lifecycle_mgr_obj),

        Event(id='DEVICE_NOT_UP', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_NOT_REACHABLE', handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_CONFIGURATION_FAILED',
              handler=device_lifecycle_mgr_obj),
        Event(id='DEVICE_ERROR', handler=device_lifecycle_mgr_obj),
        ]
    controller.register_events(evs)


def module_init(controller, config):
    events_init(controller, config)
    rpc_init(controller, config)
    LOG.info(_("DLCM: module_init"))


class RpcHandler(object):
    RPC_API_VERSION = '1.0'

    def __init__(self, conf, controller):
        super(RpcHandler, self).__init__()
        self.conf = conf
        self._controller = controller
        self.rpc_event_mapping = {'healthmonitor': ['DEVICE_HEALTHY',
                                                   'DEVICE_NOT_REACHABLE'],
                                  'interfaces':    ['DEVICE_CONFIGURED',
                                                   'DEVICE_CONFIGURATION_FAILED'],
                                  'routes':        ['DEVICE_CONFIGURED',
                                                   'DEVICE_CONFIGURATION_FAILED'],
                                  }

    def _log_event_created(self, event_id, event_data):
        LOG.info(_("Created event %s(event_name)s with event "
                    "data: %(event_data)s"),
                  {'event_name': event_id, 'event_data': event_data})

    def _create_event(self, event_id, event_data=None,
                      is_poll_event=False, original_event=False):
        if is_poll_event:
            ev = self._controller.new_event(
                id=event_id, data=event_data,
                serialize=original_event.serialize,
                binding_key=original_event.binding_key,
                key=original_event.key)
            LOG.debug(_("_create_event - poll event %s" % ev.id))
            self._controller.poll_event(ev, max_times=10)
        else:
            ev = self._controller.new_event(id=event_id, data=event_data)
            self._controller.post_event(ev)
        self._log_event_created(event_id, event_data)

    # RPC APIs status notification from Configurator
    def network_function_device_notification(self, context, notification_data):
        #context = kwargs.get('context')
        #notification_data = kwargs.get('notification_data')
        responses = notification_data.get('kwargs')

        for response in responses:
            resource = response.get('resource')
            request_info = response.get('request_info')
            result = response.get('result')

            if resource == 'healthmonitor':
                LOG.info(_("healthmonitor not implemented yet, so ignoring for now."))
                return None

            event_id = self.rpc_event_mapping[resource][0]
            if result.lower() != 'success':
                event_id = self.rpc_event_mapping[resource][1]
                break

        event_data = request_info
        self._create_event(event_id=event_id,
                           event_data=event_data)


class DeviceLifeCycleManager(object):
    def __init__(self, controller, config):
        self._controller = controller
        self.config = config

    def event_method_mapping(self, state, device_lifecycle_handler):
        state_machine = {
            "CREATE_NETWORK_FUNCTION_DEVICE": (
                device_lifecycle_handler.create_network_function_device),
            "DEVICE_SPAWNING": device_lifecycle_handler.check_device_is_up,
            #"DEVICE_UP": device_lifecycle_handler.perform_health_check,
            #"DEVICE_HEALTHY": (
            #            device_lifecycle_handler.plug_interfaces),
            "DEVICE_UP": device_lifecycle_handler.plug_interfaces,
            "CONFIGURE_DEVICE": (
                        device_lifecycle_handler.create_device_configuration),
            "DEVICE_CONFIGURED": (
{'fraction_non_alphanumeric': 0.08314087759815242, 'fraction_numerical': 0.0014846585285384361, 'mean_word_length': 2.8128930817610063, 'pattern_counts': {'":': 14, '<': 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': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '258827', 'n_tokens_mistral': 3434, 'n_tokens_neox': 3394, 'n_words': 673}