ラベル API の投稿を表示しています。 すべての投稿を表示
ラベル API の投稿を表示しています。 すべての投稿を表示

2024年3月7日木曜日

ORDS Database APIをローカルの環境で有効にする

Apple Mシリーズ上でコンテナ・イメージから作成した、ローカルのAPEX環境でORDS Database APIを有効にしてみました。その際の作業ログを残しておきます。

こちらの記事の手順で作成した直後から作業を始めます。

環境を作成した直後はワークスペースが作成されていません。APEXの管理サービスに接続し、ワークスペースを作成します。


管理者ユーザーパスワード@apxchpwdを実行したときに設定しています。管理者ユーザー名のデフォルトはADMINです。


ワークスペースが未作成であるため、Oracle APEXへようこその画面が開きます。ワークスペースの作成をクリックしても同じ作業になりますが、今回はワークスペースを2つ作る予定なのでワークペースの管理を開きます。


ワークスペースの管理画面が開きます。最初に既存のワースペースを確認し、その後にワークスペースの作成を実施します。


Oracle APEXをインストールするとINTERNALというワークスペースが作成されます。Oracle APEXの管理ツールや開発ツールは、このINTERNALワークスペースに作成されているAPEXアプリケーションになります。


ワークスペースの管理画面に戻り、ワークスペースの作成をクリックします。

ワークスペース名を指定します。今回はapexdevとしています。ワークスペースIDは開発環境を作成するときに指定します(こちらの記事で説明しています)。今回は指定しません。

へ進みます。


既存スキーマの再利用いいえを選択し、ワークスペースに紐づくスキーマを新規作成します。スキーマ名apexdevとします。領域割当て制限(MB)10000を選択します。Oracle Database 23c Freeが持てるユーザー・データの上限が12GBなので、ほぼ上限いっぱいまでこのスキーマはデータが持てることになります。

スキーマのパスワード必須項目なので設定しますが、APEXはこのパスワードを使いません。他のツールよりデータベースに接続する際に使用します。

へ進みます。


ワークスペースの管理者のユーザー名管理者のパスワードを設定します。電子メールも必須項目なので合わせて設定します。

Autonomous Databaseと異なりオンプレミスの環境では、管理者ユーザーや開発者ユーザーはデータベースのアカウントではなく、Oracle APEXで管理します。

へ進みます。


確認画面が開きます。ワークスペースの作成を実行します。


ワークスペースが作成されました。完了します。


同じ作業を繰り返し、ワークスペースapexdev2を作成します。紐づけるスキーマはapexdev2として作成します。

既存のワークスペースを開き、INTERNALAPEXDEVAPEXDEV2の3つのワークスペースが作成されていることを確認します。


作成したワークスペースAPEXDEV2の方です)にサインインし、検証に使用する設定を行ないます。


初回接続時は管理者のパスワードの変更を求められます。パスワードの変更を実施し、ワークスペースへサインインします。


ワークスペースに含まれるアプリケーション一覧を取得するORDS Database APIを呼び出したときに、結果が返されるようにアプリケーションを作成します。空のアプリケーションで十分です。

アプリケーション・ビルダーを開きます。


作成をクリックします。


作成するアプリケーションの名前確認用アプリとします。

アプリケーションの作成をクリックします。


アプリケーションが作成されました。ワークスペースAPEXDEV2での作業は終了です。

これからワークスペースAPEXDEVを対象としてORDS Database APIを発行し、ワークスペースAPEXDEV2に作成されているアプリケーション一覧を取得するために必要な設定を行ないます。


ワークスペースAPEXDEV2からサインアウトし、ワークスペースAPEXDEVにサインインします。APEXDEV2のときと同様に、初回はパスワードの変更を求められます。


ワークスペースAPEXDEVに管理者ユーザーでサインインしました。SQLワークショップからRESTfulサービスを呼び出し、ワークスペースに紐づいているスキーマAPEXDEVをORDSに登録します(ORDSの用語ではREST有効化という作業になります)。


ORDSにスキーマを登録をクリックします。


ORDSスキーマ属性を保存します。RESTfulアクセスの有効化オンスキーマ別名apexdev(通常ワークスペース名と同じ名前にします)、(RESTfulサービスの呼び出しの確認に使用するため)サンプル・サービスのインストールオンにします。

スキーマ属性の保存をクリックします。


