기능 개발
데이터를 처리하려면 변형 함수, 로드 함수 및 콜백 함수의 세 가지 독립 코드 단위가 필요합니다.
이러한 함수는 Oracle Functions를 사용하여 구현되고 Python으로 작성되었습니다. Oracle Functions는 데이터 로드가 제한된 빈도(시간당 한 번 또는 두 번 또는 하루에 한 번)로 발생하는 것일 수 있으므로 이 작업에 완벽하게 적합합니다. Oracle Functions 사용이 유리한 이유는 수행할 작업이 있는 경우에만 함수가 호출되고 처리를 완료한 후에 종료되기 때문입니다. 또한 유지 관리할 운영 체제, 경로 지정 또는 기타 서버가 없습니다. 서버리스 구조입니다. 이 예제 구현에서는 쉽게 이해하고 확장할 수 있으므로 다른 언어 옵션보다 Python을 선택했습니다. 이 데이터 로드 작업에 대해 엄격한 성능 요구 사항이 없습니다.
세 가지 기능은 다음과 같습니다.
- 단순화된 JSON 형식의 데이터 파일을 Oracle Cloud ERP 특정 Zip 파일로 변환하는 변환 함수입니다.
- 파일을 Oracle Cloud ERP로 로드하는 로드 함수
- Oracle Fusion의 응답을 처리하기 위한 콜백 함수
이러한 각 기능은 OCI 스토리지 버킷에서 데이터를 소싱하고 처리한 후 다른 버킷에 배치합니다.
OCI 스토리지 버킷 사용
로드할 변환된 데이터는 이 JSON 파일과 유사합니다.
"invoices": [
{
"invoiceId": "222290",
"businessUnit": "US1 Business Unit",
"source": "External",
"invoiceNumber": "111190",
"invoiceAmount": "4242.00",
"invoiceDate" : "2019/02/01",
"supplierName": "Staffing Services",
"supplierNumber" : 1253,
"supplierSite" : "Staffing US1",
"invoiceCurrency": "USD",
"paymentCurrency": "USD",
"description" : "New Invoice from global Angels",
"importSet": "AP_Cloud_Demo",
"invoiceType": "STANDARD",
"paymentTerms": "Immediate",
"termsDate": "2019/02/01",
"accountingDate": "2019/02/01",
"paymentMethod": "CHECK",
"invoiceLines": [
{
"amount": "200",
"description" : "Invoice Line Description"
},
{
"amount": "300",
"description" : "Invoice Line Description2",
"invoiceQuantity": "10",
"unitPrice": "5"
}]
}]
CSV 발췌 내용과 유사한 두 개의 CSV 파일로 구성된 기본 Oracle Cloud ERP 형식 FBDI 임포트 zip보다 훨씬 간단합니다.
222284,US1 Business Unit,External,111184,4242.00,2019/02/01,Staffing
Services,1253,Staffing US1,USD,USD,New Invoice from global
Angels,AP_Cloud_Demo,STANDARD,,,,,,Immediate,2019/02/01,,,2019/02/01,CHECK,Standard,#NULL,,,,,,,,,,,#NULL,,,,,#NULL,#NULL,,,,21,#NULL,,,#NULL,#NULL,,,,#NULL,,,,,,,,,,,,,,,N,N,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,END
222284,1,ITEM,200,,,,Invoice Line
Description,,,,,,,,,,,,,N,,#NULL,2019/02/01,,,,,#NULL,,,,,,,,,,,,,,,,,#NULL,,,N,1,,,N,,,,,,,N,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,END
이 솔루션의 나머지 부분에서는 또한 파일을 처리하는 동안 저장할 추가 버킷을 사용합니다. 프로세스가 진행되면 파일이 다음 버킷으로 이동합니다. 파일이 Oracle Cloud ERP로 로드되는 즉시 파일 이름이 바뀌어 ERP 데이터 로드 JOBID가 포함됩니다.
그림 load-data-serverless-overview.png에 대한 설명
변환 함수 생성
이 작업을 수동으로 수행할 때는 일반적으로 zip 파일을 채우고 생성할 수 있는 Excel 매크로 파일을 다운로드해야 합니다. 자세한 내용은 링크를 참조하십시오. 대신 일부 Python 코드를 실행하는 함수를 사용하여 변환을 수행할 수 있습니다.
변환 함수는 수신 JSON 버킷에서 JSON 데이터를 가져와서 코드를 사용하여 CSV로 변환하고 압축을 푼 다음 수신 ZIP 버킷에 저장합니다. 변환 함수는 템플리트 접근 방식을 사용하여 CSV 파일을 생성합니다. OCI 파일과의 상호 작용은 간단합니다. 객체를 배치 및 삭제할 수 있으며 대용량 파일을 복사해야 하는 경우에는 이 파일을 비동기적으로 실행할 수 있습니다. 이 예에서는 작은 파일을 사용하므로 여기에 비동기 복사가 사용되지 않습니다.
put_object_response = object_storage_client.put_object(namespace, param_processing_bucket_name, data_file_name + "_ERPJOBID_" + erp_job_id, data_file.data.content)
로드 함수 생성
Oracle Cloud ERP로 데이터를 간편하게 로드할 수 있습니다. 이 예에서는 표준 importBulkData
REST API를 사용합니다.
오픈 소스 requests
REST API를 사용하여 데이터를 로드하는 방법을 보여주는 코드 조각은 다음과 같습니다.
erp_payload = {
"OperationName": "importBulkData",
"DocumentContent": base64_encoded_file,
"ContentType": "zip",
"FileName": data_file_name,
"JobName": jobname,
"ParameterList": paramlist,
"CallbackURL": param_fa_callback_url,
"NotificationCode": "10"
}
logging.info(f'Sending file to erp with payload {erp_payload}')
result = requests.post(
url=param_erp_url,
auth=param_erp_auth,
headers={"Content-Type": JSON_CONTENT_TYPE},
json=erp_payload
)
if result.status_code != 201:
message = "Error " + str(result.status_code) + " occurred during upload. Message=" + str(result.content)
raise FA_REST_Exception("Error " + message)
이벤트를 사용하여 객체 연결 정보
파일이 Oracle Cloud Infrastructure Object Storage 버킷에 업로드되면 CRUD 작업을 수행할 때 이벤트를 내보내도록 버킷을 구성할 수 있습니다. 이 이벤트는 Oracle Cloud Infrastructure Events 서비스에서 캡처할 수 있습니다.
객체 이벤트를 기반으로 하는 규칙 생성은 선언적입니다. 예를 들어, "INCOMING_JSON
라는 버킷에 새 파일이 생성된 경우 erp-transform
serverless 함수를 호출"과 같은 논리를 구현하는 규칙을 생성할 수 있습니다. 버킷 정보 탭의 기능 섹션에서 옵션으로 객체 이벤트 제출 버킷을 구성할 수 있습니다.
다음은 인바운드 JSON 버킷에서 내보낸 오브젝트 스토리지 이벤트를 기반으로 하는 규칙의 예입니다.
이벤트를 사용하면 스토리지 버킷(또는 기타 객체)에 발생하는 작업을 처리용 함수 호출에 연결할 수 있습니다. 이벤트 기반 기능을 사용하면 완전히 분리된 방식으로 이벤트에 의해 트리거되는 일련의 작업을 생성할 수 있습니다.
이 이미지는 이벤트가 구현된 새 운영 플로우를 보여줍니다.
각 버킷은 이벤트를 내보내도록 표시되었으며 이벤트 서비스는 이 이벤트를 캡처하고 적절한 Oracle 함수를 호출합니다. 함수를 호출할 때 이벤트 서비스는 다시 함수를 호출하는 이벤트 페이로드를 전달합니다. 이벤트 페이로드 내에는 내보낸 이벤트의 유형이 있으며, 이 경우 버킷 및 파일 이름도 포함됩니다.
Oracle Vault를 사용하여 암호 보안
LoadToSaaS
함수는 Oracle Cloud ERP로 인증할 수 있어야 합니다. 인증하려면 통합 사용자에 대한 사용자 이름과 비밀번호가 필요합니다. Oracle Cloud Infrastructure Vault 서비스는 암호화된 암호를 저장할 수 있는 안전한 장소를 제공합니다.
유저 이름을 Functions Configuration 변수로 저장할 수 있지만 이 변수에 암호를 저장하는 것은 안전하지 않습니다. Oracle OCI는 이상적인 솔루션으로 Oracle Cloud Infrastructure Vault를 제공합니다. 코드 내에서 저장소를 질의하고 암호를 추출할 수 있습니다. 검색한 후에는 이 암호를 사용하여 Oracle Cloud ERP에 대한 인증된 REST 호출을 실행할 수 있습니다. 이 보안 키의 OCID는 업데이트해도 변경되지 않으므로 솔루션을 중단하지 않고 비밀번호를 안전하게 업데이트할 수 있습니다.
Vault Details 화면의 Resources에서 Secrets를 선택하여 새 암호를 만듭니다.
다음 예제 Python 코드를 사용하여 암호를 추출할 수 있습니다.
signer = oci.auth.signers.get_resource_principals_signer()
secret_client = oci.secrets.SecretsClient(config={}, signer=signer)
secret_response = secret_client.get_secret_bundle("ocid1.vaultsecret.oc1.phx.xxxxxxxx")
base64_secret_bytes = secret_response.data.secret_bundle_content.content.encode('ascii')
base64_message_bytes = base64.b64decode(base64_secret_bytes)
print("secret value is " + base64_message_bytes.decode('ascii'))
콜백 함수 생성
데이터가 Oracle Fusion Applications로 로드되면 클라이언트에 대한 콜백이 상태 페이로드와 함께 전송됩니다. 이 정보를 수신하는 콜백 함수를 생성할 수 있습니다.
데이터가 Oracle Cloud ERP로 로드되면 서비스는 다음(간소화된) 단계를 수행합니다.
- 데이터가 Fusion UCM 저장소에 로드됩니다.
- ESS 작업은 파일 콘텐츠를 ERP 통합 테이블로 이전합니다.
- ESS 작업은 데이터를 트랜잭션 테이블로 임포트합니다.
- UCM 저장소에서 삽입된 행을 보여주는 보고서가 생성됩니다.
- 클라이언트에 대한 콜백이 상태 페이로드와 함께 전송됩니다.
이 예제 솔루션에서 호출되는 최종 함수는 클라이언트측을 구현하거나 Oracle Cloud ERP에서 이 콜백의 수신측을 구현하는 함수입니다. 콜백은 XML 데이터가 있는 HTTP 호출입니다. Oracle Functions는 REST 엔드포인트가 아니므로 Oracle Cloud ERP에서 GET HTTP 호출을 수신하려면 API Gateway로 함수를 프론트 엔드해야 합니다.
이전과 마찬가지로 끝점 및 리소스 URL을 함수에 매핑하는 작업을 수행하는 선언적 작업입니다. 배치 생성(또는 편집) 마법사의 경로 지정 단계에 경로 정보를 입력합니다. 이 이미지는 다음 예를 보여줍니다.
이 erp-callback
함수는 Oracle Cloud ERP가 콜백을 발행할 때 트리거됩니다. 이 함수는 XML 페이로드를 디코딩하고 JOBID 및 Status를 추출합니다. JOBID를 사용하여 이벤트가 발생한 처리 버킷의 파일을 확인한 다음 처리 버킷의 파일을 성공 또는 오류 버킷으로 이동할 수 있습니다. 중요한 것은 ERP 콜백에서 성공한 작업은 데이터가 Oracle Cloud ERP로 로드되었음을 의미하지는 않습니다. 이는 중복 데이터, 알 수 없는 비즈니스 조직 등일 수 있습니다. 여기에서 설명한 패턴에 대해 구현할 수 있는 한 가지 향상된 기능은 이 콜백 함수가 UCM에서 보고서를 다운로드하여 모든 행이 성공적으로 삽입되었는지 여부를 확인하는 것입니다.
통지에 가입하여 솔루션 확장
Oracle Cloud Infrastructure Notifications 서비스를 사용하면 메시지를 게시할 수 있는 항목을 생성할 수 있습니다. 이 항목에는 메시지를 수신한 후 다른 곳으로 보내는 가입자가 있을 수 있습니다.
플로우가 완료되면 OCI와의 통합에 따른 이점을 활용할 수 있습니다. 플로우는 마이크로 서비스로 설계되었으며 이벤트와 같은 네이티브 서비스를 사용하고 있으므로 Oracle Cloud Infrastructure Notifications와 같은 추가 기능 및 서비스를 활용할 수 있습니다. 이 샘플 코드에서 통지는 전자 메일이지만 가입자는 다른 함수, PagerDuty 채널 또는 기타 메커니즘일 수 있습니다. 느슨하게 결합된 아키텍처는 다양한 방식으로 확장될 수 있습니다. 예를 들어, Grafana 대시보드에 데이터를 삽입하는 함수를 추가할 수 있으며, 통지에서 Grafana에 표시할 일부 데이터를 사용하여 이 함수를 호출할 수 있습니다.
예를 들어, 다음은 OCID를 사용하여 항목에 통지를 보내는 방법을 보여주는 helper 함수의 코드 조각입니다.
def publish_ons_notification(topic_id, msg_title, msg_body):
try:
signer = oci.auth.signers.get_resource_principals_signer()
logging.info("Publish notification, topic id" + topic_id)
client = oci.ons.NotificationDataPlaneClient({}, signer=signer)
msg = oci.ons.models.MessageDetails(title=msg_title, body=msg_body)
client.publish_message(topic_id, msg)
except oci.exceptions.ServiceError as serr:
logging.critical(f'Exception sending notification {0} to OCI, is the OCID of the notification correct? {serr}')
except Exception as err:
logging.critical(f'Unknown exception occurred when sending notification, please see log {err}')