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

import abc

from oslo_config import cfg
from oslo_utils import timeutils

from neutron._i18n import _
from neutron.common.ovn import constants as ovn_const
from neutron.common.ovn import utils as ovn_utils
from neutron.common import utils


class NeutronAgent(abc.ABC):
    types = {}

    def __init_subclass__(cls):
        # Register the subclasses to be looked up by their type
        NeutronAgent.types[cls.agent_type] = cls

    def __init__(self, chassis_private, driver, updated_at=None):
        self.driver = driver
        self.set_down = False
        self.update(chassis_private, updated_at)

    def update(self, chassis_private, updated_at=None, clear_down=False):
        self.chassis_private = chassis_private
        self.updated_at = updated_at or timeutils.utcnow(with_timezone=True)
        if clear_down:
            self.set_down = False

    @property
    def chassis(self):
        try:
            return self.chassis_private.chassis[0]
        except (AttributeError, IndexError):
            # No Chassis_Private support, just use Chassis
            return self.chassis_private

    def as_dict(self):
        return {
            'binary': self.binary,
            'host': self.chassis.hostname,
            'heartbeat_timestamp': timeutils.utcnow(),
            'availability_zone': ', '.join(
                ovn_utils.get_chassis_availability_zones(self.chassis)),
            'topic': 'n/a',
            'description': self.description,
            'configurations': {
                'chassis_name': self.chassis.name,
                'bridge-mappings':
                    self.chassis.external_ids.get('ovn-bridge-mappings', '')},
            'start_flag': True,
            'agent_type': self.agent_type,
            'id': self.agent_id,
            'alive': self.alive,
            'admin_state_up': True}

    @property
    def alive(self):
        if self.set_down:
            return False
        # TODO(twilson) Determine if we can go back to just checking:
        # if self.driver._nb_ovn.nb_global.nb_cfg == self.nb_cfg:
        if self.driver._nb_ovn.nb_global.nb_cfg - self.nb_cfg <= 1:
            return True
        now = timeutils.utcnow(with_timezone=True)
        if (now - self.updated_at).total_seconds() < cfg.CONF.agent_down_time:
            # down, but not yet timed out
            return True
        return False

    @classmethod
    def from_type(cls, _type, chassis_private, driver, updated_at=None):
        return cls.types[_type](chassis_private, driver, updated_at)

    @property
    @abc.abstractmethod
    def agent_type(self):
        pass

    @property
    @abc.abstractmethod
    def binary(self):
        pass

    @property
    @abc.abstractmethod
    def nb_cfg(self):
        pass

    @property
    @abc.abstractmethod
    def agent_id(self):
        pass


class ControllerAgent(NeutronAgent):
    agent_type = ovn_const.OVN_CONTROLLER_AGENT
    binary = 'ovn-controller'

    @staticmethod  # it is by default, but this makes pep8 happy
    def __new__(cls, chassis_private, driver, updated_at=None):
        if ('enable-chassis-as-gw' in
                chassis_private.external_ids.get('ovn-cms-options', [])):
            cls = ControllerGatewayAgent
        return super().__new__(cls)

    @staticmethod
    def id_from_chassis_private(chassis_private):
        return chassis_private.name

    @property
    def nb_cfg(self):
        return self.chassis_private.nb_cfg

    @property
    def agent_id(self):
        return self.id_from_chassis_private(self.chassis_private)

    @property
    def description(self):
        return self.chassis_private.external_ids.get(
            ovn_const.OVN_AGENT_DESC_KEY, '')
<commit_msg>[OVN] "ControllerAgent" should accept Chassis and Chassis_Private<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.
#

import abc

from oslo_config import cfg
from oslo_utils import timeutils

from neutron._i18n import _
from neutron.common.ovn import constants as ovn_const
from neutron.common.ovn import utils as ovn_utils
from neutron.common import utils


class NeutronAgent(abc.ABC):
    types = {}

    def __init_subclass__(cls):
        # Register the subclasses to be looked up by their type
        NeutronAgent.types[cls.agent_type] = cls

    def __init__(self, chassis_private, driver, updated_at=None):
        self.driver = driver
        self.set_down = False
        self.update(chassis_private, updated_at)

    def update(self, chassis_private, updated_at=None, clear_down=False):
        self.chassis_private = chassis_private
        self.updated_at = updated_at or timeutils.utcnow(with_timezone=True)
        if clear_down:
            self.set_down = False

    @staticmethod
    def chassis_from_private(chassis_private):
        try:
            return chassis_private.chassis[0]
        except (AttributeError, IndexError):
            # No Chassis_Private support, just use Chassis
            return chassis_private

    @property
    def chassis(self):
        return self.chassis_from_private(self.chassis_private)

    def as_dict(self):
        return {
            'binary': self.binary,
            'host': self.chassis.hostname,
            'heartbeat_timestamp': timeutils.utcnow(),
            'availability_zone': ', '.join(
                ovn_utils.get_chassis_availability_zones(self.chassis)),
            'topic': 'n/a',
            'description': self.description,
            'configurations': {
                'chassis_name': self.chassis.name,
                'bridge-mappings':
                    self.chassis.external_ids.get('ovn-bridge-mappings', '')},
            'start_flag': True,
            'agent_type': self.agent_type,
            'id': self.agent_id,
            'alive': self.alive,
            'admin_state_up': True}

    @property
    def alive(self):
        if self.set_down:
            return False
        # TODO(twilson) Determine if we can go back to just checking:
        # if self.driver._nb_ovn.nb_global.nb_cfg == self.nb_cfg:
        if self.driver._nb_ovn.nb_global.nb_cfg - self.nb_cfg <= 1:
            return True
        now = timeutils.utcnow(with_timezone=True)
        if (now - self.updated_at).total_seconds() < cfg.CONF.agent_down_time:
            # down, but not yet timed out
            return True
        return False

    @classmethod
    def from_type(cls, _type, chassis_private, driver, updated_at=None):
        return cls.types[_type](chassis_private, driver, updated_at)

    @property
    @abc.abstractmethod
    def agent_type(self):
        pass

    @property
    @abc.abstractmethod
    def binary(self):
        pass

    @property
    @abc.abstractmethod
    def nb_cfg(self):
        pass

    @property
    @abc.abstractmethod
    def agent_id(self):
        pass


class ControllerAgent(NeutronAgent):
    agent_type = ovn_const.OVN_CONTROLLER_AGENT
    binary = 'ovn-controller'

    @staticmethod  # it is by default, but this makes pep8 happy
    def __new__(cls, chassis_private, driver, updated_at=None):
        external_ids = cls.chassis_from_private(chassis_private).external_ids
        if ('enable-chassis-as-gw' in
                external_ids.get('ovn-cms-options', [])):
            cls = ControllerGatewayAgent
        return super().__new__(cls)

    @staticmethod
    def id_from_chassis_private(chassis_private):
        return chassis_private.name

    @property
    def nb_cfg(self):
        return self.chassis_private.nb_cfg

    @property
    def agent_id(self):
        return self.id_from_chassis_private(self.chassis_private)

    @property
    def description(self):
        return self.chassis_private.external_ids.get(
            ovn_const.OVN_AGENT_DESC_KEY, '')

{'fraction_non_alphanumeric': 0.08580783561025178, 'fraction_numerical': 0.0020322908434007, 'mean_word_length': 2.5333067411248504, 'pattern_counts': {'":': 0, '<': 7, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '932074', 'n_tokens_mistral': 2733, 'n_tokens_neox': 2594, 'n_words': 657}