RESTfulサービスの画面が開きます。

左ペインよりサンプル・サービスとしてインストールされたモジュールoracle.example.hrのテンプレートversionのメソッドGETを選択します。


このメソッドの完全なURLを確認します。

http://localhost:8181/ords/apexdev/hr/version/


手元のPCからcurlコマンドを実行し、REST APIを呼び出してみます。

curl http://localhost:8181/ords/apexdev/hr/version/

レスポンスとして { "version": "23.1" } が返されます。

% curl http://localhost:8181/ords/apexdev/hr/version/

{"version": "23.1"}

% 


作成したローカルの環境でREST APIを受け付けることが確認できました。

続いてSQLワークショップSQLコマンドから、このREST APIを呼び出します。

Oracle APEXをインストールした直後は、ネットワークACLの設定がされていません。Oracle APEXはバージョンごとにスキーマを作成し、そのスキーマにデータベース・オブジェクトを作成します。Oracle APEX 23.2であれば、インストール先のスキーマはAPEX_230200になります。

以下のSELECT文によりスキーマAPEX_230200に設定されているネットワークACLを確認します。
select host, acl,
decode(dbms_network_acl_admin.check_privilege_aclid(aclid, 'APEX_230200','connect'), 1, 'GRANTED', 0, 'DENIED', NULL) privilege
from dba_network_acls;

PRIVILEGEnullです。

(Oracle SQL Developer Extension for VS Codeの画面です)


以下のスクリプトを実行し、すべての宛先を対象としてconnectresolveの権限を与えます。
begin
    dbms_network_acl_admin.append_host_ace(
        host => '*',
        ace => xs$ace_type(
            privilege_list => xs$name_list('connect','resolve'),
            principal_name => 'APEX_230200',
            principal_type => xs_acl.ptype_db
        )
    );
    commit; 
end;
/


先ほどのSELECT文を再実行し、PRIVILEGEの再確認を行ないます。connectについてPRIVILEGEGRANTEDになっています。resolveの確認は割愛しますが、同様にGRANTEDになっています。


SQLワークショップSQLコマンドより、REST APIであるversionを呼び出します。手元のPCからORDSのコンテナordsへはlocalhostで接続できますが、データベースのコンテナapexdbからはlocalhostではなく、ORDSのコンテナに割り当てられたIPアドレスを宛先とする必要があります。

コンテナordsに割り当てられたIPアドレスを確認します。

docker inspect --format='{{.NetworkSettings.IPAddress}}' ords

172.17.0.3と確認できました。

% docker inspect --format='{{.NetworkSettings.IPAddress}}' ords


172.17.0.3

ynakakoshi@Ns-MacBook ~ % 


コンテナordsの起動時にIPアドレスが変わると面倒なので、コンテナapexdbと同様に、作成時に--ipオプションを指定して、あらかじめIPアドレスを割り当てておくとよいでしょう。

docker run -d --name ords --ip=172.17.0.3 -v `pwd`/ords_config/:/etc/ords/config/ -p 8181:8181 container-registry.oracle.com/database/ords:latest

SQLコマンドより以下のスクリプトを実行します。
declare
    l_response clob;
begin
    apex_web_service.clear_request_headers();
    l_response := apex_web_service.make_rest_request(
        p_url => 'http://172.17.0.3:8181/ords/apexdev/hr/version/'
        ,p_http_method => 'GET'
    );
    dbms_output.put_line(l_response);
end;
結果に{ "version": "23.1" }が印刷されます。

データベースからREST APIを呼び出せることが確認できました。


OAuthクライアントを作成します。SQL Developer Webに接続します。


詳細を開きパスにapexdevORDSスキーマ属性スキーマ別名として保存した値です)を設定します。ユーザー名パスワードは、APEXのワークスペースの管理者ユーザー(今回はadmin)とそのパスワードを入力します。

SQL Developer WebにスキーマAPEXDEVの権限でサインインします。


REST を開きます。


クライアントを開きます。


OAuthクライアントの作成をクリックします。


クライアント定義のタブを開きます。

付与タイプCLIENT_CREDです。OAuthクライアント名前restuser説明は必須項目なのでRest Userとしました。サポート電子メールも必須項目です。


ロールのタブを開きます。

