2023年12月11日月曜日

Oracle Database 23c FreeにDBMS_CLOUDパッケージを入れてAmazon S3にアクセスする

Oracle Corporationは無料で利用できるオラクル・データベースとしてOracle Database 23c Freeを提供しています。このオラクル・データベースからAmazon S3にアクセスするためにDBMS_CLOUDパッケージをインストールしました。

以下、実施した作業を記述します。以下の記事に従って作成した環境に、DBMS_CLOUDをインストールします。

Oracle APEXの環境作成(0) - はじめに

パッケージDBMS_CLOUDのインストールについて、オラクル社としてMy Oracle Supportに以下のドキュメントを公開しています。

How To Setup And Use DBMS_CLOUD Package (Doc ID 2748362.1)

今回のAmazon S3にアクセスすることが目的であることもあり、AWS Database Blogの以下の記事に従って作業することにしました。

Use the DBMS_CLOUD package in Amazon RDS Custom for Oracle for direct Amazon S3 integration

AWSを使った経験が少ない方の参考になるように、AWSの操作についても記述します。

今回の作業はAWSのREST APIを、アクセスキーで認証して呼び出すことを目的としています。DBMS_CLOUDのほとんどのAPIは、オラクルのディレクトリ・オブジェクトを介してオブジェクト・ストレージとのデータのやり取りを行います。DBMS_CLOUDでは、このディレクトリ・オブジェクトがOracle File System(Oracle Database File System)であることが前提となっているようです。そのため、LIST_FILES、GET_OBJECT、PUT_OBJECTその他を使うためにはOFS/DBFSの設定が必要なようです。リソースに制限のある23c FreeでDBFSを構成するのは無理があると思ったので、試していません。


Amazon S3バケットを作成する



Oracle Database 23c FreeからアクセスするAmazon S3のバケットを作成します。

AWSコンソールよりAmazon S3バケットを開きます。

汎用バケットバケットの作成をクリックします。


一般的な設定バケット名を設定します。今回の作業ではmyoraclefreebucketとしました。AWSリージョンは後の設定で使うため覚えておきます。バケットタイプ汎用です。


AWSのブログの手順にポリシーが含まれて、そのまま使えます。ポリシーを使用できるため、オブジェクト所有者ACL無効(推奨)を選択します。


以降の設定もデフォルトから変更しません。画面下のバケットの作成を実行します。


バケットが作成されます。



ポリシーを作成する



AWSコンソールよりIdentity and Access Management(IAM)ポリシーを開きます。

ポリシーの作成をクリックします。


アクセス許可を指定します。ポリシーエディタJSONを選び、AWSのブログに記載されているポリシーのJSONを貼り付けます。今回の作業ではSidOracleFreeS3Policyとしています。<your bucket name>の部分はmyoraclefreebucketに置き換えています。


へ進みます。


ポリシー名は任意ですが、今回の作業ではOracleFreeS3Policyとしました。

ポリシーの作成をクリックします。


ポリシーOracleFreeS3Policyが作成されます。



IAMユーザーを作成する



Identity and Access Management(IAM)ユーザーを開きます。

ユーザーの作成をクリックします。


ユーザー名を指定します。今回の作業ではoracletestuserとしました。

へ進みます。


許可のオプションとしてポリシーを直接アタッチするを選択します。許可ポリシーからOracleFreeS3Policyを検索し、チェックを入れます。

へ進みます。


ユーザーの作成を実行します。


ユーザーが作成されます。

アクセスキーを生成するため、作成したユーザーを開きます。



セキュリティ認証情報のタブを開き、アクセスキーを作成をクリックします。


AWSとしてはアクセスキーの使用は推奨していないようです。ユースケースを選択すると、代替案が示されます。今回はAWSのブログの記載に従っているため、採用可能な代替案があるのかどうかわかりません。どれを選択してもアクセスキーは作成できますが、その他を選択します。

へ進みます。


説明タグは必須ではありません。

アクセスキーを作成をクリックします。


アクセスキーシークレットアクセスキーが作成されます。DBMS_CLOUD.CREATE_CREDENTIALを呼び出してAmazon S3にアクセスするためのクリデンシャルを作成する際に、アクセスキーusernameシークレットアクセスキーpasswordの値になります。



パッケージDBMS_CLOUDをインストールする



Oracle Database 23c FreeにOracle APEXとOracle ORDSをインストールした環境に接続します。作業はユーザーoracleで実施します。Oracle Cloudのコンピュート・インスタンスとして実行されている環境を想定していますが、その他のクラウドでも、手順は変わらないでしょう。

