newdwh2021/ecs/crm-datafetch/src/fetch_crm_data_process.py

148 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from requests.exceptions import ConnectTimeout, ReadTimeout
from tenacity import retry, stop_after_attempt
from tenacity.wait import wait_exponential
from src.config.objects import LastFetchDatetime, TargetObject
from src.error.exceptions import SalesforceAPIException
from src.salesforce.salesforce_api import SalesforceApiClient
from src.salesforce.soql_builder import SOQLBuilder
from src.system_var.constants import FETCH_JP_NAME
from src.system_var.environments import (
CRM_AUTH_TIMEOUT, CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT,
CRM_FETCH_RECORD_RETRY_INTERVAL, CRM_FETCH_RECORD_RETRY_MAX_INTERVAL,
CRM_FETCH_RECORD_RETRY_MIN_INTERVAL, CRM_FETCH_RECORD_TIMEOUT,
CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT,
CRM_GET_RECORD_COUNT_RETRY_INTERVAL,
CRM_GET_RECORD_COUNT_RETRY_MAX_INTERVAL,
CRM_GET_RECORD_COUNT_RETRY_MIN_INTERVAL, CRM_GET_RECORD_COUNT_TIMEOUT)
from src.util.counter_object import CounterObject
from src.util.logger import logger_instance as logger
def fetch_crm_data_process(target_object: TargetObject, last_fetch_datetime: LastFetchDatetime):
"""CRMデータ取得処理
Args:
target_object (TargetObject): 取得対象オブジェクト情報インスタンス
last_fetch_datetime (LastFetchDatetime): データ取得期間設定インスタンス
Raises:
SalesforceAPIException: SalesforceのAPI実行失敗が発生した場合
Returns:
crm_data_response: Salesforceオブジェクトデータ
"""
# ① CRMデータ取得処理開始ログを出力する
logger.info(
f'I-FETCH-01 [{target_object.object_name}] のCRMからのデータ取得処理を開始します')
target_object_name = target_object.object_name
# リトライ回数判定用のカウンタオブジェクトを生成
# @retryデコレータを利用した関数のリトライ処理で、基本データ型だとリトライ回数をカウントすることができないため、オブジェクト化する
count_counter = CounterObject(1)
data_counter = CounterObject(1)
try:
# ② 取得対象オブジェクトの取得期間内のレコード件数を取得する
logger.info(f'I-FETCH-02 [{target_object_name}] の件数取得を開始します')
soql_builder = SOQLBuilder(target_object, last_fetch_datetime)
count_soql = soql_builder.create_count_soql()
record_count = fetch_record_count_retry(count_soql, target_object_name, count_counter)
logger.info(f'I-FETCH-03 [{target_object_name}] の件数:[{record_count}]')
except Exception as e:
raise SalesforceAPIException(
'E-FETCH-01', FETCH_JP_NAME, f'[{target_object_name}] の件数取得に失敗しました エラー内容:[{e}]')
try:
# ③ 取得対象オブジェクトのレコードを取得する
logger.info(f'I-FETCH-04 [{target_object_name}] のレコード取得を開始します')
fetch_soql = soql_builder.create_fetch_soql()
crm_data_response = fetch_sf_data_retry(fetch_soql, target_object_name, data_counter)
logger.info(f'I-FETCH-05 [{target_object_name}] のレコード取得が成功しました')
except Exception as e:
raise SalesforceAPIException(
'E-FETCH-02', FETCH_JP_NAME, f'[{target_object_name}] のレコード取得に失敗しました エラー内容:[{e}]')
# ④ CRMデータ取得処理終了ログを出力する
logger.info(f'I-FETCH-06 [{target_object_name}] のCRMからのデータ取得処理を終了します')
# ⑤ 次の処理へ移行する
return crm_data_response
@retry(
wait=wait_exponential(multiplier=CRM_GET_RECORD_COUNT_RETRY_INTERVAL,
min=CRM_GET_RECORD_COUNT_RETRY_MIN_INTERVAL, max=CRM_GET_RECORD_COUNT_RETRY_MAX_INTERVAL),
stop=stop_after_attempt(CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT))
def fetch_record_count_retry(soql: str, target_object_name: str, count_counter: CounterObject):
try:
salesforce_api_client = SalesforceApiClient()
return salesforce_api_client.fetch_sf_count(soql)
except ConnectTimeout as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if count_counter.describe() < CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT:
count_counter.increment(1)
logger.warning(f'W-FETCH-01 CRMの接続処理がタイムアウトしため、リトライします[{CRM_AUTH_TIMEOUT}] エラー内容:[{e}]')
raise e
except ReadTimeout as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if count_counter.describe() < CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT:
count_counter.increment(1)
logger.warning(
f'W-FETCH-02 [{target_object_name}] の件数取得処理がタイムアウトしたため、リトライします:[{CRM_GET_RECORD_COUNT_TIMEOUT}] エラー内容:[{e}]')
raise e
except Exception as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if count_counter.describe() < CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT:
count_counter.increment(1)
logger.warning(
f'W-FETCH-03 [{target_object_name}] の件数取得に失敗したため、リトライします エラー内容:[{e}]')
raise e
@retry(
wait=wait_exponential(multiplier=CRM_FETCH_RECORD_RETRY_INTERVAL,
min=CRM_FETCH_RECORD_RETRY_MIN_INTERVAL, max=CRM_FETCH_RECORD_RETRY_MAX_INTERVAL),
stop=stop_after_attempt(CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT))
def fetch_sf_data_retry(soql: str, target_object_name: str, data_counter: CounterObject):
try:
salesforce_api_client = SalesforceApiClient()
return salesforce_api_client.fetch_sf_data(soql)
except ConnectTimeout as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if data_counter.describe() < CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT:
data_counter.increment(1)
logger.warning(f'W-FETCH-04 CRMの接続処理がタイムアウトしため、リトライします[{CRM_AUTH_TIMEOUT}] エラー内容:[{e}]')
raise e
except ReadTimeout as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if data_counter.describe() < CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT:
data_counter.increment(1)
logger.warning(
f'W-FETCH-05 [{target_object_name}] のレコード取得処理がタイムアウトしたため、リトライします:[{CRM_FETCH_RECORD_TIMEOUT}] エラー内容:[{e}]')
raise e
except Exception as e:
# 「リトライします」のメッセージ出力後、リトライせず例外終了になってしまうことを防ぐため、カウンタによる回数の判定を行う
if data_counter.describe() < CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT:
data_counter.increment(1)
logger.warning(
f'W-FETCH-06 [{target_object_name}] のレコード取得に失敗したため、リトライします エラー内容:[{e}]')
raise e