ロールとしてSQL DeveloperRESTful Servicesを選択します。ORDS Database APIを呼び出しために必要なロールはSQL Developerだけです。RESTful Servicesはサンプルとしてインストールしたoracle.example.hrを使って、OAuthによる保護を確認するために割り当てます。

作成をクリックするとOAuthクライアントが作成されますが、その前にコードの表示オンにしてみます。


ORDSの管理作業はPL/SQLのスクリプトを呼び出して実施することが一般的です。そのため、大体の画面操作で、同等の作業を行なうコードを確認できます。

OAuthクライアントを作成します。


OAuthクライアントが作成されました。

REST APIの認証にクライアントIDクライアント・シークレットを使用するため、これらの値をコピーして安全に保存します。


これらの値を使って、Bearerトークンを取得してみます。

手元のPCより以下のトークンURLに対して、curlコマンドを実行してトークンをリクエストします。ワークスペースのベースURLに/oauth/tokenが続きます。

http://localhost:8181/ords/apexdev/oauth/token
curl http://localhost:8181/ords/apexdev/oauth/token \
-X POST \
-u <クライアントID>:<クライアント・シークレット> \
-d "grant_type=client_credentials"
レスポンスとしてaccess_tokenが返されます。

% curl http://localhost:8181/ords/apexdev/oauth/token \

-X POST \

-u <クライアントID>:<クライアント・シークレット> \

-d "grant_type=client_credentials"

{"access_token":"j2-PVvvomRNWPYclDLsmlw","token_type":"bearer","expires_in":3600}%                  ynakakoshi@Ns-MacBook ~ % 


APEXのワークスペースAPEXDEVにサインインし、ワークショップ・ユーティリティWeb資格証明を開きます。OAuthクライアントのクライアントIDクライアント・シークレットWeb資格証明として保存します。


作成をクリックします。


作成するWeb資格証明の名前静的IDCRED_OAUTH_REST_USERとします。認証タイプOAuth2クライアント資格証明フローを選択し、クライアントIDまたはユーザー名に先ほどコピーしたOAuthクライアントのクライアントIDクライアント・シークレットまたはパスワードクライアント・シークレットを設定します。

以上でWeb資格証明を作成します。


Web資格証明CRED_OAUTH_REST_USERが作成されました。

Web資格証明が正しく作成されたかどうか確認するため、サンプルとして作成されたRESTfulサービスを保護します。

RESTfulサービスを開き、左ペインで権限を選択し権限の作成を実行します。


作成する権限の名前タイトルoracle.example.hrとします。ロールRESTful Servicesモジュールoracle.example.hrを選択します。

以上の設定で権限の作成を実行します。


権限oracle.example.hrが作成されます。


SQLコマンドよりREST APIのversionを呼び出すコードを実行します。実行するコードは同じです。

結果としてUnauthorizedが返されます。


APEX_WEB_SERVICE.MAKE_REST_REQUESTを呼び出す際の引数としてp_credential_static_idCRED_OAUTH_REST_USERp_token_urlhttp://172.17.0.3:8181/ords/apexdev/oauth/tokenを追加します。
declare
    l_response clob;
begin
    apex_web_service.clear_request_headers();
    l_response := apex_web_service.make_rest_request(
        p_url => 'http://172.17.0.3:8181/ords/apexdev/hr/version/'
        ,p_http_method => 'GET'
        ,p_credential_static_id => 'CRED_OAUTH_REST_USER'
        ,p_token_url => 'http://172.17.0.3:8181/ords/apexdev/oauth/token'
    );
    dbms_output.put_line(l_response);
end;
今度は認証に成功し、レスポンスとして{"version": "23.1"}が返されます。

Web資格証明CRED_OAUTH_REST_USERが有効であることが確認できました。


これからORDS Database APIの呼び出しを行ないます。

ORDS Database APIはデフォルトでは有効になっていないため、最初にORDS Database APIを有効にします。通常は以下のコマンドでORDS Database APIを有効にします。

ords config set database.api.enabled true

今回の環境ではコンテナordsで実行するため、以下のコマンドを実行します。

docker exec -it ords ords config set database.api.enabled true

% docker exec -it ords ords config set database.api.enabled true

2024-03-07T10:25:03Z INFO ORDS has not detected the option '--config' and this will be set up to the default directory.


ORDS: Release 23.4 Production on Thu Mar 07 10:25:14 2024


Copyright (c) 2010, 2024, Oracle.


