def do_exec(self, parameter: str) -> StatusCode: result: StatusCode = StatusCode.SUCCEED_STATUS try: try: result = self.on_exec(parameter if parameter else self._task_data_parameter) if result.is_success: # notify "[Task] " + this.CurrentTaskInfo.description + " Done" pass except Exception as ex: result = StatusCode(CommonStatusCode.TASK_EXECUTION_FAILED, arguments=[self.application_id, self.task_info_id, self._task_data_parameter, self.task_data_id], exception=ex, config=self.config, target_application_id=self.application_id) result2 = self.__create_new_instance(parameter, status=self.STATUS_COMPLETE if result.is_success else self.STATUS_FAIL, submit_to=None, status_code=None if result.is_success else result, comment='') if not result.is_success: return result else: return result2 except Exception as ex2: result = StatusCode(CommonStatusCode.TASK_LIBRARY_INTERNAL_ERROR, arguments=[self.application_id, self.task_info_id, self._task_data_parameter, self.task_data_id], exception=ex2, config=self.config, target_application_id=self.application_id) # Event Notification for Task Finish return result
def __init(self, parameter: str, comment: str) -> StatusCode: result: StatusCode try: result = self.__check_status_and_owner(self.STATUS_INIT) if not result.is_success: return result self._task_data_parameter = parameter if self.task_data_id != -1: return StatusCode(CommonStatusCode.TASK_ALREADY_GENERATED, arguments=[self.application_id, self.task_info_id, self._task_data_parameter, self.task_data_id], config=self.config, target_application_id=self.application_id) try: with DbConnectionFactory.get_gyomu_db_session() as session: task_data = GyomuTaskData() task_data.application_id = self.application_id task_data.task_info_id = self.task_info_id task_data.entry_author = self.config.username task_data.parameter = parameter session.add(task_data) session.flush() task_instance = GyomuTaskInstance() task_instance.task_data_id = task_data.id task_instance.entry_date = task_data.entry_date task_instance.entry_author = task_data.entry_author task_instance.task_status = "INIT" task_instance.is_done = False task_instance.parameter = parameter task_instance.comment = comment session.add(task_instance) session.flush() task_status = GyomuTaskDataStatus() task_status.task_data_id = task_data.id task_status.latest_task_instance_id = task_instance.id task_status.latest_update_date = task_instance.entry_date task_status.task_status = task_instance.task_status session.add(task_status) session.commit() self._current_task = task_data self._task_data_id = task_data.id self._latest_instance = task_instance self.__instances = [task_instance] self._latest_instance_id = task_instance.id except Exception as ex: return StatusCode(CommonStatusCode.TASK_GENERATE_ERROR, arguments=[self.application_id, self.task_info_id, parameter], config=self.config, target_application_id=self.application_id, exception=ex) except Exception as ex: return StatusCode(CommonStatusCode.TASK_LIBRARY_INTERNAL_ERROR, arguments=[self.application_id, self.task_info_id, parameter, self.task_data_id], config=self.config, target_application_id=self.application_id, exception=ex) return result
def archive(archive_filename: str, archive_type: FileArchiveType, source_file_list: list[FileTransportInfo], config: Configurator, application_id: int, password: str = None) -> StatusCode: if source_file_list is None or len(source_file_list) == 0: return StatusCode.invalid_argument_status( "Source File Not Specified to archive", config, application_id) archive_info = FileInfo(archive_filename) if archive_type == FileArchiveType.GuessFromFileName: extension = archive_info.extension.lower() if extension == "zip": archive_type = FileArchiveType.ZIP elif extension == "tgz": archive_type = FileArchiveType.TGZ elif extension == "bz2": archive_type = FileArchiveType.BZIP2 elif extension == "gz": archive_type = FileArchiveType.GZIP elif extension == "tar": archive_type = FileArchiveType.TAR else: return StatusCode.invalid_argument_status( "File Extension Not supported for archiving", config, application_id) if archive_type == FileArchiveType.BZIP2 or archive_type == FileArchiveType.GZIP: if len(source_file_list) > 1 or len( [f for f in source_file_list if f.is_source_directory]) > 0: return StatusCode.invalid_argument_status( "Multiple files are not supported in this compression type", config, application_id) if archive_type != FileArchiveType.ZIP and password != "": return StatusCode.invalid_argument_status( "password is not supported on other than zip format", config, application_id) source_file = source_file_list[0] archive_file_directory = archive_info.dir_path archive_name = archive_info.file_name if archive_type == FileArchiveType.ZIP: gyomu.archive.zip.ZipArchive.create( zip_filename=archive_name, transfer_information_list=source_file_list, password=password, config=config) return StatusCode.SUCCEED_STATUS
def __check_status_and_owner(self, target_status: str) -> StatusCode: if not self.__internal_valid_status(target_status): return StatusCode(CommonStatusCode.TASK_STATUS_INCONSISTENT, arguments=[self.application_id, self.task_info_id, self.task_data_id, self.latest_instance_id, self.latest_instance.task_status, target_status], config=self.config, target_application_id=self.application_id) elif not self.__internal_valid_owner(target_status): return StatusCode(CommonStatusCode.INVALID_USER_ACCESS, arguments=[self.application_id, self.task_info_id, self.task_data_id, self.latest_instance_id, target_status, self.current_user.userid], config=self.config, target_application_id=self.application_id) else: return StatusCode.SUCCEED_STATUS
def __create_new_instance(self, parameter: str, status: str, submit_to: list[User] = None, status_code: StatusCode = None, comment: str = '') -> StatusCode: try: new_instance = GyomuTaskInstance() with DbConnectionFactory.get_gyomu_db_session() as session: new_instance.task_data_id = self._current_task.id new_instance.is_done = status in [self.STATUS_COMPLETE, self.STATUS_FAIL, self.STATUS_CANCEL] # new_instance.entry_date = self._current_task.entry_date new_instance.entry_author = self.config.username new_instance.task_status = status new_instance.parameter = parameter new_instance.comment = comment new_instance.status_info_id = None if status_code is None else status_code.get_status_id() session.add(new_instance) session.flush() task_status = session.get(GyomuTaskDataStatus, self._current_task.id) if task_status is None: task_status = GyomuTaskDataStatus() task_status.task_data_id = self._current_task.id task_status.latest_task_instance_id = new_instance.id task_status.latest_update_date = new_instance.entry_date task_status.task_status = new_instance.task_status session.add(task_status) else: task_status.latest_task_instance_id = new_instance.id task_status.latest_update_date = new_instance.entry_date task_status.task_status = new_instance.task_status if submit_to is not None and len(submit_to) > 0: for user in submit_to: if user.is_valid: submit_information = GyomuTaskInstanceSubmitInformation() submit_information.task_instance_id = self.latest_instance_id submit_information.submit_to = user.userid session.add(submit_information) session.commit() self._latest_instance = new_instance self._latest_instance_id = new_instance.id self.__instances.append(new_instance) return StatusCode.SUCCEED_STATUS except Exception as ex: return StatusCode(CommonStatusCode.TASK_INSTANCE_GENERATE_ERROR, arguments=[self.application_id, self.task_info_id, self.task_data_id, parameter], config=self.config, target_application_id=self.application_id, exception=ex)
def create(cls, zip_filename: str, transfer_information_list: list[FileTransportInfo], config: Configurator, application_id: int =-1, password: str = "", encoding: str = 'ascii', is_aes_encrypted: bool = True) -> StatusCode: if password != "" and not is_aes_encrypted: raise ValueError("Other than AES Encryption is supported") if application_id==-1: application_id= config.application_id pwd: bytes = bytes(password, encoding) if password != "" and ascii != "" else bytes() with cls.__create_zip_object(zip_filename, mode='w', password=pwd, is_aes_encrypted=is_aes_encrypted) as zip_object: for transfer_information in transfer_information_list: source_path = transfer_information.source_fullname_with_basepath if not os.path.exists(source_path): return StatusCode(StatusCode.FILE_NOT_FOUND, config, arguments=[source_path], target_application_id=application_id) if not transfer_information.is_source_directory: destination_entry_name = transfer_information.destination_fullname destination_entry_name = destination_entry_name.replace(os.sep, "/") zip_object.write(filename=source_path, arcname=destination_entry_name) else: for root, _, files in os.walk(source_path): for filename in files: source_file_full_path = os.path.join(root, filename) # destination_entry_name = filename if not transfer_information.source_path \ # else os.path.join(transfer_information.source_path, filename) destination_entry_name = source_file_full_path[len(source_path) + 1:] destination_entry_name = destination_entry_name.replace(os.sep, "/") zip_object.write(filename=source_file_full_path, arcname=destination_entry_name) return StatusCode.SUCCEED_STATUS
def __run(self, parameter: str, comment: str) -> StatusCode: try: with self.__lock: self.__lock_instance_and_refresh_task_data() return self.__execution_decision(parameter, comment) except Exception as ex: return StatusCode(CommonStatusCode.TASK_LIBRARY_INTERNAL_ERROR, arguments=[self.application_id, self.task_info_id, parameter, self.task_data_id], config=self.config, target_application_id=self.application_id, exception=ex)
def __create_instance( module_name: str, class_name: str, config: Configurator) -> (AbstractBaseTask, StatusCode): try: module = importlib.import_module(module_name) cls = getattr(module, class_name) task: AbstractBaseTask = cls(config) return task, StatusCode.SUCCEED_STATUS except Exception as ex: return None, StatusCode( CommonStatusCode.TASK_CLASS_CREATE_ERROR, arguments=[module_name, class_name], exception=ex, config=config, target_application_id=config.application_id)
def unzip(cls, transfer_information: FileTransportInfo, config: Configurator, application_id: int = -1, password: str = "", encoding: str = 'ascii', is_aes_encrypted: bool = False): pwd: bytes = bytes(password, encoding) if password != "" and ascii != "" else bytes() if application_id == -1: application_id = config.application_id zip_filename = transfer_information.source_fullname_with_basepath if not os.path.exists(zip_filename): return StatusCode(StatusCode.FILE_NOT_FOUND, config, arguments=[zip_filename], target_application_id=application_id) with cls.__create_zip_object(zip_filename, 'r', password=pwd, is_aes_encrypted=is_aes_encrypted) as zip_object: for info in zip_object.infolist(): if info.filename.endswith("/"): continue cls.__zip_info_adjust(info, encoding) zip_object.extract(info, transfer_information.destination_path)
def create_new_task( application_id: int, task_id: int, config: Configurator = None) -> (AbstractBaseTask, StatusCode): task_info: GyomuTaskInfoCdtbl try: if config is None: config = gyomu.configurator.ConfigurationFactory.get_instance() with DbConnectionFactory.get_gyomu_db_session() as session: task_info = session.query(GyomuTaskInfoCdtbl).filter( GyomuTaskInfoCdtbl.application_id == application_id and GyomuTaskInfoCdtbl.task_id == task_id).one() except NoResultFound: return None, StatusCode( error_id=CommonStatusCode.TASK_NOT_REGISTERED, arguments=[application_id, task_id], config=config, target_application_id=application_id) if task_info is not None: return TaskAccess.__create_new_task(task_info, config)
def static_initialize(cls): cls.EMAIL_SEND_ERROR = StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x10, "Email Sent Failed", "") cls.TASK_CLASS_CREATE_ERROR = StatusCode._code_gen( cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x40, "Task class can't be created", "Module:{0}\nClass:{1}") cls.TASK_GENERATE_ERROR = StatusCode._code_gen( cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x41, "Task can't be generated", "ApplicationID:{0}\nTask Info ID:{1}\nParameter:{2}") cls.TASK_INSTANCE_GENERATE_ERROR = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x42, "Task Instance can't be generated", "ApplicationID:{0}\nTask Info ID:{1}\nTask Data ID:{2}\nParameter:{3}") cls.TASK_ALREADY_GENERATED = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x43, "Task is already generated. Can't start twice in the same instance.", "ApplicationID:{0}\nTask Info ID:{1}\nParameter:{2}\nTask Data ID:{3}") cls.TASK_EXECUTION_FAILED = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x44, "Unknown Exception happens. Developer must handle exception in the target task.", "ApplicationID:{0}\nTask Info ID:{1}\nParameter:{2}\nTask Data ID:{3}") cls.TASK_LIBRARY_INTERNAL_ERROR = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x45, "Task Library Internal Error happens", "Developer must fix the issue,\nApplicationID:{0}\nTask Info ID:{1}\nParameter:{" "2}\nTask Data ID:{3}") cls.TASK_INSTANCE_ALREADY_CHANGED = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_BUSINESS, 0x46, "Task already changed", "Task {0} Status already changed since you got before.\nID:{1}") cls.TASK_INSTANCE_NOT_EXIST = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x47, "Task Instance Not Found", "ApplicationID:{0}\nTask Info ID:{1}\nTask Data ID:{2}\nInstance ID:{3}") cls.TASK_STATUS_INCONSISTENT = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x48, "There is inconsistent in task status", "ApplicationID:{0}\nTask Info ID:{1}\nTask Data ID:{2}\nInstance ID:{3}\n" "Current Status:{4}\nRequest Status:{5}") cls.MAIL_CANNOT_BE_SENT = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_BUSINESS, 0x49, "E-mail can't be sent, but process succeeded.Please send by yourself.", "Task {0} ") cls.OVERRIDE_METHOD_OTHER_ERROR = StatusCode._code_gen( cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x4a, "Overrided Method caused unhandled Exception.", "Developers need to fix this issue.") cls.INVALID_USER_ACCESS = \ StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x4b, "Invalid User Access Found", "ApplicationID:{0}\nTask Info ID:{1}\nTask Data ID:{2}\nInstance ID:{3}\n" "Target Action:{4}\nCurrent User:{5}") # cls.INVALID_USER_ACCESS_TASKBATCH = StatusCode._code_gen(cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x4c, # "Invalid User Access Found", # "Task Batch ID:{0}\nTask Batch Data ID:{1}\n") cls.TASK_CANNOT_BE_INSTANCED = StatusCode._code_gen( cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x4d, "Assembly can't be found", "Assembly:{0}\nClass:{1}") cls.TASK_NOT_REGISTERED = StatusCode._code_gen( cls.APP_ID, StatusCode.ERROR_DEVELOPER, 0x4e, "Task is not registered", "ApplicationID:{0}\nTask Info ID:{1}")
def test_status_code(status_handler_setup, register_file_mail_sender): config: Configurator = status_handler_setup ret_val: StatusCode = StatusCode.debug("Debug Test", config, application_id=config.application_id) print(ret_val.get_status_id()) print(str(StatusCode.SUCCEED_STATUS.code)) print(str(ret_val))
def on_exec(self, parameter: str) -> StatusCode: print('Task 2 Fail Test') print('Parameter: ' + parameter) return StatusCode(StatusCode.INVALID_ARGUMENT_ERROR, config=self.config, description="Just a failure")
def run(self): config = ConfigurationFactory.get_instance( shared_dictionary=self.shared_dictionary) StatusCode.debug('Process Init', config) if self._target: self._target(*self._args, **self._kwargs)