148 lines
7.6 KiB
Python
148 lines
7.6 KiB
Python
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
|