Configuration:

  /etc/ords/config/


No updates required to setting named database.api.enabled in global configuration because the values are the same.

% 


ワークスペースAPEXDEV2に含まれるアプリケーションの一覧を取得してみます。以下のURLを呼び出します。

http://172.17.0.3:8181/ords/apexdev/_/db-api/stable/apex/workspaces/apexdev2/applications/
declare
    l_response clob;
begin
    apex_web_service.clear_request_headers();
    l_response := apex_web_service.make_rest_request(
        p_url => 'http://172.17.0.3:8181/ords/apexdev/_/db-api/stable/apex/workspaces/apexdev2/applications/'
        ,p_http_method => 'GET'
        ,p_credential_static_id => 'CRED_OAUTH_REST_USER'
        ,p_token_url => 'http://172.17.0.3:8181/ords/apexdev/oauth/token'
    );
    dbms_output.put_line(l_response);
end;
レスポンス自体は正常に受け取れますが、ワークスペースAPEXDEV2に作成されているはずのアプリケーション確認用アプリが返ってきません。


このORDS Database APIはスキーマAPEXDEVの権限で実行されています。異なるAPEXワークスペースの情報を参照するには、スキーマはAPEX_ADMINISTRATOR_ROLEを持つ必要があります。

スキーマAPEXDEVにロールAPEX_ADMINISTRATOR_ROLEを割り当てます。ユーザSYSによる接続から実行します。

grant APEX_ADMINISTRATOR_ROLE to apexdev;


再度、ORDS Database APIを呼び出します。今度は確認用アプリが返ってきました。


以上でローカル環境にインストールしたAPEXでORDS Database APIを有効にし、その呼び出しを確認することができました。

2024年3月6日水曜日

ORDS Database APIを呼び出し別環境のAPEXアプリケーションのエクスポート/インポート/削除を行なう

Oracle REST Data ServicesはOracle REST Data Services APIとして、Oracle Databaseを操作するREST APIを提供しています。これらのREST APIは、ORDS開発者ガイドではORDS Database APIと呼ばれていて、利用するための準備は8 Enabling ORDS Database APIに記載されています。

ORDS Database APIには、APEXのワークスペースを操作するREST APIが含まれています。主要なAPIにアプリケーションの一覧/エクスポート/インポート/削除があり、これらのREST APIを呼び出すことにより、インスタンスの異なるワークスペースに含まれるアプリケーションを操作することができます。

異なるAutonomous DatabaseのAPEXワークスペースにあるアプリケーションの一覧、アプリケーションのインポート、エクスポートおよび削除を行なうAPEXアプリケーションを作成してみました。以下のように動作します。


ORDS Database APIについて、以下の記事を参考にしています。

ORDSのProduct ManagerのJeff Smithさんによる以下の記事
ORDS and our APEX REST APIs

Oracle APEXのArchitectのCarsten Czarskiさんによる以下の記事
Oracle APEX App Deployments made easy: Use the ORDS REST APIs

インスタンスURLワークスペース名により操作するAPEXのワークスペースを特定し、ユーザー認証にはOAuthのクライアント・クリデンシャル・フローのクライアントIDクライアントシークレットを使用します。

アプリケーションを作成するAPEXワークスペースと作成したアプリケーションから操作するAPEXワークスペースの両方に、Always FreeのAutonomous Databaseを使用して作業を進めます。ORDS Database APIはORDSに実装されている機能であるためネットワークとして接続できれば、オンプレミスの環境も操作の対象にできます。

これから作成するAPEXアプリケーションの操作対象となるインスタンスを準備します。操作対象となるAutonomous DatabaseのORDSに接続します。

https://ADBのホスト名/ords/

SQL Developer Webを開きます。


ADBの管理者ユーザーADMINでサインインします。パスワードはADBの作成時に設定しています。


RESTを開きます。


クライアントを開きます。


OAuthクライアントの作成を実行します。


クライアント定義のタブを開き、必要な情報を入力します。付与タイプCLIENT_CREDです。

名前説明サポート電子メールを入力します。これらの値は、ORDS Database APIを呼び出す際の認証情報としては使われません。


ロールのタブを開き、ORDS Database APIの実行に必要なロールSQL Developerを選択します。

作成をクリックします。


OAuthクライアントが作成されます。

