diff --git a/lambda/mbj-newdwh2021-staging-lambda-sap-fin-receive-check-daily.py b/lambda/mbj-newdwh2021-staging-lambda-sap-fin-receive-check-daily.py new file mode 100644 index 00000000..1f25ca32 --- /dev/null +++ b/lambda/mbj-newdwh2021-staging-lambda-sap-fin-receive-check-daily.py @@ -0,0 +1,190 @@ +import os +import datetime +import boto3 +import io +import re +import sys + +# 環境変数 +CHECK_BUCKET_NAME = os.environ["CHECK_BUCKET_NAME"] +CONFIG_BUCKET_NAME = os.environ["CONFIG_BUCKET_NAME"] +RECEIVE_DAILY_FILE_NAME_LIST_PATH = os.environ["RECEIVE_DAILY_FILE_NAME_LIST_PATH"] +NON_BUSINESS_DAY_LIST_PATH = os.environ["NON_BUSINESS_DAY_LIST_PATH"] +NOTICE_MAIL_TITLE_TEMPLATE_PATH = os.environ["NOTICE_MAIL_TITLE_TEMPLATE_PATH"] +NOTICE_MAIL_BODY_TEMPLATE_PATH = os.environ["NOTICE_MAIL_BODY_TEMPLATE_PATH"] +MBJ_SAP_NOTICE_TOPIC = os.environ["MBJ_SAP_NOTICE_TOPIC"] +MAIL_BODY_REPLACE_SYMBOL = os.environ["MAIL_BODY_REPLACE_SYMBOL"] +NDS_NOTICE_TOPIC = os.environ["NDS_NOTICE_TOPIC"] +NDS_NOTICE_TITLE = os.environ["NDS_NOTICE_TITLE"] + +# 定数 +ROW_COMMENT_SYMBOL = '#' + +# 変数 +s3_client = boto3.client('s3') +s3_resource = boto3.resource('s3') +sns_client = boto3.client('sns') +mail_msg = '' + + +def lambda_handler(event, context): + try: + # ① 処理開始ログを出力する + info_log('I-01-01', '処理開始 SAP_finデータ受領チェック処理(日次)') + today = datetime.date.today().strftime('%Y/%m/%d') + info_log('I-01-02', f'処理稼働日:{today}') + + # ② 営業日チェック処理を行う + info_log('I-02-01', '営業日チェック処理開始') + + # 1.設定ファイル[非営業日設定ファイル]を読み込む + try: + info_log('I-02-02', f'非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}') + non_business_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, NON_BUSINESS_DAY_LIST_PATH) + non_business_day_response = non_business_day_obj.get() + info_log('I-02-03', '非営業日設定ファイルを読み込みました') + except Exception as e: + error_log('E-02-01', '非営業日設定ファイルの読み込みに失敗しました') + error_process('E-02-01', e) + + # 2.処理稼働日が「1」で読み込んだ「非営業日設定ファイル」に存在するか確認する + try: + today = datetime.date.today() + info_log('I-02-04', f'本日が非営業日かチェックします チェック日:{today}') + non_date_list = [] + for i, row in enumerate(io.TextIOWrapper(io.BytesIO(non_business_day_response["Body"].read()), encoding='utf-8'), 1): + if row[0] == ROW_COMMENT_SYMBOL: + continue + date = row.strip('/') + non_date = datetime.date(date[0], date[1], date[2]) + non_date_list.append(non_date) + if today in non_date_list: + info_log('I-02-05', '本日は非営業日のため、チェック処理をスキップします') + sys.exit() + else: + info_log('I-02-06', '本日は営業日のため、チェック処理を実施します') + except Exception as e: + error_log('E-02-02', f'メルク社非営業日設定ファイルに不備があります 行数:{i}') + error_process('E-02-02', e) + + # ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル(日次)]を読み込む + try: + info_log('I-03-01', f'日次I/Fファイルネーム設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}') + receive_daily_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_DAILY_FILE_NAME_LIST_PATH) + receive_daily_file_name_response = receive_daily_file_name_obj.get() + info_log('I-03-02', '日次I/Fファイルネーム設定ファイルを読み込みました') + except Exception as e: + error_log('E-03-01', '日次I/Fファイルネーム設定ファイルの読み込みに失敗しました') + error_process('E-03-01', e) + + # ④ 日次チェック処理を行う + info_log('I-04-01', '日次チェック処理開始') + + # 1.オブジェクトリストを取得する + info_log('I-04-02', f'オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{today}/') + object_prefix = f'{today.strftime("%Y")}/{today.strftime("%m")}/{today.strftime("%d")}/' + object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix) + + # 2.日次I/Fファイルチェック処理 + info_log('I-04-03', '日次I/Fファイルチェック処理開始') + info_log('I-04-04', '取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します') + row_count = 0 + match_count = 0 + for i, row in enumerate(io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8'), 1): + row_count = i + file_exsit = False + for object in object_list: + object_key = object.key.rsplit('/', 1) + file_name = object_key[-1] + match_result = re.fullmatch(row[0], file_name) + if match_result is not None: + file_exsit = True + break + if file_exsit == True: + match_count += 1 + info_log('I-04-05', f'日次I/Fファイルの受領を確認しました ファイル名:{file_name}') + else: + error_log('E-04-01', f'日次I/Fファイルに不足があります ファイル名:{file_name}') + mail_msg = f'  {row[1]}\n' + if row_count == match_count: + info_log('I-04-06', '日次I/Fファイルは全て受領していることを確認しました') + + # ⑤ メール通知本文に出力内容が存在するか確認する + info_log('I-05-01', 'メール送信処理開始') + + if len(mail_msg) > 0: + # 1.存在した場合 + info_log('I-05-02', f'{today} 日次I/Fファイルは全て受領しているため、メール送信処理を開始します') + + try: + info_log('I-05-03', f'通知メール(タイトル)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NOTICE_MAIL_TITLE_TEMPLATE_PATH}') + mail_title_obj = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NOTICE_MAIL_TITLE_TEMPLATE_PATH) + mail_title = mail_title_obj['Body'].read().decode('utf-8') + info_log('I-05-04', '通知メール(タイトル)テンプレートファイルを読み込みました') + except Exception as e: + error_log('E-05-01', '通知メール(タイトル)テンプレートファイルの読み込みに失敗しました') + error_process('E-05-01', e) + + try: + info_log('I-05-05', f'通知メール(本文)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NOTICE_MAIL_BODY_TEMPLATE_PATH}') + mail_body_obj = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NOTICE_MAIL_BODY_TEMPLATE_PATH) + mail_body_response = mail_body_obj['Body'].read().decode('utf-8') + mail_body = mail_body_response.replace(MAIL_BODY_REPLACE_SYMBOL, mail_msg) + info_log('I-05-06', '通知メール(本文)テンプレートファイルを読み込みました') + except Exception as e: + error_log('E-05-02', '通知メール(本文)テンプレートファイルの読み込みに失敗しました') + error_process('E-05-02', e) + + info_log('I-05-07', f'メール送信指示をします 送信先トピック:{MBJ_SAP_NOTICE_TOPIC}') + params = { + 'TopicArn': MBJ_SAP_NOTICE_TOPIC, + 'Subject': mail_title, + 'Message': mail_body + } + sns_client.publish(**params) + info_log('I-05-08', 'メール送信指示をしました') + else: + # 2.存在しない場合 + info_log('I-05-09', f'{today} 日次I/Fファイルに不足がなかったため、メール送信処理をスキップします') + + # ⑥ 処理終了ログを出力する + info_log('I-06-01', '処理終了 SAP_finデータ受領チェック処理(日次)') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def info_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info {log_id} {msg}') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error {log_id} {msg}') + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_process(error_log_id, exception): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-01 エラー処理開始') + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-02 処理異常通知の送信指示をしました 通知先トピック:{NDS_NOTICE_TOPIC}') + error_msg = f'{error_log_id} のエラーが発生しました。ご確認ください\n詳細:{exception}' + params = { + 'TopicArn': NDS_NOTICE_TOPIC, + 'Subject': NDS_NOTICE_TITLE, + 'Message': error_msg + } + sns_client.publish(**params) + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-03 エラー終了 処理を中断します') + sys.exit() + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + sys.exit() diff --git a/lambda/mbj-newdwh2021-staging-lambda-sap-sup-receive-check-daily.py b/lambda/mbj-newdwh2021-staging-lambda-sap-sup-receive-check-daily.py new file mode 100644 index 00000000..3067d65c --- /dev/null +++ b/lambda/mbj-newdwh2021-staging-lambda-sap-sup-receive-check-daily.py @@ -0,0 +1,190 @@ +import os +import datetime +import boto3 +import io +import re +import sys + +# 環境変数 +CHECK_BUCKET_NAME = os.environ["CHECK_BUCKET_NAME"] +CONFIG_BUCKET_NAME = os.environ["CONFIG_BUCKET_NAME"] +RECEIVE_DAILY_FILE_NAME_LIST_PATH = os.environ["RECEIVE_DAILY_FILE_NAME_LIST_PATH"] +NON_BUSINESS_DAY_LIST_PATH = os.environ["NON_BUSINESS_DAY_LIST_PATH"] +NOTICE_MAIL_TITLE_TEMPLATE_PATH = os.environ["NOTICE_MAIL_TITLE_TEMPLATE_PATH"] +NOTICE_MAIL_BODY_TEMPLATE_PATH = os.environ["NOTICE_MAIL_BODY_TEMPLATE_PATH"] +MBJ_SAP_NOTICE_TOPIC = os.environ["MBJ_SAP_NOTICE_TOPIC"] +MAIL_BODY_REPLACE_SYMBOL = os.environ["MAIL_BODY_REPLACE_SYMBOL"] +NDS_NOTICE_TOPIC = os.environ["NDS_NOTICE_TOPIC"] +NDS_NOTICE_TITLE = os.environ["NDS_NOTICE_TITLE"] + +# 定数 +ROW_COMMENT_SYMBOL = '#' + +# 変数 +s3_client = boto3.client('s3') +s3_resource = boto3.resource('s3') +sns_client = boto3.client('sns') +mail_msg = '' + + +def lambda_handler(event, context): + try: + # ① 処理開始ログを出力する + info_log('I-01-01', '処理開始 SAP_supデータ受領チェック処理(日次)') + today = datetime.date.today().strftime('%Y/%m/%d') + info_log('I-01-02', f'処理稼働日:{today}') + + # ② 営業日チェック処理を行う + info_log('I-02-01', '営業日チェック処理開始') + + # 1.設定ファイル[非営業日設定ファイル]を読み込む + try: + info_log('I-02-02', f'非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}') + non_business_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, NON_BUSINESS_DAY_LIST_PATH) + non_business_day_response = non_business_day_obj.get() + info_log('I-02-03', '非営業日設定ファイルを読み込みました') + except Exception as e: + error_log('E-02-01', '非営業日設定ファイルの読み込みに失敗しました') + error_process('E-02-01', e) + + # 2.処理稼働日が「1」で読み込んだ「非営業日設定ファイル」に存在するか確認する + try: + today = datetime.date.today() + info_log('I-02-04', f'本日が非営業日かチェックします チェック日:{today}') + non_date_list = [] + for i, row in enumerate(io.TextIOWrapper(io.BytesIO(non_business_day_response["Body"].read()), encoding='utf-8'), 1): + if row[0] == ROW_COMMENT_SYMBOL: + continue + date = row.strip('/') + non_date = datetime.date(date[0], date[1], date[2]) + non_date_list.append(non_date) + if today in non_date_list: + info_log('I-02-05', '本日は非営業日のため、チェック処理をスキップします') + sys.exit() + else: + info_log('I-02-06', '本日は営業日のため、チェック処理を実施します') + except Exception as e: + error_log('E-02-02', f'メルク社非営業日設定ファイルに不備があります 行数:{i}') + error_process('E-02-02', e) + + # ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル(日次)]を読み込む + try: + info_log('I-03-01', f'日次I/Fファイルネーム設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}') + receive_daily_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_DAILY_FILE_NAME_LIST_PATH) + receive_daily_file_name_response = receive_daily_file_name_obj.get() + info_log('I-03-02', '日次I/Fファイルネーム設定ファイルを読み込みました') + except Exception as e: + error_log('E-03-01', '日次I/Fファイルネーム設定ファイルの読み込みに失敗しました') + error_process('E-03-01', e) + + # ④ 日次チェック処理を行う + info_log('I-04-01', '日次チェック処理開始') + + # 1.オブジェクトリストを取得する + info_log('I-04-02', f'オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{today}/') + object_prefix = f'{today.strftime("%Y")}/{today.strftime("%m")}/{today.strftime("%d")}/' + object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix) + + # 2.日次I/Fファイルチェック処理 + info_log('I-04-03', '日次I/Fファイルチェック処理開始') + info_log('I-04-04', '取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します') + row_count = 0 + match_count = 0 + for i, row in enumerate(io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8'), 1): + row_count = i + file_exsit = False + for object in object_list: + object_key = object.key.rsplit('/', 1) + file_name = object_key[-1] + match_result = re.fullmatch(row[0], file_name) + if match_result is not None: + file_exsit = True + break + if file_exsit == True: + match_count += 1 + info_log('I-04-05', f'日次I/Fファイルの受領を確認しました ファイル名:{file_name}') + else: + error_log('E-04-01', f'日次I/Fファイルに不足があります ファイル名:{file_name}') + mail_msg = f'  {row[1]}\n' + if row_count == match_count: + info_log('I-04-06', '日次I/Fファイルは全て受領していることを確認しました') + + # ⑤ メール通知本文に出力内容が存在するか確認する + info_log('I-05-01', 'メール送信処理開始') + + if len(mail_msg) > 0: + # 1.存在した場合 + info_log('I-05-02', f'{today} 日次I/Fファイルは全て受領しているため、メール送信処理を開始します') + + try: + info_log('I-05-03', f'通知メール(タイトル)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NOTICE_MAIL_TITLE_TEMPLATE_PATH}') + mail_title_obj = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NOTICE_MAIL_TITLE_TEMPLATE_PATH) + mail_title = mail_title_obj['Body'].read().decode('utf-8') + info_log('I-05-04', '通知メール(タイトル)テンプレートファイルを読み込みました') + except Exception as e: + error_log('E-05-01', '通知メール(タイトル)テンプレートファイルの読み込みに失敗しました') + error_process('E-05-01', e) + + try: + info_log('I-05-05', f'通知メール(本文)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NOTICE_MAIL_BODY_TEMPLATE_PATH}') + mail_body_obj = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NOTICE_MAIL_BODY_TEMPLATE_PATH) + mail_body_response = mail_body_obj['Body'].read().decode('utf-8') + mail_body = mail_body_response.replace(MAIL_BODY_REPLACE_SYMBOL, mail_msg) + info_log('I-05-06', '通知メール(本文)テンプレートファイルを読み込みました') + except Exception as e: + error_log('E-05-02', '通知メール(本文)テンプレートファイルの読み込みに失敗しました') + error_process('E-05-02', e) + + info_log('I-05-07', f'メール送信指示をします 送信先トピック:{MBJ_SAP_NOTICE_TOPIC}') + params = { + 'TopicArn': MBJ_SAP_NOTICE_TOPIC, + 'Subject': mail_title, + 'Message': mail_body + } + sns_client.publish(**params) + info_log('I-05-08', 'メール送信指示をしました') + else: + # 2.存在しない場合 + info_log('I-05-09', f'{today} 日次I/Fファイルに不足がなかったため、メール送信処理をスキップします') + + # ⑥ 処理終了ログを出力する + info_log('I-06-01', '処理終了 SAP_supデータ受領チェック処理(日次)') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def info_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info {log_id} {msg}') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error {log_id} {msg}') + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_process(error_log_id, exception): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-01 エラー処理開始') + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-02 処理異常通知の送信指示をしました 通知先トピック:{NDS_NOTICE_TOPIC}') + error_msg = f'{error_log_id} のエラーが発生しました。ご確認ください\n詳細:{exception}' + params = { + 'TopicArn': NDS_NOTICE_TOPIC, + 'Subject': NDS_NOTICE_TITLE, + 'Message': error_msg + } + sns_client.publish(**params) + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-03 エラー終了 処理を中断します') + sys.exit() + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + sys.exit()