Object StorageにCSVファイルをUploadされた際にイベント・サービスがOracle Functionsをキックし、Autonomous Databaseにロードするサンプルを動かしてみた。
Autonomous DatabaseへのロードはRESTを呼び出しSODAを使用してJSON形式で格納します。パスワードの管理にはOCIシークレットを使用し、FunctionはPythonで記載しています。
※ Oracle Functionsとは、Oracle Cloud Infrastructureで提供されるFn Projectのマネージドサービス
※ OCIシークレットとは、パスワードなどリソースにアクセスするために使用する資格情報を安全に一元的に管理できます。
作業ステップ
- Functionsの準備
- Autonomous DBの作成
- コレクションの作成
- Object Storageの準備
- 動的グループの作成とポリシーの割り当て
- シークレットの作成
- Functionsの作成
- イベント・ルールの作成
Functionsの準備
Oracle Functionsが利用できるように以下の作業を実施
- 仮想クラウド・ネットワークの作成
- IAMポリシーの作成
- (オプション) OCIレジストリの作成
- Cloud Shellを使ってOracle Functionsサンプルを動かしてみた。 を参考に fn shell のセットアップを実施。
Autonomous Databaseの作成
接続するAutonomous Databaseを作成
作成したAutonomous Databaseの[サービス・コンソール]を開き、[開発]からRESTfulサービスとSODA のBase URLをコピー
コレクションの作成
作成したAutonomousDBに対して、ロード用のコレクション(regionsnumbers)を作成します。
今回は、adminスキーマ(デフォルトでRESTアクセスが有効になっている)を使用します。
※ 本番環境では、別のスキーマを作成してRESTサービスを有効にすることを推奨
方法の詳細は、マニュアル を確認
ターミナルから、curlコマンドを発行しコレクション 'regionsnumbers' を作成します。
curl -X PUT -u 'ADMIN:<DB password>' "<ADW-ORDS-URL>admin/soda/latest/regionsnumbers“
例) curl -X PUT -u 'ADMIN:<DB password>' "https://AAAAA-ORCLATP.adb.ap-tokyo-1.oraclecloudapps.com/ords/admin/soda/latest/regionsnumbers"
Object Storage の準備
Object Storageに2つのバケットを作成
1つ目のバケットは、Autonomous DatabaseにロードするCSVファイルの配置
2つ目のバケットは、処理が完了したファイルの移動場所
例えば「input-bucket」と「processed-bucket」を作成
1つ目のバケット(入力用)の「オブジェクト・イベントの出力」ボックスにチェックを入れます。
動的グループの作成とポリシーの割り当て
Functionから他のOCIサービスが利用できるようにポリシーを割り当てる動的グループを作成します。
コンパートメント内のすべてのファンクションをマッチング・ルールに指定する動的グループの例
ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..aaaaaxxxxx'}
動的グループが 2 つのバケット内のオブジェクトを管理できるように新しいポリシーを作成
Allow dynamic-group <dynamic-group-name> to manage objects in compartment <compartment-name> where target.bucket.name=‘<input-bucket-name>’
Allow dynamic-group <dynamic-group-name> to manage objects in compartment <compartment-name> where target.bucket.name=‘<processed-bucket-name>’
シークレットを読み取れるようにポリシーを割り当て
Allow dynamic-group <dynamic-group-name> to read secret-family in compartment <compartment-name>
allow service objectstorage-<region-name> to manage object-family in compartment <compartment-name>
例)allow service objectstorage-us-ashburn-1 to manage object-family in compartment <compartment-name>
シークレットの作成
シークレット操作用のサービスレベルポリシーの割り当て
allow service VaultSecret to use vaults in tenancy
allow service VaultSecret to use keys in tenancy
Autonomous Databaseへの接続パスワードを格納するシークレット作成します。
- ボールトの作成
- キーの作成
- DBユーザのパスワードのシークレットを作成
ボールトの作成
OCI Webコンソールから[セキュリティ] > [ボールト] で「ボールトの作成」を選択
キーの作成
作成したボールトに対して「キーの作成」からキーを作成します。
DBユーザのパスワードのシークレットを作成
- 名前・説明を入力
- 暗号化キー:作成したキー
- シークレット・タイプ:プレーンテキスト
- シークレット・コンテンツ:データベースユーザのパスワード
作成したシークレットのOCIDを記録します。
Functionsの作成
すべてのファイルは Githubより取得可能です。
シークレット取得部分
import oci
import base64
import sys
def read_secret_value(secret_client, secret_id):
response = secret_client.get_secret_bundle(secret_id)
base64_Secret_content = response.data.secret_bundle_content.content
base64_secret_bytes = base64_Secret_content.encode('ascii')
base64_message_bytes = base64.b64decode(base64_secret_bytes)
secret_content = base64_message_bytes.decode('ascii')
return secret_content
Handlerでの呼び出し部分
secret_contents = read_secret_value(secret_client, secret_id)
dbpwd = format(secret_contents)
load_data(signer, namespace, input_bucket, object_name, ordsbaseurl, schema, dbuser, dbpwd)
move_object(signer, namespace, input_bucket, processed_bucket, object_name)
ファンクションに構成を追加
ORDS URL、ADBスキーマ、Object Storageバケット名、シークレットOCID
fn config function <APP NAME> <function NAME> ords-base-url https://G8HITPQLBTFUF9F-ORCLATP.adb.ap-tokyo-1.oraclecloudapps.com/ords/
fn config function <APP NAME> <function NAME> db-schema "admin"
fn config function <APP NAME> <function NAME> db-user "admin"
fn config function <APP NAME> <function NAME> input-bucket "input-bucket"
fn config function <APP NAME> <function NAME> processed-bucket "processed-bucket"
fn config function <APP NAME> <function NAME> password_id "ocid1.vaultsecret.oc1.iad.amaaaaaa“
デプロイするアプリケーションを指定し、ファンクションをデプロイ
fn deploy --app <AP名>
イベント・ルールの作成
バケットにファイルを配置したタイミングでFunctionをトリガーするイベントを設定
OCI コンソール > アプリケーション統合 > イベント・サービス に移動
- [ルールの作成]をクリック
動作確認
input-bucket に file1.csvをアップロード
INFO - Event ID 63062746-0a2d-2eff-d928-927e982b2d5e received
INFO - Object name: file1.csv
INFO - Bucket name: input-bucket
INFO - Namespace: XXXXXXX7
INFO - Object file1.csv is read
INFO - inserting:
INFO - {"region": "AMER", "col1": "1", "col2": "2", "col3": "3"}
INFO - Successfully inserted document ID 2C7207FFA0F64FE8A68F737FA6760939
INFO - inserting:
INFO - {"region": "APAC", "col1": "4", "col2": "5", "col3": "6"}
INFO - Successfully inserted document ID 562F77FA21014EA08BFFF1FBB0B3D77E
INFO - inserting:
INFO - {"region": "EMEA", "col1": "7", "col2": "8", "col3": "9"}
INFO - Successfully inserted document ID 7AE7BD6D992A48A3AC70234AABB6C550
INFO - inserting:
INFO - {"region": "AMER", "col1": "10", "col2": "11", "col3": "12"}
INFO - Successfully inserted document ID 1BF89A74B20A46A18A3E7F52565B2762
INFO - All documents are successfully loaded into the database
INFO - Object file1.csv moved to Bucket processed-bucket
2020-05-05 02:22:16,055 - fdk.event_handler - INFO - request execution completed
ロードの確認
SQLでregionsnumbersコレクションにアクセス
select
id,
r.json_document.region,
r.json_document.col1,
r.json_document.col2,
r.json_document.col3,
from regionsnumbers r
"ID" "REGION" "COL1" "COL2" "COL3"
"78709441BFA2447883D185EEEFDCA0D3" "APAC" "4" "5" "6"
"A0A8FC73B54C4665AD321693E2E35F09" "APAC" "16" "17" "18"
"AFEF7F4544C24E4482687FDBAD5ED197" "AMER" "22" "23" "24"
"6497837A71614CE6B1F788D2369B49C7" "AMER" "13" "14" "15"
おわりに
イベント・サービスとFunctionsを使って、Object StorageにUploadされたファイルのAutonomous Databaseへのロード自動化ができた。
参考情報
- Using the OCI Instance Principals and Vault with Python to retrieve a Secret
- Automatically load data from Object Storage into Autonomous Data Warehouse
- Cloud Shellを使ってOracle Functionsサンプルを動かしてみた。
- [AutonomousDB] Autonomous DatabaseにJSONドキュメントを格納してみた。(ORDS+SODA)
- Oracle Functionsことはじめ
- Autonomous Database ハンズオンラボ(ADB HOL)