クライアントIDクライアントシークレットをコピーし、安全に保存します。この値からORDS Database APIを呼び出す際に指定するAPEXのWeb資格証明を作成します。


操作対象とするAPEXワークスペースの準備は以上で完了です。

リモートのワークスペースを操作するAPEXアプリケーションを作成します。

最初にORDS Database APIを呼び出すパッケージUTL_APEX_REMOTEを作成します。ORDS Database APIの呼び出しをPL/SQLのプロシージャにラップすることにより、プロセス・タイプAPIの呼出しとして呼び出せるようにします。

クイックSQLの以下のモデルより、表DBAPEX_WORKSPACESを作成します。操作対象とする別環境のAPEXワークスペースを保持します。


レビューおよび実行をクリックし処理を進め、表DBAPEX_WORKSPACESを作成します。

表が作成された時点で、その表を元にしたアプリケーションの作成を実行します。


アプリケーション作成ウィザードが起動します。

アプリケーションの名前Sample APEX DBAPIとします。ホーム・ページは不要なので削除します。結果として表DBAPEX_WORKSPACESを対象としたフォーム付き対話モード・レポートのページが作成されます。

以上の設定でアプリケーションの作成を実行します。


アプリケーションが作成されたら、とりあえず実行してみます。

作成ボタンをクリックします。


画面右に操作対象のAPEXワークスペースを登録するドロワーが開きます。

ワークスペース名(Workspace Name)、インスタンスのURL(Instance URL)、Web資格証明の名前(Credential Name)、Web資格証明の静的ID(Credential Static ID)を入力するページ・アイテムはありますが、OAuthのクライアントIDクライアントシークレットを入力するページ・アイテムは表DBAPEX_WORKSPACESの列として存在していないため、ありません。

OAuthのクライアントIDクライアントシークレットを入力するページ・アイテムを追加し、それらの値からWeb資格証明を作成するプロセスを作成します。

ページ・デザイナでページ番号のドロワーのページを開きます。


クライアントIDを入力するページ・アイテムP2_CLIENT_IDを作成します。

識別タイプテキスト・フィールドラベルClient IDとします。セッション・ステートストレージとしてリクエストごと(メモリーのみ)を選択します。


クライアントシークレットを入力するページ・アイテムP2_CLIENT_SECRETを作成します。

識別タイプパスワードラベルClient Secretとします。セッション・ステートストレージとしてリクエストごと(メモリーのみ)を選択します。

パスワードの設定[Enter]を押すと送信オフにします。


左ペインでプロセス・ビューを開きます。

新規にプロセスを作成し、プロセスの先頭に配置します。識別名前Web資格証明の作成または更新とし、タイプAPIの呼出しとします。

設定タイプPL/SQLパッケージを選択し、パッケージは作成済みのUTL_APEX_REMOTEを選択します。プロシージャまたはファンクションとしてCREATE_OR_UPDATE_WEB_CREDENTIALを選択します。

パラメータ名に一致するようにページ・アイテム名を決めているため、デフォルトで適切なページ・アイテムがパラメータに紐づきます。

サーバー側の条件タイプリクエストは値に含まれるを選択し、としてCREATE SAVEを設定します。ボタン作成および変更の確定をクリックしたときに実行されます。削除に関する処理は実装していないため、登録しているAPEXワークスペースを削除しても、紐づいているWeb資格証明は削除されずAPEXのワークスペースに残ります。


以上でAPEXワークスペースを登録するページは完成です。

アプリケーションよりWeb資格証明を作成できるように、アプリケーション定義セキュリティ詳細に含まれるランタイムAPIの使用状況ワークスペース・リポジトリを変更チェックします。


アプリケーションを実行し、操作対象のワークスペースを登録します。

作成をクリックし、先ほどOAuthのクライアントIDクライアントシークレットを作成したインスタンスとワークスペースを登録します。

Autonomous Databaseの場合、インスタンスURLは以下の形式で設定します。管理者ユーザーADMINの権限で実行するためインスタンスURLの末尾はadmin/になります。

https://ホスト名/ords/admin/

Oracle APEX REST Endpointsの一覧は/apex/から始まっています。最終的に呼び出すREST APIのエンドポイントは、インスタンスURLに_/db-api/stableとOracle APEX REST Endpointsを繋げたURLになります。

https://ホスト名/ords/admin/_/db-api/stable/apex/...

