<commit_before># -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Authors: <NAME> <<EMAIL>>
#
# 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_config import cfg
from oslo_log import log

from watcher._i18n import _LW
from watcher.common import utils
from watcher.decision_engine.planner import base
from watcher import objects

LOG = log.getLogger(__name__)


class DefaultPlanner(base.BasePlanner):
    """Default planner implementation

    This implementation comes with basic rules with a set of action types that
    are weighted. An action having a lower weight will be scheduled before the
    other ones. The set of action types can be specified by 'weights' in the
    ``watcher.conf``. You need to associate a different weight to all available
    actions into the configuration file, otherwise you will get an error when
    the new action will be referenced in the solution produced by a strategy.
    """

    weights_dict = {
        'nop': 0,
        'sleep': 1,
        'change_nova_service_state': 2,
        'migrate': 3,
    }

    @classmethod
    def get_config_opts(cls):
        return [
            cfg.DictOpt(
                'weights',
                help="These weights are used to schedule the actions",
                default=cls.weights_dict),
        ]

    def create_action(self,
                      action_plan_id,
                      action_type,
                      input_parameters=None):
        uuid = utils.generate_uuid()
        action = {
            'uuid': uuid,
            'action_plan_id': int(action_plan_id),
            'action_type': action_type,
            'input_parameters': input_parameters,
            'state': objects.action.State.PENDING,
            'next': None,
        }

        return action

    def schedule(self, context, audit_id, solution):
        LOG.debug('Creating an action plan for the audit uuid: %s', audit_id)
        priorities = self.config.weights
        action_plan = self._create_action_plan(context, audit_id, solution)

        actions = list(solution.actions)
        to_schedule = []
        for action in actions:
            json_action = self.create_action(
                action_plan_id=action_plan.id,
                action_type=action.get('action_type'),
                input_parameters=action.get('input_parameters'))
            to_schedule.append((priorities[action.get('action_type')],
                                json_action))

        self._create_efficacy_indicators(
            context, action_plan.id, solution.efficacy_indicators)

        # scheduling
        scheduled = sorted(to_schedule, key=lambda x: (x[0]))
        if len(scheduled) == 0:
            LOG.warning(_LW("The action plan is empty"))
            action_plan.first_action_id = None
            action_plan.save()
        else:
            # create the first action
            parent_action = self._create_action(context,
                                                scheduled[0][1],
                                                None)
            # remove first
            scheduled.pop(0)

            action_plan.first_action_id = parent_action.id
            action_plan.save()

            for s_action in scheduled:
                current_action = self._create_action(context, s_action[1],
                                                     parent_action)
                parent_action = current_action

        return action_plan

    def _create_action_plan(self, context, audit_id, solution):
        strategy = objects.Strategy.get_by_name(<commit_msg>When action plan is empty, its state is incorrect<commit_after># -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Authors: <NAME> <<EMAIL>>
#
# 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_config import cfg
from oslo_log import log

from watcher._i18n import _LW
from watcher.common import utils
from watcher.decision_engine.planner import base
from watcher import objects

LOG = log.getLogger(__name__)


class DefaultPlanner(base.BasePlanner):
    """Default planner implementation

    This implementation comes with basic rules with a set of action types that
    are weighted. An action having a lower weight will be scheduled before the
    other ones. The set of action types can be specified by 'weights' in the
    ``watcher.conf``. You need to associate a different weight to all available
    actions into the configuration file, otherwise you will get an error when
    the new action will be referenced in the solution produced by a strategy.
    """

    weights_dict = {
        'nop': 0,
        'sleep': 1,
        'change_nova_service_state': 2,
        'migrate': 3,
    }

    @classmethod
    def get_config_opts(cls):
        return [
            cfg.DictOpt(
                'weights',
                help="These weights are used to schedule the actions",
                default=cls.weights_dict),
        ]

    def create_action(self,
                      action_plan_id,
                      action_type,
                      input_parameters=None):
        uuid = utils.generate_uuid()
        action = {
            'uuid': uuid,
            'action_plan_id': int(action_plan_id),
            'action_type': action_type,
            'input_parameters': input_parameters,
            'state': objects.action.State.PENDING,
            'next': None,
        }

        return action

    def schedule(self, context, audit_id, solution):
        LOG.debug('Creating an action plan for the audit uuid: %s', audit_id)
        priorities = self.config.weights
        action_plan = self._create_action_plan(context, audit_id, solution)

        actions = list(solution.actions)
        to_schedule = []
        for action in actions:
            json_action = self.create_action(
                action_plan_id=action_plan.id,
                action_type=action.get('action_type'),
                input_parameters=action.get('input_parameters'))
            to_schedule.append((priorities[action.get('action_type')],
                                json_action))

        self._create_efficacy_indicators(
            context, action_plan.id, solution.efficacy_indicators)

        # scheduling
        scheduled = sorted(to_schedule, key=lambda x: (x[0]))
        if len(scheduled) == 0:
            LOG.warning(_LW("The action plan is empty"))
            action_plan.first_action_id = None
            action_plan.state = objects.action_plan.State.SUCCEEDED
            action_plan.save()
        else:
            # create the first action
            parent_action = self._create_action(context,
                                                scheduled[0][1],
                                                None)
            # remove first
            scheduled.pop(0)

            action_plan.first_action_id = parent_action.id
            action_plan.save()

            for s_action in scheduled:
                current_action = self._create_action(context, s_action[1],
                                                     parent_action)
                parent_action = current_action

        return action_plan

    def _create_action_plan(self, context, audit_id, solution):
        strategy = objects.Strategy.get_by_name(
{'fraction_non_alphanumeric': 0.07725841608137564, 'fraction_numerical': 0.005085977234197142, 'mean_word_length': 2.111906556141673, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2390504', 'n_tokens_mistral': 2165, 'n_tokens_neox': 2081, 'n_words': 671}