Oracle Cloud 最新機能紹介:Oracle Functions でサーバーレスをはじめよう ~ Python で ADWC に接続 ~
基盤ソリューション事業本部 オラクル事業部
サービス推進担当 サービス・イノベーション・グループ
Tricy Liu
背景
Oracle Functions は、Oracle Cloud のサーバーレスコンピューティングを実現する FaaS ( Function as a Service ) です。
イベントドリブンで呼び出せるイベントサービスの「 Oracle Cloud Infrastructure Events 」と一緒に利用することで、Oracle Cloud 上の特定のイベントが発生した際に、指定されたファンクションを作動することができます。
これを利用して、オブジェクト・ストレージ上にユーザーが分析用の Excel ファイルをアップロードしたら、Oracle Functions でその Excel ファイルを自動的に ADWC へ取り込み、すぐにデータ分析を行うといったことが可能になります。
本ブログでは、Oracle Functions ( Fn project ) から ADWC へ接続する手順を書いてみました。
作業に使用する言語として Java 、Node.js 、Go などがあげられますが、今回はまだネット上で記事数が比較的に少ない Python で接続したいと思います。
事前準備 ( Oracle Functions が使用できるまでのステップ )
Oracle Functions が使用できるまで、Oracle Cloud Infrastructure 上での必要項目の作成や、Fn project と Docker のインストールが必要です。
マニュアルに詳しく記載されていますので、以下を参照してください。(ステップ数が多くてやや煩雑ですが、気を抜かずに最後まで頑張ってください)
赤枠で囲まれているステップを完了すれば問題ありません。
これで正確に作動できるか不安な方はその次のステップで、簡単な Helloworld ファンクションを作成して遊んでみてもいいと思います。
また、Oracle Functions の仕組みについて上のステップで詳しく書かれていますので、理解を深めたい方は読んでみてください。
ADWC に接続するまでのステップ
ADWC に接続するまでの流れとして、まずはファンクションを実行するためのアプリケーションを用意します。
次に、ファンクションを正確に作動させるために下記の必須ファイルを揃えていきます。
Dockerfile | Docker コンテナの構成内容をまとめて記述するファイルです。 ※本来、Fn project では Docker コンテナは変更できないように、Dockerfile はデフォルトでは用意されていませんが、今回、ADWC へ接続するために Oracle Instant Client のインストールや Wallet 情報の引渡しで構成変更を必要とするため、手動で作成します。 |
func.py | ファンクションのソースコードが記載されたファイルです。 ※Fn project で Python を書く際に、必ず handler 関数を使用する必要があります。Oracle Functions は Cloud 上のイベントサービスによって作動するため、handler 関数はイベント情報が書かれた JSON ファイルを読み取るために使用されます。 |
func.yaml | ファンクションのコンフィグファイルです。 設定変更をした場合、必ずアプリケーションの再デプロイが必要になります。 |
requirements.txt | ファンクションのソースコード内でインポートするパッケージを記述するファイルです。 アプリケーションをデプロイする際に記述されたパッケージが自動で Docker コンテナにインストールされます。 |
Oracle Instant Client インストール zip ファイル | ADWC への接続に Oracle Instant Client が必要です。 zip ファイルのまま、ファンクション名のディレクトリ下に格納してください。 |
Wallet.zip ファイル | ADWC に接続するために必要な構成情報ファイルです。 解凍した状態でファンクション名のディレクトリ下に格納してください。 |
1. アプリケーションの作成
まずは、現在作成されているアプリケーションを確認します。下記の場合ではアプリケーションはまだ作成されていません。
$ fn list apps No apps found NAME ID
アプリケーションを作成するために事前準備で作成した Virtual Cloud Networks サブネットの OCID が必要です。
まず、OCI にログインし、以下の画面で1つのサブネットを選択します。
下記の画面でサブネットの OCID をコピーします。
コピーした OCID を以下のコマンドに貼り付けて、実行します。
fn create app --annotation oracle.com/oci/subnetIds='["サブネット OCID "]' <アプリケーション名>アプリケーション名>
下記はアプリケーション名を「 fn-new-app 」とした場合のコマンドです。
$ fn create app --annotation oracle.com/oci/subnetIds='["ocid1.subnet.oc1.phx...."]' fn-new-app
作成後、アプリケーションが存在することを確認します。
$ fn list apps NAME ID fn-new-app ocid1.fnapp.oc1.iad.aaaaaaaaaft67iqssgjrp7wwf3ck42j362mxv5234c4via…
Fn project のファンクション専用の作業用ディレクトリを作成します。
$ mkdir ~/fn_work/ $ cd ~/fn_work/
2. ファンクションの作成
Python の初期ファンクションを生成します。
fn init --runtime python <ファンクション名>ファンクション名>
下記はファンクション名を「 adwc-conn 」とした場合のコマンドです。
$ fn init --runtime python adwc-conn Creating function at: ./adwc-conn Function boilerplate generated. func.yaml created.
作業ディレクトリの下にファンクション名のディレクトリが作成されていることが確認できます。
$ ls -la ~/fn_work/ 合計 0 drwxrwxr-x. 4 opc opc 36 9月 26 07:05 . drwxrwxr-x. 6 opc opc 85 8月 21 01:42 .. drwxr-xr-x. 2 opc opc 62 9月 26 07:05 adwc-conn
ファンクション名のディレクトリの下には、Python のソースコード func.py、コンフィグファイル func.yaml、またパッケージをインストールする用の requirements.txt がデフォルトで生成されていることが確認できます。
$ ls -la ~/fn_work/adwc-conn/ 合計 0 drwxr-xr-x. 2 opc opc 62 9月 26 07:05 . drwxrwxr-x. 4 opc opc 36 9月 26 07:05 .. -rw-r--r--. 1 opc opc 440 9月 26 07:05 func.py -rw-r--r--. 1 opc opc 138 9月 26 07:05 func.yaml -rw-r--r--. 1 opc opc 3 9月 26 07:05 requirements.txt
3. 実行用ファイルの準備
ADWC へ接続するために Oracle Instant Client のインストールと ADWC の Wallet の情報が必要です。
Oracle Instant Client は下記 URL からダウンロードできます。
https://www.oracle.com/database/technologies/instant-client/downloads.html
今回はクライアント端末が Oracle Linux 7 64-bit なので、Instant Client for Linux x86-64 から
- instantclient-basic-linux.x64-18.5.0.0.0dbru.zip (OCI を実行するためのパッケージ)
- instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip ( Oracle アプリケーションを実行するためのパッケージ)
- instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip ( SQL と PL/SQL 文を実行するためのパッケージ)
$ ls -la ~/fn_work/adwc-conn/oracle/ 合計 73016 drwxr-xr-x. 2 opc opc 4096 9月 26 08:55 . drwxr-xr-x. 6 opc opc 4096 9月 26 08:27 .. -rw-r--r--. 1 opc opc 72902980 9月 26 08:55 instantclient-basic-linux.x64-18.5.0.0.0dbru.zip -rw-r--r--. 1 opc opc 929988 9月 26 08:55 instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip -rw-r--r--. 1 opc opc 918469 9月 26 08:54 instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip
それから ADWC の Web コンソールから wallet.zip をダウンロードします。
Wallet をダウンロードする際にパスワードを設定する必要があります。
※緑枠内の TNS 名を次のステップ5で使用しますので、メモをしてください。
ダウンロードした zip ファイルを解凍し、ファンクション名のディレクトリに入れます。
下記の例では「ファンクション名/wallet 」というディレクトリの下に解凍しています。
$ ls -la ~/fn_work/adwc-conn/wallet/ 合計 44 drwxrwxr-x. 2 opc opc 4096 9月 26 06:28 . drwxr-xr-x. 6 opc opc 4096 9月 26 08:27 .. -rw-rw-r--. 1 opc opc 6661 9月 26 06:28 cwallet.sso -rw-rw-r--. 1 opc opc 6616 9月 26 06:28 ewallet.p12 -rw-rw-r--. 1 opc opc 3242 9月 26 06:28 keystore.jks -rw-rw-r--. 1 opc opc 87 9月 26 06:28 ojdbc.properties -rw-rw-r--. 1 opc opc 114 9月 26 06:28 sqlnet.ora -rw-rw-r--. 1 opc opc 1040 9月 26 06:28 tnsnames.ora -rw-rw-r--. 1 opc opc 3336 9月 26 06:28 truststore.jks
4. Dockerfile の作成
ファンクション名のディレクトリの下に新しい Dockerfile を作成します。
$ vi Dockerfile
以下の内容を入力して、保存します。
※ディレクトリの場所は実際の環境に応じて修正してください。
- Oracle Instant Client のインストール用 zip ファイルのディレクトリ(今回の例では oracle/)
- 解凍された wallet のディレクトリ(今回の例では wallet/)
FROM fnproject/python:3.6-dev as build-stage WORKDIR /function ADD requirements.txt /function/ RUN pip3 install --target /python/ --no-cache --no-cache-dir -r requirements.txt && rm -fr ~/.cache/pip /tmp* requirements.txt func.yaml Dockerfile .venv ADD . /function/ RUN rm -fr /function/.pip_cache FROM fnproject/python:3.6 RUN apt-get update -y RUN apt-get install -y unzip RUN apt-get install -y libaio-dev RUN apt-get clean -y # -- Start setup Oracle # Install Oracle Instantclient 18.5 WORKDIR /function ADD oracle/instantclient-basic-linux.x64-18.5.0.0.0dbru.zip /function/oracle/instantclient-basic-linux.x64-18.5.0.0.0dbru.zip ADD oracle/instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip /function/oracle/instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip ADD oracle/instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip /function/oracle/instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip RUN unzip /function/oracle/instantclient-basic-linux.x64-18.5.0.0.0dbru.zip -d /function && \ unzip /function/oracle/instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip -d /function && \ unzip /function/oracle/instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip -d /function && \ addgroup --gid 1000 fn && \ adduser --uid 1000 --gid 1000 fn ENV ORACLE_HOME=/function/instantclient_18_5 ENV LD_LIBRARY_PATH=/function/instantclient_18_5:$LD_LIBRARY_PATH ENV PATH=/function/instantclient_18_5:$PATH COPY wallet/* /function/instantclient_18_5/network/admin/ # -- End setup Oracle COPY --from=build-stage /function /function COPY --from=build-stage /python /python ENV PYTHONPATH=/python ENTRYPOINT ["/python/bin/fdk", "/function/func.py", "handler"]
5. func.py の編集
ファンクションのソースコードを以下のように修正して保存します。
下記のスクリプトでは「 CREATE TABLE TEST (ID NUMBER) 」という SQL 文を発行します。
※ユーザー名とパスワードは ADWC へ接続する際に使用されるもので、そのスキーマでテーブルが作成されます。
※TNS 名はステップ3でメモした3つの名前の中の1つを入力してください。また ADWC の tnsnames.ora でも確認できます。
import io import os import json from fdk import response import cx_Oracle def handler(ctx, data: io.BytesIO=None): sql="CREATE TABLE TEST (ID NUMBER)" try: body = json.loads(data.getvalue()) except Exception as ex: print(str(ex)) # execute sql exe_sql(sql) return response.Response( ctx, response_data=json.dumps(sql), headers={"Content-Type": "application/json"} ) def exe_sql(sql): conn = cx_Oracle.connect('<ユーザー名>','<パスワード>','<TNS 名>') cur = conn.cursor() try: cur.execute(sql) conn.commit() except Exception as e: print(e) finally: cur.close() conn.close()
6. func.yaml の編集
下記のように「 timeout 」 と「 idle_timeout 」の欄を追加してください。(タイムアウトは最大120秒までしか設定できません)
schema_version: 20180708 name: adwc-conn version: 0.0.1 runtime: python entrypoint: /python/bin/fdk /function/func.py handler memory: 256 timeout: 120 idle_timeout: 1800
7. requirements.txt の編集
Python から ADWC へ接続する際に、cx_Oracle パッケージを使用しますので、下記のように「 cx_Oracle 」を追加します。
fdk cx_Oracle
8. 全てのファイルが準備完了になっていることの確認
ファンクション名のディレクトリの下を確認します。
$ ls -lR ~/fn_work/adwc-conn/ .: 合計 36 -rw-rw-r--. 1 opc opc 1698 9月 26 09:29 Dockerfile 追加済み -rw-rw-r--. 1 opc opc 709 9月 26 08:27 func.py 修正済み -rw-r--r--. 1 opc opc 167 9月 26 08:27 func.yaml 修正済み drwxr-xr-x. 2 opc opc 4096 9月 26 08:55 oracle 追加済み -rw-r--r--. 1 opc opc 43 9月 26 05:17 requirements.txt 修正済み drwxrwxr-x. 2 opc opc 4096 9月 26 06:28 wallet 追加済み ./oracle: 合計 73008 -rw-r--r--. 1 opc opc 72902980 9月 26 08:55 instantclient-basic-linux.x64-18.5.0.0.0dbru.zip -rw-r--r--. 1 opc opc 929988 9月 26 08:55 instantclient-sdk-linux.x64-18.5.0.0.0dbru.zip -rw-r--r--. 1 opc opc 918469 9月 26 08:54 instantclient-sqlplus-linux.x64-18.5.0.0.0dbru.zip ./wallet: 合計 36 -rw-rw-r--. 1 opc opc 6661 9月 26 06:28 cwallet.sso -rw-rw-r--. 1 opc opc 6616 9月 26 06:28 ewallet.p12 -rw-rw-r--. 1 opc opc 3242 9月 26 06:28 keystore.jks -rw-rw-r--. 1 opc opc 87 9月 26 06:28 ojdbc.properties -rw-rw-r--. 1 opc opc 114 9月 26 06:28 sqlnet.ora -rw-rw-r--. 1 opc opc 1040 9月 26 06:28 tnsnames.ora -rw-rw-r--. 1 opc opc 3336 9月 26 06:28 truststore.jks
9. ファンクションの実行
実行する前にまず ADWC 上で指定するスキーマでは「 TEST 」という名のテーブルが存在しないことを確認します。
アプリケーションをデプロイします。
fn --verbose deploy --app <アプリケーション名>アプリケーション名>
下記はアプリケーション名を「 fn-new-app 」で実行した場合になります。
※実行後の出力はやや多いですが、成功するまで待ちましょう。
$ fn --verbose deploy --app fn-new-app
デプロイが成功したあと、ファンクションを実行します。
fn invoke <アプリケーション名> <ファンクション名>ファンクション名>アプリケーション名>
下記はアプレケーション名を「 fn-new-app 」、ファンクション名を「 adwc-conn 」で実行した場合になります。
$ fn invoke fn-new-app adwc-conn "CREATE TABLE TEST (ID NUMBER)"
ADWC 上でも確認してみましょう。
テーブルが正確に作成されたことが確認できました。
これと同様にソースファイル「 func.py 」の中の SQL 文のところに修正を加えれば、お好みの SQL 文を ADWC 上で発行することが可能になります。
ぜひお試しください。
エラー対応
ファンクション実行してエラーになった場合、syslog で確認することができます。
下記のページを参考し、ログを確認してデバッグをしてみてください。
https://fnproject.io/tutorials/Troubleshooting/
Tweet