<commit_before>import json
import re
from abc import ABC, abstractmethod

from atlas.JIRA.client import JIRAClient
from atlas.jedi.client import JEDIClient, JEDITaskActionInterface
import logging
from django.utils import timezone

from atlas.prodtask.ddm_api import DDM
from atlas.prodtask.hashtag import add_or_get_request_hashtag
from atlas.prodtask.models import ProductionTask, TRequest, ActionStaging, StepAction
from atlas.prodtask.task_views import sync_deft_jedi_task

logger = logging.getLogger('prodtaskwebui')
_jsonLogger = logging.getLogger('prodtask_ELK')
from dataclasses import dataclass


class DEFTAction(ABC):

    @abstractmethod
    def create_disable_idds_action(self, task_id):
        pass

    # @abstractmethod
    # def increase_task_priority(self, task_id, delta):
    #     pass
    #
    # @abstractmethod
    # def decrease_task_priority(self, task_id, delta):
    #     pass

    @abstractmethod
    def obsolete_task(self, task_id):
        pass

    @abstractmethod
    def sync_jedi(self, task_id):
        pass

    @abstractmethod
    def set_hashtag(self, task_id, hashtag_name):
        pass

    @abstractmethod
    def remove_hashtag(self, task_id, hashtag_name):
        pass

    @abstractmethod
    def retry_new(self, task_id):
        pass

    @abstractmethod
    def clean_task_carriages(self, task_id, output_formats):
        pass

    @abstractmethod
    def kill_jobs_in_task(self, task_id, jobs_id_str, code, keepUnmerged):
        pass


@dataclass
class TaskActionExecutor(JEDITaskActionInterface, DEFTAction):

    username: str
    comment: str

    def __init__(self, username, comment=''):
        self.jedi_client = JEDIClient()
        self.username = username
        self.jira_client = None
        self.comment = comment

    def _log_production_task_action_message(self, production_request_id, task_id, action, return_code, return_message, *args):
        _jsonLogger.info("Production task action",
                         extra={'task': str(task_id), 'prod_request': production_request_id,'user': self.username, 'action': action, 'params': json.dumps(args),
                                'return_code': return_code,'return_message': return_message ,'comment': self.comment})
        # print({'task': str(task_id), 'prod_request': production_request_id,'user': self.username, 'action': action, 'params': json.dumps(args),
        #                          'return_code': return_code,'return_message': return_message})

    def _log_analysis_task_action_message(self, task_id, action, return_code, return_message, *args):
        _jsonLogger.info("Analysis task action",
                         extra={'task': str(task_id), 'user': self.username, 'comment': self.comment,
                                'action': action, 'params': json.dumps(args),
                                'return_code': return_code, 'return_message': return_message})
        # print({'task': str(task_id), 'user': self.username,
        #                          'action': action, 'params': json.dumps(args),
        #                          'return_code': return_code, 'return_message': return_message})

    def _log_action_message(self, task_id, action, return_code, return_message, *args):
        try:

            if ProductionTask.objects.filter(id=task_id).exists():
                task = ProductionTask.objects.get(id=task_id)
                if task.request_id > 300:
                    production_request = task.request
                    # if not production_request.info_field('task_jira_es'):
                    #     if not self.jira_client:
                    #         self.jira_client = JIRAClient()
                    #     production_request.set_info_field('task_jira_es', True)
                    #     production_request.save()
                    self._log_production_task_action_message(production_request.reqid, task_id, action, return_code, return_message, *args)
                    return
            self._log_analysis_task_action_message(task_id, action, return_code, return_message, *args)
        except Exception as ex:
            logger.error(f"Action logging problem: {ex}")
            print(f"Action logging problem: {ex}")


    def _jedi_decorator(func):
        def inner(self, task_id, *args, **kwargs):
            try:
                result = func(self, task_id, *args, **kwargs)
                logger.info(f"JEDI action {task_id} {func.__name__} with parameters {args} from {self.username} result  {result}")
                return_code, return_message = result
                if type(return_code) is int and return_code == 0:
                    return_code = True
                self._log_action_message(task_id, func.__name__, bool(return_code), return_message, *args)
                return bool(return_code), return_message
            except Exception as ex:
                self._log_action_message(task_id, func.__name__, False, str(ex), *args)
                return False, str(ex)
        return inner

    def _action_logger(func):
        def inner(self, task_id, *args, **kwargs):
            try:
                return_code, return_message = func(self, task_id, *args, **kwargs)
                self._log_action_message(task_id, func.__name__, return_code, return_message, *args)
                return return_code, return_message
            except Exception as ex:
                self._log_action_message(task_id, func.__name__, False, str(ex), *args)<commit_msg>Add JIRA action initial comment<commit_after>import json
import re
from abc import ABC, abstractmethod

from atlas.JIRA.client import JIRAClient
from atlas.jedi.client import JEDIClient, JEDITaskActionInterface
import logging
from django.utils import timezone

from atlas.prodtask.ddm_api import DDM
from atlas.prodtask.hashtag import add_or_get_request_hashtag
from atlas.prodtask.models import ProductionTask, TRequest, ActionStaging, StepAction
from atlas.prodtask.task_views import sync_deft_jedi_task