Credential Nameの指定がない場合は、静的IDWeb資格証明の名前にしています。今回の例ではDBAPI_CRED_APEXDEVWeb資格証明静的IDとしています。


操作対象のAPEXワークスペースが登録されます。


Web資格証明を開くと、指定した静的IDWeb資格証明が作成されていることも確認できます。


続けて別環境のワークスペースに含まれるアプリケーションの一覧とエクスポート/インポート/削除を行なうページを作成します。

取得したアプリケーションの一覧はAPEXコレクションに保存します。使用するAPEXコレクションの名前を変えられるように、アプリケーション定義置換置換文字列としてG_WORKSPACE_APPLICATIONSを作成します。置換値WORKSPACEAPPSとします。この値が実際のコレクション名になります。


新規にページを作成します。


空白ページを選択します。


ページ番号名前Applicationsとします。その他はデフォルトから変更せず、ページ・モード標準ナビゲーションは両方ともオンとします。

ページの作成をクリックします。


空白ページが作成されます。

ORDS Database APIの引数となる値を保持するページ・アイテムを作成します。ページ・アイテムのタイプ非表示です。セッション・ステートストレージセッションごと(永続)を選択し、ページを送信した後も値が維持されるようにします。

作成するページ・アイテムP3_WORKSPACE_NAMEP3_INSTANCE_URLP3_CREDENTIAL_STATIC_IDの3つです。


ORDS Database APIのGet all applications in the specified workspaceのAPIを発行し、取得したアプリケーションでAPEXコレクションを初期化するプロセスを作成します。

新規にプロセスを作成しレンダリング前ヘッダーの前に配置します。

識別名前APEXコレクションの初期化とします。タイプAPIの呼出しです。設定タイプPL/SQLパッケージを選び、パッケージとしてUTL_APEX_REMOTEプロシージャまたはファンクションとしてLOAD_APPS_INTO_APEX_COLLECTIONを選択します。


パラメータp_collection_nameを選択し、タイプ静的値静的値として&G_WORKSPACE_APPLICATIONS.を指定します。それ以外のパラメータはデフォルトで適切なページ・アイテムまたはAPIデフォルトが割り当たります。


アプリケーションの一覧を表示する対話モード・レポートを作成します。

識別タイトルApplicationsとします。タイプ対話モード・レポートです。ソースタイプSQL問合せとし、SQL問合せとして以下を記述します。列EXPDELには、アプリケーションのエクスポート削除を呼び出すボタンを後で作成します。

JavaScriptよりレポートのリフレッシュを実行するため、詳細静的IDとしてAPPLICATIONSを設定します。

変更を一旦保存します。


ページ・デザイナでページ番号1の対話モード・レポートのページを開きます。

WORKSPACE_NAMEをクリックすることにより、先ほど作成したページ番号を開いて別環境にあるワークスペースに含まれるアプリケーションの一覧を表示するようにします。

識別タイプリンクに変更します。リンクターゲットを開きます。


ターゲットページです。ページ番号3にあるページ・アイテムP3_WORKSPACE_NAMEP3_INSTANCE_URLP3_CREDENTIAL_STATIC_IDに、それぞれ列の値\#WORKSPACE_NAME#\\#INSTANCE_URL#\\#CREDENTIAL_STATIC_ID#\を設定します。列INSTANCE_URLには(コロン)が含まれます。:(コロン)はAPEXの内部で値を分割する文字として認識されるため、その影響を受けないように値を\(バックスラッシュ)で囲みます。

OKをクリックします。


変更を保存し、アプリケーションを実行して動作を確認します。

ワークスペース名クリックします。


ページ番号3が開き、そのワークスペースに作成されているアプリケーションが一覧されます。


アプリケーションをインポートする機能を追加します。

ページ・アイテムとしてP1_APPLICATION_IDを作成し、インポートするアプリケーションに割り当てるアプリケーションIDを指定します。ORDS Database APIによるインポートではアプリケーションIDは必須であり、空いているIDを自動で割り当てる機能はないようです。空いているIDを見つけるようにすると親切ですが今回はその機能は実装を見送り、アプリケーションIDは明示的に指定するようにします。同じアプリケーションIDのアプリケーションがある場合は上書きされるため注意が必要です。

識別タイプ数値フィールドラベルApplication IDとします。設定数字の位置合せ開始仮想キーボード数値を選択します。