/home/oracle以下にファイルdbms_cloud_install.sqlを作成します。以下の内容を記述します。AWSのブログに記載されている内容ですが、できればオラクルの公式のドキュメント2748362.1を参照するのが望ましいです。2023年12月11日時点では、空白行を除くと両者に差異はありませんでした。


作成したdbms_cloud_install.sqlを実行します。パッケージDBMS_CLOUDはcatcon.plを使って、CDBに作成します。

ユーザーoracleにインストール済みのデータベースの環境を設定します。データベースのSIDは、FREEです。

. oraenv

[oracle@apexs3 ~]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@apexs3 ~]$


catcon.plを呼び出し、dbms_cloud_install.sqlを実行します。
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u sys/[SYSのパスワード] --force_pdb_mode 'READ WRITE' -b dbms_cloud_install -d /home/oracle -l /home/oracle dbms_cloud_install.sql

[oracle@apexs3 ~]$ $ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u sys/****** --force_pdb_mode 'READ WRITE' -b dbms_cloud_install -d /home/oracle -l /home/oracle dbms_cloud_install.sql

catcon::set_log_file_base_path: ALL catcon-related output will be written to [/home/oracle/dbms_cloud_install_catcon_2850.lst]


catcon::set_log_file_base_path: catcon: See [/home/oracle/dbms_cloud_install*.log] files for output generated by scripts


catcon::set_log_file_base_path: catcon: See [/home/oracle/dbms_cloud_install_*.lst] files for spool files, if any


catcon.pl: completed successfully

[oracle@apexs3 ~]$ 


completed successfullyと表示されれば、スクリプトの実行は成功しています。

CDBに接続し、オブジェクトDBMS_CLOUDのステータスを確認します。以下を実行します。


[oracle@apexs3 ~]$ sqlplus / as sysdba


SQL*Plus: Release 23.0.0.0.0 - Production on Mon Dec 11 13:36:11 2023

Version 23.3.0.23.09


Copyright (c) 1982, 2023, Oracle.  All rights reserved.



Connected to:

Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.3.0.23.09


SQL> column name format a10

column owner format a20

column object_name format a12

column status format a10

set tab off


select v.name, o.owner, o.object_name, o.status, o.sharing, o.oracle_maintained 

from cdb_objects o join v$containers v on o.con_id=v.con_id 

where o.object_name = 'DBMS_CLOUD' 

order by name;SQL> SQL> SQL> SQL> SQL> SQL>   2    3    4  


NAME       OWNER                OBJECT_NAME  STATUS     SHARING            O

---------- -------------------- ------------ ---------- ------------------ -

CDB$ROOT   PUBLIC               DBMS_CLOUD   VALID      METADATA LINK      Y

CDB$ROOT   C##CLOUD$SERVICE     DBMS_CLOUD   VALID      METADATA LINK      Y

CDB$ROOT   C##CLOUD$SERVICE     DBMS_CLOUD   VALID      METADATA LINK      Y

FREEPDB1   PUBLIC               DBMS_CLOUD   VALID      METADATA LINK      Y

FREEPDB1   C##CLOUD$SERVICE     DBMS_CLOUD   VALID      METADATA LINK      Y

FREEPDB1   C##CLOUD$SERVICE     DBMS_CLOUD   VALID      METADATA LINK      Y


6 rows selected.


SQL> 



データベースにSSLウォレットを設定する



Oracle APEXで使用しているSSLウォレットを流用できます。こちらの記事(Oracle APEXの環境作成(9) - REST呼び出しに使うウォレットの作成)に従って作業を行っていると、/home/oracle/wallet以下に自動ログインウォレットが作成済みです。

$ORACLE_HOME/network/admin/sqlnet.oraに以下の1行を追記します。
WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/home/oracle/wallet)))


CDBにACEsを設定する



/home/oracle以下にsetup_aces.sqlを作成し、以下の内容を記述します。


CDBに接続し、setup_aces.sqlを実行します。

[oracle@apexs3 ~]$ sqlplus / as sysdba


SQL*Plus: Release 23.0.0.0.0 - Production on Mon Dec 11 13:46:24 2023

Version 23.3.0.23.09


Copyright (c) 1982, 2023, Oracle.  All rights reserved.



Connected to:

Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.3.0.23.09


SQL> @setup_aces.sql


Session altered.


old   9:     principal_name => upper('&clouduser'),

new   9:     principal_name => upper('C##CLOUD$SERVICE'),

old  14:     wallet_path => 'file:&sslwalletdir',

new  14:     wallet_path => 'file:/home/oracle/wallet',

old  17:     principal_name => upper('&clouduser'),

new  17:     principal_name => upper('C##CLOUD$SERVICE'),


PL/SQL procedure successfully completed.


old   3: execute immediate 'alter database property set ssl_wallet=''&sslwalletdir''';

new   3: execute immediate 'alter database property set ssl_wallet=''/home/oracle/wallet''';


PL/SQL procedure successfully completed.



Session altered.


SQL> 



PDBにACEsを設定する



PDBにACEsの許可を与えたロールを作成します。ロール名はCLOUD_USER_ROLEとします。PDBにSYSで接続し、以下のスクリプトを実行します。


スクリプト名はconfigure_role.sqlとします。

Oracle APEXの環境を手順通りに作成していると、FREEPDB1というPDBにAPEXがインストールされています。

以下を実行します。

sqlplus / as sysdba
alter session set container=FREEPDB1;
create role CLOUD_USER_ROLE;
@configure_role


[oracle@apexs3 ~]$ sqlplus / as sysdba


SQL*Plus: Release 23.0.0.0.0 - Production on Mon Dec 11 14:05:14 2023

Version 23.3.0.23.09


Copyright (c) 1982, 2023, Oracle.  All rights reserved.



Connected to:

Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.3.0.23.09


SQL> alter session set container=FREEPDB1;


Session altered.


SQL> create role CLOUD_USER_ROLE;


Role created.


SQL> @configure_role


Session altered.


old   9:     principal_name => upper('&cloudrole'),

new   9:     principal_name => upper('CLOUD_USER_ROLE'),

old  14:     wallet_path => 'file:&sslwalletdir',

new  14:     wallet_path => 'file:/home/oracle/wallet',

old  17:     principal_name => upper('&cloudrole'),

new  17:     principal_name => upper('CLOUD_USER_ROLE'),


PL/SQL procedure successfully completed.



Session altered.


SQL> 


ロールCLOUD_USER_ROLEに、ビューDBA_CREDENTIALSのSELECT権限とパッケージDBMS_CLOUDの実行権限を与えます。

grant select on dba_credentials to cloud_user_role;
grant execute on dbms_cloud to cloud_user_role;

SQL> grant execute on dbms_cloud to cloud_user_role;


Grant succeeded.


SQL> grant select on dba_credentials to cloud_user_role;


Grant succeeded.


SQL> 


APEXのワークスペースのスキーマに作成したロールを割り当てます。以下ではWKSP_APEXDEVというスキーマが作成済みとしています。

grant cloud_user_role to <ワークスペース・スキーマ>;

SQL> grant cloud_user_role to wksp_apexdev;


Grant succeeded.


SQL> 


以上で、Oracle APEXのSQLコマンドより、パッケージDBMS_CLOUDを呼び出す準備ができました。


DBMS_CLOUDを呼び出す



Amazon S3にアクセスするクリデンシャルcred_demouserを作成します。
begin
    dbms_cloud.create_credential(
        credential_name => 'cred_demouser'
        ,username => 'アクセスキー'
        ,password => 'シークレットアクセスキー'
    );
end;


作成されたクリデンシャルを確認します。

select * from dba_credentials;


内容にmy first uploadと記載したファイルtest.txtを、S3のバケットにアップロードします。
declare
    l_resp dbms_cloud_types.resp;
    l_blob blob;
    l_clob clob;
begin
    l_clob := 'my first upload';
    l_blob := apex_util.clob_to_blob(l_clob);
    l_resp := dbms_cloud.send_request(
        credential_name => 'cred_demouser'
        ,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt'
        ,method => 'PUT'
        ,body => l_blob
    );
end;

バケットの内容をリストします。test.txtがアップロードされていることが確認できます。
select * from dbms_cloud.list_objects(
    credential_name => 'cred_demouser'
    ,location_uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket'
)

AWSコンソールからも確認できます。


ファイルtest.txtを取得します。ファイルの内容がmy first uploadとして表示されます。
declare
    l_resp dbms_cloud_types.resp;
    l_clob clob;
begin
    l_resp := dbms_cloud.send_request(
        credential_name => 'cred_demouser'
        ,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt'
        ,method => 'GET'
    );
    l_clob := dbms_cloud.get_response_text(
        resp => l_resp
    );
    dbms_output.put_line(l_clob);
end;


ファイルtest.txtを削除します。
begin
    dbms_cloud.send_request(
        credential_name => 'cred_demouser'
        ,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt'
        ,method => 'DELETE'
    );
end;

再度、バケット内のファイルをリストします。データが見つかりませんと返されます。


AWSコンソールからも、オブジェクトが存在しないことが確認できます。


今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。