feat: 設計に合わせて実装修正
This commit is contained in:
parent
8397998bb3
commit
bc29d22526
@ -8,13 +8,14 @@ import pyzipper
|
|||||||
from pyzipper.zipfile import BadZipFile
|
from pyzipper.zipfile import BadZipFile
|
||||||
|
|
||||||
# 環境変数
|
# 環境変数
|
||||||
# mbj-newdwh2021-staging-data
|
|
||||||
DATA_IMPORT_BUCKET = os.environ["DATA_IMPORT_BUCKET"]
|
DATA_IMPORT_BUCKET = os.environ["DATA_IMPORT_BUCKET"]
|
||||||
# mbj-newdwh2021-staging-backup-medpass
|
HCP_WEB_TARGET_FOLDER = os.environ["HCP_WEB_TARGET_FOLDER"]
|
||||||
MEDPASS_BACKUP_BUCKET = os.environ["MEDPASS_BACKUP_BUCKET"]
|
HCP_WEB_BACKUP_BUCKET = os.environ["HCP_WEB_BACKUP_BUCKET"]
|
||||||
MEDPASS_TARGET_FOLDER = os.environ["MEDPASS_TARGET_FOLDER"] # medpass/target
|
BACKUP_ZIPFILE_FOLDER = os.environ["BACKUP_ZIPFILE_FOLDER"]
|
||||||
# /staging/s3/medpassZipExtractPassword
|
BACKUP_DATA_IMPORT_FOLDER = os.environ["BACKUP_DATA_IMPORT_FOLDER"]
|
||||||
|
DATA_IMPORT_FILENAME = os.environ["DATA_IMPORT_FILENAME"]
|
||||||
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY = os.environ["MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY"]
|
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY = os.environ["MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY"]
|
||||||
|
|
||||||
LOG_LEVEL = os.environ["LOG_LEVEL"]
|
LOG_LEVEL = os.environ["LOG_LEVEL"]
|
||||||
TZ = os.environ["TZ"]
|
TZ = os.environ["TZ"]
|
||||||
|
|
||||||
@ -55,13 +56,15 @@ if not isinstance(level, int):
|
|||||||
logger.setLevel(level)
|
logger.setLevel(level)
|
||||||
|
|
||||||
|
|
||||||
def extract_zip_with_password(zip_filepath: str, extract_to_folder: str, password: str):
|
def extract_zip_with_password(zip_filepath: str, extract_to_folder: str, password: str) -> os.path:
|
||||||
"""
|
"""
|
||||||
暗号化ZIPを解凍する。
|
暗号化ZIPを解凍する。
|
||||||
|
|
||||||
:param zip_filepath: ZIPファイルが保管されているフォルダパス
|
:param zip_filepath: ZIPファイルが保管されているフォルダパス
|
||||||
:param extract_to_folder: ZIPファイルの解凍先フォルダ
|
:param extract_to_folder: ZIPファイルの解凍先フォルダ
|
||||||
:param password: ZIPパスワード
|
:param password: ZIPパスワード
|
||||||
|
|
||||||
|
:return 解凍されたファイルパス
|
||||||
"""
|
"""
|
||||||
# ZIPを解凍
|
# ZIPを解凍
|
||||||
try:
|
try:
|
||||||
@ -69,40 +72,45 @@ def extract_zip_with_password(zip_filepath: str, extract_to_folder: str, passwor
|
|||||||
# ZIP内のファイルは1つのみ
|
# ZIP内のファイルは1つのみ
|
||||||
inner_filename = z.filelist[0].filename
|
inner_filename = z.filelist[0].filename
|
||||||
z.extractall(path=extract_to_folder, pwd=password.encode())
|
z.extractall(path=extract_to_folder, pwd=password.encode())
|
||||||
except BadZipFile as e:
|
|
||||||
pass
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
raise e
|
||||||
|
|
||||||
logger.info(f'解凍先フォルダ: {os.listdir("/tmp")}')
|
|
||||||
logger.info(f'解凍ファイルパス: {os.path.join(extract_to_folder, inner_filename)}')
|
|
||||||
return os.path.join(extract_to_folder, inner_filename)
|
return os.path.join(extract_to_folder, inner_filename)
|
||||||
|
|
||||||
|
|
||||||
def get_s3_event_parameter(event: dict):
|
def get_s3_event_parameter(event: dict) -> tuple[str, str, str, str]:
|
||||||
s3_event = event["Records"][0]["s3"]
|
s3_event = event["Records"][0]["s3"]
|
||||||
event_bucket_name = s3_event["bucket"]["name"]
|
event_bucket_name: str = s3_event["bucket"]["name"]
|
||||||
event_object_key = s3_event["object"]["key"]
|
event_object_key: str = s3_event["object"]["key"]
|
||||||
event_file_name = os.path.basename(event_object_key)
|
event_file_name: str = os.path.basename(event_object_key)
|
||||||
event_folder_name = os.path.dirname(event_object_key).split('/')[0]
|
event_folder_name: str = os.path.dirname(event_object_key).split('/')[0]
|
||||||
|
|
||||||
return event_bucket_name, event_object_key, event_file_name, event_folder_name
|
return event_bucket_name, event_object_key, event_file_name, event_folder_name
|
||||||
|
|
||||||
|
|
||||||
def get_ssm_params(parameter_key: str, with_decryption: bool = True):
|
def get_ssm_params(parameter_key: str, with_decryption: bool = True) -> str:
|
||||||
|
"""SSMパラメータストアから指定されたパラメータ名の値を取得する"""
|
||||||
response = ssm_client.get_parameter(
|
response = ssm_client.get_parameter(
|
||||||
Name=parameter_key, WithDecryption=with_decryption)
|
Name=parameter_key, WithDecryption=with_decryption)
|
||||||
parameter_value = response['Parameter']['Value']
|
parameter_value: str = response['Parameter']['Value']
|
||||||
return parameter_value
|
return parameter_value
|
||||||
|
|
||||||
|
|
||||||
def delete_doing_file(event_bucket_name: str, event_object_key: str):
|
def delete_doing_file(event: dict) -> None:
|
||||||
|
""".doingファイルをバケット上から削除する"""
|
||||||
|
# イベント情報を取得
|
||||||
|
(
|
||||||
|
event_bucket_name,
|
||||||
|
event_object_key,
|
||||||
|
_,
|
||||||
|
_
|
||||||
|
) = get_s3_event_parameter(event)
|
||||||
# ⑨ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
|
# ⑨ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
|
||||||
s3_client.delete_object(
|
s3_client.delete_object(
|
||||||
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
|
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
|
||||||
|
|
||||||
|
|
||||||
def handler(event, context):
|
def handler(event, context) -> None:
|
||||||
try:
|
try:
|
||||||
# ① 処理開始ログを出力する
|
# ① 処理開始ログを出力する
|
||||||
logger.info('I-01-01 処理開始 medパスデータ解凍・復号化・転送処理')
|
logger.info('I-01-01 処理開始 medパスデータ解凍・復号化・転送処理')
|
||||||
@ -141,7 +149,8 @@ def handler(event, context):
|
|||||||
logger.info('I-04-02 暗号化ZIPファイルをダウンロードしました')
|
logger.info('I-04-02 暗号化ZIPファイルをダウンロードしました')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f'E-04-01 暗号化ZIPファイルのダウンロードに失敗しました エラー内容:{e}')
|
logger.exception(f'E-04-01 暗号化ZIPファイルのダウンロードに失敗しました エラー内容:{e}')
|
||||||
raise e
|
delete_doing_file(event)
|
||||||
|
return
|
||||||
|
|
||||||
# ⑤ ZIP解凍パスワードをSSM パラメータストアから取得する
|
# ⑤ ZIP解凍パスワードをSSM パラメータストアから取得する
|
||||||
try:
|
try:
|
||||||
@ -151,54 +160,78 @@ def handler(event, context):
|
|||||||
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY)
|
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f'E-05-01 ZIP解凍パスワードの読み込みに失敗しました エラー内容:{e}')
|
logger.exception(f'E-05-01 ZIP解凍パスワードの読み込みに失敗しました エラー内容:{e}')
|
||||||
raise e
|
delete_doing_file(event)
|
||||||
|
return
|
||||||
|
|
||||||
# ⑥ ZIPファイルを解凍してローカルに保存
|
# ⑥ ZIPファイルを解凍してローカルに保存
|
||||||
try:
|
try:
|
||||||
logger.info(f'I-06-01 ZIP解凍開始')
|
logger.info(f'I-05-02 ZIP解凍開始')
|
||||||
extracted_zip_file_path = extract_zip_with_password(
|
extracted_zip_file_path = extract_zip_with_password(
|
||||||
os.path.join(PATH_TMP, event_file_name), PATH_TMP, zip_password)
|
os.path.join(PATH_TMP, event_file_name), PATH_TMP, zip_password)
|
||||||
except Exception as e:
|
except RuntimeError as e:
|
||||||
logger.exception(f'E-06-01 ZIPの解凍に失敗しました エラー内容:{e}')
|
if 'password' in str(e).lower():
|
||||||
raise e
|
# パスワードが間違っている場合のエラー
|
||||||
logger.info(f'I-06-02 ZIP解凍成功')
|
logger.exception(
|
||||||
# ⑦ バックアップS3バケットにコピー
|
f'E-05-02 ZIPのパスワードが不正のため、解凍に失敗しました エラー内容:{e}')
|
||||||
copy_source = {'Bucket': event_bucket_name, 'Key': event_object_key}
|
delete_doing_file(event)
|
||||||
execute_date_yyyymm = datetime.date.today().strftime('%Y/%m/%d')
|
return
|
||||||
|
else:
|
||||||
|
# 想定外のエラー
|
||||||
|
raise e
|
||||||
|
# ZIPファイルが壊れている場合のエラー
|
||||||
|
except BadZipFile as e:
|
||||||
|
logger.exception(f'E-05-03 ZIPの形式が不正のため、解凍に失敗しました エラー内容:{e}')
|
||||||
|
delete_doing_file(event)
|
||||||
|
return
|
||||||
|
|
||||||
|
# データ登録用にファイルをリネーム
|
||||||
|
# ZIPファイル名がyyyymmdd.zipのため、年月日部分をデータ登録用ファイル名の末尾につけ、拡張子をCSVに変更
|
||||||
|
data_import_file_name = f'{DATA_IMPORT_FILENAME}_{event_file_name.replace(ZIP_FILE_EXT, CSV_FILE_EXT)}'
|
||||||
|
logger.info(f'I-05-03 ZIP解凍成功')
|
||||||
|
|
||||||
|
# ⑥ 受信した暗号化ZIPファイルと解凍後のファイルをバックアップする
|
||||||
|
backup_copy_source = {
|
||||||
|
'Bucket': event_bucket_name, 'Key': event_object_key}
|
||||||
|
execute_date_yyyymmdd = datetime.date.today().strftime('%Y/%m/%d')
|
||||||
|
|
||||||
|
# ZIPファイルのバックアップ
|
||||||
s3_client.copy_object(
|
s3_client.copy_object(
|
||||||
Bucket=MEDPASS_BACKUP_BUCKET,
|
Bucket=HCP_WEB_BACKUP_BUCKET,
|
||||||
Key=f'{execute_date_yyyymm}/{event_file_name}',
|
Key=f'{BACKUP_ZIPFILE_FOLDER}/{execute_date_yyyymmdd}/{event_file_name}',
|
||||||
CopySource=copy_source
|
CopySource=backup_copy_source
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f'I-07-01 medパス受信データのバックアップ完了:{MEDPASS_BACKUP_BUCKET}/{execute_date_yyyymm}/{event_file_name}')
|
f'I-06-01 medパス受信データのバックアップ完了:{BACKUP_ZIPFILE_FOLDER}/{HCP_WEB_BACKUP_BUCKET}/{execute_date_yyyymmdd}/{event_file_name}')
|
||||||
|
|
||||||
# ⑧ データ登録S3バケットにアップロード
|
# 解凍後ファイルのバックアップ
|
||||||
csv_file_name = extracted_zip_file_path.split('/')[-1]
|
|
||||||
logger.info(csv_file_name)
|
|
||||||
s3_client.upload_file(
|
s3_client.upload_file(
|
||||||
extracted_zip_file_path,
|
extracted_zip_file_path,
|
||||||
|
Bucket=HCP_WEB_BACKUP_BUCKET,
|
||||||
|
Key=f'{HCP_WEB_TARGET_FOLDER}/{data_import_file_name}'
|
||||||
|
)
|
||||||
|
logger.info(
|
||||||
|
f'I-06-02 medパス解凍後データのバックアップ完了:{BACKUP_DATA_IMPORT_FOLDER}/{HCP_WEB_BACKUP_BUCKET}/{execute_date_yyyymmdd}/{data_import_file_name}')
|
||||||
|
|
||||||
|
# ⑦ 解凍後のファイルをデータ登録バケットに転送する
|
||||||
|
data_import_copy_source = {'Bucket': HCP_WEB_BACKUP_BUCKET,
|
||||||
|
'Key': f'{BACKUP_DATA_IMPORT_FOLDER}/{execute_date_yyyymmdd}/{data_import_file_name}'}
|
||||||
|
s3_client.copy_object(
|
||||||
Bucket=DATA_IMPORT_BUCKET,
|
Bucket=DATA_IMPORT_BUCKET,
|
||||||
Key=f'{MEDPASS_TARGET_FOLDER}/{csv_file_name}'
|
Key=f'{HCP_WEB_TARGET_FOLDER}/{data_import_file_name}',
|
||||||
|
CopySource=data_import_copy_source
|
||||||
)
|
)
|
||||||
|
|
||||||
# アップロード後、元のバケットからは削除する
|
# アップロード後、元のバケットからは削除する
|
||||||
s3_client.delete_object(Bucket=event_bucket_name, Key=event_object_key)
|
s3_client.delete_object(Bucket=event_bucket_name, Key=event_object_key)
|
||||||
logger.info(
|
logger.info(
|
||||||
f'I-08-01 Encise受信データの転送完了:{DATA_IMPORT_BUCKET}/{MEDPASS_TARGET_FOLDER}/{csv_file_name}')
|
f'I-07-01 medパス解凍後データの転送完了:{DATA_IMPORT_BUCKET}/{HCP_WEB_TARGET_FOLDER}/{data_import_file_name}')
|
||||||
|
|
||||||
# ⑨ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
|
# ⑧ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
|
||||||
delete_doing_file(event_bucket_name, event_object_key)
|
delete_doing_file(event)
|
||||||
|
|
||||||
logger.info('I-08-09 処理終了 Medpass受信データ転送処理')
|
logger.info('I-08-01 処理終了 medパスデータ解凍・復号化・転送処理')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f'想定外のエラーが発生しました。処理を終了します。 例外内容:{e}')
|
logger.exception(f'想定外のエラーが発生しました。処理を終了します。 例外内容:{e}')
|
||||||
(
|
delete_doing_file(event)
|
||||||
event_bucket_name,
|
|
||||||
event_object_key,
|
|
||||||
_,
|
|
||||||
_
|
|
||||||
) = get_s3_event_parameter(event)
|
|
||||||
delete_doing_file(event_bucket_name, event_object_key)
|
|
||||||
raise e
|
raise e
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user