diff --git a/ecs/jskult-batch/src/aws/s3.py b/ecs/jskult-batch/src/aws/s3.py index b37b38d2..27701f7b 100644 --- a/ecs/jskult-batch/src/aws/s3.py +++ b/ecs/jskult-batch/src/aws/s3.py @@ -53,46 +53,31 @@ class S3Bucket(): class ConfigBucket(S3Bucket): - # TODO 日付更新処理で内容の修正を行う _bucket_name = environment.JSKULT_CONFIG_BUCKET - def download_holiday_list(self): + def download_jsk_archive_run_day_list(self): # 一時ファイルとして保存する temporary_dir = tempfile.mkdtemp() temporary_file_path = path.join( - temporary_dir, environment.JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME) - holiday_list_key = f'{environment.JSKULT_CONFIG_CALENDAR_FOLDER}/{environment.JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME}' + temporary_dir, environment.JSKULT_CONFIG_CALENDAR_RUN_ARCHIVE_DAY_FILE_NAME) + jsk_archive_run_day_list_key = f'{environment.JSKULT_CONFIG_CALENDAR_FOLDER}/{environment.JSKULT_CONFIG_CALENDAR_RUN_ARCHIVE_DAY_FILE_NAME}' with open(temporary_file_path, mode='wb') as f: self._s3_client.download_file( - self._bucket_name, holiday_list_key, f) + self._bucket_name, jsk_archive_run_day_list_key, f) f.seek(0) return temporary_file_path - - def download_wholesaler_stock_input_day_list(self): - # 一時ファイルとして保存する + + def download_jsk_expected_data_list(self): temporary_dir = tempfile.mkdtemp() temporary_file_path = path.join( - temporary_dir, environment.JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME) - wholesaler_stock_input_day_list_key = \ - f'{environment.JSKULT_CONFIG_CALENDAR_FOLDER}/{environment.JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME}' - + temporary_dir, environment.JSKULT_CONFIG_EXPECTED_DATA_LIST_FILE_NAME) + jsk_expected_data_list_key = f'{environment.JSKULT_CONFIG_EXPECTED_DATA_LIST_FOLDER}/{environment.JSKULT_CONFIG_EXPECTED_DATA_LIST_FILE_NAME}' with open(temporary_file_path, mode='wb') as f: self._s3_client.download_file( - self._bucket_name, wholesaler_stock_input_day_list_key, f) + self._bucket_name, jsk_expected_data_list_key, f) f.seek(0) return temporary_file_path - def download_ultmarc_hex_convert_config(self): - # 一時ファイルとして保存する - temporary_dir = tempfile.mkdtemp() - temporary_file_path = path.join( - temporary_dir, environment.JSKULT_ULTMARC_HEX_CONVERT_CONFIG_FILE_NAME) - hex_convert_config_key = f'{environment.JSKULT_CONFIG_CONVERT_FOLDER}/{environment.JSKULT_ULTMARC_HEX_CONVERT_CONFIG_FILE_NAME}' - with open(temporary_file_path, mode='wb') as f: - self._s3_client.download_file( - self._bucket_name, hex_convert_config_key, f) - f.seek(0) - return temporary_file_path class JskUltBackupBucket(S3Bucket): diff --git a/ecs/jskult-batch/src/batch/common/calendar_file.py b/ecs/jskult-batch/src/batch/common/calendar_file.py new file mode 100644 index 00000000..b456f03c --- /dev/null +++ b/ecs/jskult-batch/src/batch/common/calendar_file.py @@ -0,0 +1,32 @@ +from src.system_var import constants + + +class CalendarFile: + """カレンダーファイル""" + + __calendar_file_lines: list[str] + + def __init__(self, calendar_file_path): + with open(calendar_file_path) as f: + self.__calendar_file_lines: list[str] = f.readlines() + + def compare_date(self, date_str: str) -> bool: + """与えられた日付がカレンダーファイル内に含まれているかどうか + カレンダーファイル内の日付はyyyy/mm/ddで書かれている前提 + コメント(#)が含まれている行は無視される + + Args: + date_str (str): yyyy/mm/dd文字列 + + Returns: + bool: 含まれていればTrue + """ + for calendar_date in self.__calendar_file_lines: + # コメント行が含まれている場合はスキップ + if constants.CALENDAR_COMMENT_SYMBOL in calendar_date: + continue + + if date_str in calendar_date: + return True + + return False diff --git a/ecs/jskult-batch/src/batch/update_business_day.py b/ecs/jskult-batch/src/batch/update_business_day.py index 65b8916d..298eb7c9 100644 --- a/ecs/jskult-batch/src/batch/update_business_day.py +++ b/ecs/jskult-batch/src/batch/update_business_day.py @@ -2,7 +2,9 @@ import json import boto3 from datetime import datetime from src.batch.jskult_batch_entrypoint import JskultBatchEntrypoint -from src.aws.s3 import JskTransferListBucket +from src.aws.s3 import (ConfigBucket, + JskTransferListBucket) +from src.batch.common.calendar_file import CalendarFile from src.batch.environment.update_business_day_environment import \ UpdateBusinessDayEnvironment from src.manager.jskult_batch_run_manager import JskultBatchRunManager @@ -54,10 +56,10 @@ class UpdateBusinessDay(JskultBatchEntrypoint): '日次バッチ処理中でない、もしくはdump取得が正常終了していないため、日次バッチ処理を異常終了します。') # バッチ実行管理テーブルをfailedで登録 jskult_batch_run_manager.batch_failed() - + # バッチステータス管理テーブルをエラーに更新 jskult_batch_status_manager.set_process_status( - constants.PROCESS_STATUS_ERROR) + constants.PROCESS_STATUS_ERROR) return try: @@ -71,7 +73,7 @@ class UpdateBusinessDay(JskultBatchEntrypoint): jskult_batch_run_manager.batch_retry() return - + except MaxRunCountReachedException: logger.error('後続処理の実行が完了していないため、日付テーブル更新処理を異常終了します。') @@ -82,40 +84,65 @@ class UpdateBusinessDay(JskultBatchEntrypoint): logger.error(f'E-1 異常終了:実消化&アルトマーク_日付テーブル更新。{e}') return try: - # TODO アーカイブ取得日カレンダーを取得する - get_archive_calendar = None - # 日付テーブルの処理年月日を取得する - _, _, process_date = jskult_hdke_tbl_manager.get_batch_statuses() - - - if get_archive_calendar == process_date: + _, _, syor_date = jskult_hdke_tbl_manager.get_batch_statuses() + + if self._is_archive_run_day(syor_date): logger.info('I-7 [NOTICE]実消化データアーカイブ取得処理を実行します。') - + # 実消化データアーカイブ取得処理を起動する sfn_client = boto3.client('stepfunctions') # StepFunctionsを起動する - response = sfn_client.start_execution( + sfn_client.start_execution( stateMachineArn=self.environment.ARCHIVE_STATEMACHINE_ARN ) - dt = datetime.strptime(process_date, "%Y/%m/%d") + dt = datetime.strptime(syor_date, "%Y/%m/%d") # 日付テーブルの処理年月日が月曜日の場合 - if dt.weekday() == 0: - if not JskultBatchStatusManager.is_done_ultmarc_import(): - logger.info('[NOTICE]アルトマーク取込稼働日でしたが、アルトマーク取込が行われませんでした。') + if dt.weekday() == constants.WEEKDAY_MONDAY: - # TODO 実消化転送データ一覧を取得する - jsk_receive_file_list = None - # TODO 実消化&アルトマーク_実消化受領予定データリストを取得する - transfer_list = None + if not jskult_batch_status_manager.is_done_ultmarc_import(): + logger.info( + 'I-3 [NOTICE]アルトマーク取込稼働日でしたが、アルトマーク取込が行われませんでした。') - if transfer_list is not None: - # TODO jsk_receive_file_listと比較して結果不足ファイルがあった場合(I-5)ログ出力 + # 実消化転送データ一覧を取得する + try: + transfer_list_bucket = JskTransferListBucket() - # TODO jsk_receive_file_listと比較して受領予定にないファイルがあった場合(I-6)ログ出力 - pass + transfer_list_file_path = transfer_list_bucket.download_transfer_result_file( + syor_date) + except Exception as e: + logger.exception(f'転送ファイル一覧の取得に失敗しました。 {e}') + # バッチ実行管理テーブルをfailedで登録 + jskult_batch_run_manager.batch_failed() + + with open(transfer_list_file_path) as f: + transfer_data_list = json.load(f) + + jsk_transfer_data_list = transfer_data_list['jsk_transfer_list'] + + # 実消化&アルトマーク_実消化受領予定データリストを取得する + try: + config_bucket = ConfigBucket() + jsk_expected_data_path = config_bucket.download_jsk_expected_data_list() + except Exception as e: + logger.exception(f'転送ファイル一覧の取得に失敗しました。 {e}') + # バッチ実行管理テーブルをfailedで登録 + jskult_batch_run_manager.batch_failed() + + with open(jsk_expected_data_path) as f: + jsk_expected_data_list = json.load(f) + + jsk_transfer_expected_data_list = jsk_expected_data_list['jsk_transfer_list'] + + if len(jsk_transfer_data_list) != 0: + # 不足ファイルがあった場合ログ出力 + self._check_missing_received_files( + jsk_transfer_expected_data_list, jsk_transfer_data_list) + # 受領予定にないファイルがあった場合ログ出力 + self._check_extra_received_files( + jsk_transfer_expected_data_list, jsk_transfer_data_list) jskult_hdke_tbl_manager.update_batch_process_complete() # 処理ステータスを「処理済」に設定 @@ -124,10 +151,49 @@ class UpdateBusinessDay(JskultBatchEntrypoint): jskult_batch_run_manager.batch_success() - logger.info('[NOTICE]処理終了: 実消化&アルトマーク_日付テーブル更新') + logger.info('I-4 [NOTICE]処理終了: 実消化&アルトマーク_日付テーブル更新') except Exception as e: # 何らかのエラーが発生した際に、バッチ実行管理テーブルに「failed」で登録 jskult_batch_run_manager.batch_failed() jskult_batch_status_manager.set_process_status( constants.PROCESS_STATUS_ERROR) logger.error(f'E-1 異常終了:実消化&アルトマーク_日付テーブル更新。{e}') + + def _is_archive_run_day(self, syor_date: str): + # アーカイブ取得日カレンダーを取得する + archive_calendar_file_path = ConfigBucket().download_jsk_archive_run_day_list() + + # 設定ファイル「実消化データアーカイブ起動日カレンダーファイル」の定義内容を取得する + target_days = CalendarFile(archive_calendar_file_path) + + # 処理日付が、設定ファイル「実消化データアーカイブ起動日カレンダーファイル」の定義に該当するかを判定する + return target_days.compare_date(syor_date) + + def _check_missing_received_files(self, jsk_transfer_expected_data_list: list, jsk_transfer_data_list: list): + # jsk_transfer_data_listと比較し、結果不足ファイルがあった場合ログ出力 + missing_files = [ + jsk_transfer_expected_data + for jsk_transfer_expected_data in jsk_transfer_expected_data_list + if not any( + jsk_transfer_data.startswith( + jsk_transfer_expected_data) + for jsk_transfer_data in jsk_transfer_data_list + ) + ] + if missing_files != 0: + logger.info( + f'I-5 [NOTICE]日次連携受領ファイルに不足がありました。ファイル名:{missing_files}') + + def _check_extra_received_files(self, jsk_transfer_expected_data_list: list, jsk_transfer_data_list: list): + unexpected_data = [ + jsk_transfer_data + for jsk_transfer_data in jsk_transfer_data_list + if not any( + jsk_transfer_data.startswith( + jsk_transfer_expected_data) + for jsk_transfer_expected_data in jsk_transfer_expected_data_list + ) + ] + if len(unexpected_data) != 0: + logger.info( + f'I-6 [NOTICE]受領ファイルに日次連携ファイルでないファイルがありました。ファイル名:{unexpected_data}') diff --git a/ecs/jskult-batch/src/system_var/environment.py b/ecs/jskult-batch/src/system_var/environment.py index 63fcc236..fbb334f3 100644 --- a/ecs/jskult-batch/src/system_var/environment.py +++ b/ecs/jskult-batch/src/system_var/environment.py @@ -13,8 +13,9 @@ PROCESS_NAME = os.environ.get('PROCESS_NAME', None) # AWS JSKULT_CONFIG_BUCKET = os.environ.get('JSKULT_CONFIG_BUCKET', None) JSKULT_BACKUP_BUCKET = os.environ.get('JSKULT_BACKUP_BUCKET', None) -BATCH_MANAGE_DYNAMODB_TABLE_NAME = os.environ.get('BATCH_MANAGE_DYNAMODB_TABLE_NAME', None) -ARCHIVE_STATEMACHINE_ARN = os.environ('ARCHIVE_STATEMACHINE_ARN', None) +BATCH_MANAGE_DYNAMODB_TABLE_NAME = os.environ.get( + 'BATCH_MANAGE_DYNAMODB_TABLE_NAME', None) +ARCHIVE_STATEMACHINE_ARN = os.environ.get('ARCHIVE_STATEMACHINE_ARN', None) BATCH_EXECUTION_ID = os.environ.get('BATCH_EXECUTION_ID', None) MAX_RUN_COUNT = os.environ.get('MAX_RUN_COUNT', None) TRANSFER_RESULT_FOLDER = os.environ.get('TRANSFER_RESULT_FOLDER', None) @@ -31,6 +32,8 @@ JSKULT_CONFIG_EXPECTED_DATA_LIST_FOLDER = os.environ.get( JSKULT_CONFIG_EXPECTED_DATA_LIST_FILE_NAME = os.environ.get( 'JSKULT_CONFIG_EXPECTED_DATA_LIST_FILE_NAME', None ) +JSK_IO_BUCKET = os.environ.get('JSK_IO_BUCKET', None) +JSK_DATA_SEND_FOLDER = os.environ.get('JSK_DATA_SEND_FOLDER', None) # 初期値がある環境変数