logger = logging.getLogger('prodtaskwebui')
_jsonLogger = logging.getLogger('prodtask_ELK')
from dataclasses import dataclass


class DEFTAction(ABC):

    @abstractmethod
    def create_disable_idds_action(self, task_id):
        pass

    # @abstractmethod
    # def increase_task_priority(self, task_id, delta):
    #     pass
    #
    # @abstractmethod
    # def decrease_task_priority(self, task_id, delta):
    #     pass

    @abstractmethod
    def obsolete_task(self, task_id):
        pass

    @abstractmethod
    def sync_jedi(self, task_id):
        pass

    @abstractmethod
    def set_hashtag(self, task_id, hashtag_name):
        pass

    @abstractmethod
    def remove_hashtag(self, task_id, hashtag_name):
        pass

    @abstractmethod
    def retry_new(self, task_id):
        pass

    @abstractmethod
    def clean_task_carriages(self, task_id, output_formats):
        pass

    @abstractmethod
    def kill_jobs_in_task(self, task_id, jobs_id_str, code, keepUnmerged):
        pass


@dataclass
class TaskActionExecutor(JEDITaskActionInterface, DEFTAction):

    username: str
    comment: str

    ES_PATTERN = "https://es-atlas.cern.ch/kibana/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-7d,to:now))&_a=(columns:!(task,prod_request,user,return_code,return_message,comment),filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:bce7ecb0-7533-11eb-ba28-77fe4323ac05,key:funcName,negate:!f,params:(query:_log_production_task_action_message),type:phrase),query:(match_phrase:(funcName:_log_production_task_action_message))),('$state':(store:appState),meta:(alias:!n,disabled:!f,index:bce7ecb0-7533-11eb-ba28-77fe4323ac05,key:prod_request,negate:!f,params:(query:{0}),type:phrase),query:(match_phrase:(prod_request:{0})))),index:bce7ecb0-7533-11eb-ba28-77fe4323ac05,interval:M,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"

    JIRA_MESSAGE_TEMPLATE = "Tasks actions for this request can be found [es-atlas|{link}]"
    def __init__(self, username, comment=''):
        self.jedi_client = JEDIClient()
        self.username = username
        self.jira_client = None
        self.comment = comment

    def _log_production_task_action_message(self, production_request_id, task_id, action, return_code, return_message, *args):
        _jsonLogger.info("Production task action",
                         extra={'task': str(task_id), 'prod_request': production_request_id,'user': self.username, 'action': action, 'params': json.dumps(args),
                                'return_code': return_code,'return_message': return_message ,'comment': self.comment})


    def _log_analysis_task_action_message(self, task_id, action, return_code, return_message, *args):
        _jsonLogger.info("Analysis task action",
                         extra={'task': str(task_id), 'user': self.username, 'comment': self.comment,
                                'action': action, 'params': json.dumps(args),
                                'return_code': return_code, 'return_message': return_message})


    def _log_action_message(self, task_id, action, return_code, return_message, *args):
        try:

            if ProductionTask.objects.filter(id=task_id).exists():
                task = ProductionTask.objects.get(id=task_id)
                if task.request_id > 300:
                    production_request = task.request
                    es_link = self.ES_PATTERN.format(production_request.reqid)
                    jira_message = self.JIRA_MESSAGE_TEMPLATE.format(link=es_link)
                    if production_request.jira_reference and not production_request.info_field('task_jira_es'):
                        if not self.jira_client:
                            self.jira_client = JIRAClient()
                            self.jira_client.authorize()
                        self.jira_client.add_issue_comment(production_request.jira_reference, jira_message)
                        production_request.set_info_field('task_jira_es', True)
                        production_request.save()
                    self._log_production_task_action_message(production_request.reqid, task_id, action, return_code, return_message, *args)
                    return
            self._log_analysis_task_action_message(task_id, action, return_code, return_message, *args)
        except Exception as ex:
            logger.error(f"Action logging problem: {ex}")
            print(f"Action logging problem: {ex}")


    def _jedi_decorator(func):
        def inner(self, task_id, *args, **kwargs):
            try:
                result = func(self, task_id, *args, **kwargs)
                logger.info(f"JEDI action {task_id} {func.__name__} with parameters {args} from {self.username} result  {result}")
                return_code, return_message = result
                if type(return_code) is int and return_code == 0:
                    return_code = True
                self._log_action_message(task_id, func.__name__, bool(return_code), return_message, *args)
                return bool(return_code), return_message
            except Exception as ex:
                self._log_action_message(task_id, func.__name__, False, str(ex), *args)
                return False, str(ex)
        return inner

    def _action_logger(func):
        def inner(self, task_id, *args, **kwargs):
            try:
                return_code, return_message = func(self, task_id, *args, **kwargs)
                self._log_action_message(task_id, func.__name__, return_code, return_message, *args)
                return return_code, return_message
            except Exception as ex:
                self._log_action_message(task_id, func.__name__, False, str(ex), *args)
{'fraction_non_alphanumeric': 0.09976166155941436, 'fraction_numerical': 0.0056179775280898875, 'mean_word_length': 2.8345300261096606, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3851468', 'n_tokens_mistral': 3557, 'n_tokens_neox': 3424, 'n_words': 690}