検証必須の値オンセッション・ステートストレージリクエストごと(メモリーのみ)を選択します。


ページ・アイテムとしてP3_FILEを作成し、アプリケーションとしてインポートするファイルを選択します。

識別タイプファイルのアップロードラベルFileとします。ストレージタイプ表APEX_APPLICATION_TEMP_FILESを選択し、ファイルをパージするタイミングリクエストの終わりとします。

検証必須の値オンセッション・ステートストレージリクエストごと(メモリーのみ)を選択します。


アプリケーションのインポートを実行するボタンIMPORTを作成します。

識別ラベルImportとします。外観ホットオンにし、テンプレート・オプションWidthStretchを設定します。

動作アクションはデフォルトのページの送信のまま、変更しません。


プロセス・ビューを開き、アプリケーションをインポートするプロセスを作成します。

識別名前アプリケーションのインポートタイプAPIの呼出しとします。設定タイプとしてPL/SQLパッケージを選択し、パッケージUTL_APEX_REMOTEプロシージャまたはファンクションとしてIMPORT_APPLICATIONを選びます。

成功メッセージアプリケーションはインポートされました。とします。サーバー側の条件ボタン押下時IMPORTを設定します。


以上でアプリケーションのインポート処理が実装できました。

続いてアプリケーションのエクスポートを実装します。

アプリケーションをエクスポートするプロセスを、Ajaxコールバックとして作成します。

識別名前EXPORTタイプコードの実行を選びます。Ajaxコールバックとして作成したプロセスの場合、タイプAPIの呼出しを選ぶことはできません(不具合か仕様かは不明です)。そのためソースPL/SQLコードとして、プロシージャUTL_APEX_REMOTE.EXPORT_APPLICATIONの呼び出しを記述します。
utl_apex_remote.export_application(
    p_application_id        => :P3_APPLICATION_ID
    ,p_instance_url         => :P3_INSTANCE_URL
    ,p_workspace_name       => :P3_WORKSPACE_NAME
    ,p_credential_static_id => :P3_CREDENTIAL_STATIC_ID
);

対話モード・レポートの列EXPより、このAjaxコールバックのプロセスEXPORTを呼び出します。

EXPを選択し、識別タイプリンクに変更します。次のスクリーンショットにあるようにターゲットを設定したのち、リンク・テキストに以下を設定します。リンクをボタンとして表示します。

<button type="button" class="t-Button">Export</button>


ターゲットページアイテムの設定名前P3_APPLICATION_ID#APPLICATION_ID#を設定します。クリックしたボタンEXPORTがある行のアプリケーションIDがページ・アイテムP3_APPLICATION_IDに設定されます。AjaxコールバックEXPORTP3_APPLICATION_IDの値より、エクスポートするアプリケーションを決定します。

詳細リクエストAPPLICATION_PROCESS=EXPORTを設定することにより、AjaxコールバックEXPORTが呼び出されます。


アプリケーションを削除するプロセスを、Ajaxコールバックとして作成します。

識別名前DELETEタイプコードの実行ソースPL/SQLコードとして以下を記述します。
utl_apex_remote.delete_application(
    p_application_id        => apex_application.g_x01
    ,p_instance_url         => :P3_INSTANCE_URL
    ,p_workspace_name       => :P3_WORKSPACE_NAME
    ,p_credential_static_id => :P3_CREDENTIAL_STATIC_ID
    ,p_refresh_collection   => true
    ,p_collection_name      => :G_WORKSPACE_APPLICATIONS
);

JavaScriptによるAPEXアクションとしてdelete-applicationを作成し、そのアクションの引数idアプリケーションIDを渡してAjaxコールバックのプロセスDELETEを呼び出すようにします。

ページ・プロパティJavaScriptページ・ロード時に実行に以下を記述します。



対話モード・レポートの列DELを選択し、列の書式のHTML式として以下を記述します。カスタム属性data-actionを指定し、APEXアクションdelete-applicationを呼び出しています。

<button type="button" class="t-Button t-Button--danger" data-action="#action$delete-application?id=#APPLICATION_ID#">Delete</button>


以上でアプリケーションは完成です。これで記事の先頭にあるGIF動画のように、別環境のワークスペースにあるアプリケーションの一覧、アプリケーションのインポート/エクスポート/削除ができるようになりました。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-apex-dbapi.zip

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