Delta SharingのProvider側の実装を行います。主にLiveLabsのImplement Data Sharing with PL/SQLのLab 2、3、4の作業に相当します。
APEXアプリケーションのProviderのページに、以下の処理を組み込みます。
- Cloud Storage Linkの一覧、作成、削除
- Shareの一覧、作成、削除、パブリッシュ
- Share Tableの一覧、作成(Shareへの表の追加)、削除(Shareからの表の削除)
- Share Versionの一覧
- Share Recipientの一覧、作成、削除、更新
- Share Recipient Grantの一覧、作成、削除
以下より、実装を進めます。
Cloud Storage Linkを一覧する対話モード・レポートを作成します。Body以下に新規にリージョンを作成します。
識別の名前はCloud Storage Links、タイプは対話モード・レポートを選択します。
ソースのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select * from user_lineage_cloud_storage_links
外観のテンプレートにStandardを選択し、テンプレート・オプションを開いてRemove Body Paddingにチェックを入れます。
Cloud Storage Linkの作成と削除を行なうフォームを作成します。
ページの作成を実行し、フォームを選択します。
ページ番号は4、名前はCloud Storage Link、ページ・モードはドロワーを選択します。ソース・タイプにSQL問合せを選択し、SQL SELECT文を入力に以下を記述します。
select
storage_link_id
,storage_link_name
,uri
,credential_name
from user_lineage_cloud_storage_links
ページ・モードにドロワーを選択しているため、ナビゲーションはデフォルトでオフになります。
次へ進みます。
主キー列1としてSTORAGE_LINK_ID (Number)を選択します。
ページの作成をクリックします。
フォームのページが作成されます。
ページ・アイテムP4_STORAGE_LINK_NAMEの識別のタイプをテキスト・フィールドへ変更します。
ページ・アイテムP4_CREDENTIAL_NAMEの識別のタイプを選択リストに変更します。
LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select credential_name d, credential_name r from user_credentials
追加値の表示はオフ、NULL値の表示はオン、NULL表示値として- Select Credential -を記述します。
プロセス・ビューを開き、Cloud Storage Linkの作成と削除を行なうプロセスを作成します。
最初にすでに作成済みのプロセスプロセス・フォームCloud Storage Linkをコメント・アウトします。
Cloud Storage Linkを作成するプロセスを作成します。
識別の名前はCreate、タイプはコードを実行とします。ソースのPL/SQLコードとして以下を記述します。
begin
dbms_share.create_or_replace_cloud_storage_link(
storage_link_name => :P4_STORAGE_LINK_NAME
,uri => :P4_URI
);
if :P4_CREDENTIAL_NAME is not null then
dbms_share.set_storage_credential(
storage_link_name => :P4_STORAGE_LINK_NAME
,credential_name => :P4_CREDENTIAL_NAME
);
end if;
end;
サーバー側の条件のボタン押下時にCREATEを指定します。
Cloud Storage Linkを削除するプロセスを作成します。
識別の名前はDelete、タイプはコードを実行とします。ソースのPL/SQLコードとして以下を記述します。
begin
dbms_share.drop_cloud_storage_link(
storage_link_name => :P4_STORAGE_LINK_NAME
);
end;
サーバー側の条件のボタン押下時にDELETEを指定します。
最低限必要な機能がフォームに実装できました。もっと調整できる箇所もありますが(例えばボタンSAVEの扱いや、プロシージャ呼び出しへの引数の追加)、記事が長くなりすぎるため最低限の実装に留めます。
Providerのページを開き、対話モード・レポートCloud Storage Linksがフォームのページと連携するように、ボタンや設定を追加します。
対話モード・レポートCloud Storage Linksにボタンを作成します。
識別のボタン名はCREATE_CLOUD_STORAGE_LINK、ラベルはCreateとします。レイアウトのスロットは対話モード・レポートの検索バーの右を選択します。
動作のアクションにこのアプリケーションのページにリダイレクトを選択し、ターゲットとして先ほど作成したフォームのページ4を指定します。
対話モード・レポートCloud Storage Linksの属性タブを開き、リンク列としてカスタム・ターゲットへのリンクを選択します。ターゲットはページ4です。
リンク・ビルダーを開き、ターゲットのページは4、アイテムの設定の名前に主キー列に対応するページ・アイテムP4_STORAGE_IDと、値に列\#STORAGE_LINK_ID#\を設定します。
フォームが閉じた時に対話モード・レポートCloud Storage Linksがリフレッシュされるよう、対話モード・レポートに動的アクションを作成します。
識別の名前はonClose Dialog Cloud Storage Linkとします。タイミングのイベントはダイアログのクローズ、選択タイプはリージョン、リージョンとしてCloud Storage Linksを選択します。
TRUEアクションはリフレッシュ、影響を受ける要素の選択タイプはリージョン、リージョンはCloud Storage Linksになります。
以上でCloud Storage Linkに関する実装は完了です。
アプリケーションを実行して、動作を確認してみます。
対話モード・レポートCloud Storage Links上にあるボタンCreateをクリックします。
Storage Link Nameは
DATA_SHARE_STORAGE_LINKとします、
Uriにデータ共有用に作成した
オブジェクト・ストレージ上のバケットへのURLを入力し、
Credential Nameに
SHARE_BUCKET_CREDENTIALを選択します。
作成をクリックします。
対話モード・レポート上に作成したCloud Storage Link、DATA_SHARE_STORAGE_LINKが表示されます。
続いてShareについて実装します。
作成する対話モード・レポートSharesのソースのSQL問合せは以下になります。外観の設定は同じです。
select * from user_shares
Shareを操作するために作成するフォームのページは、ページ番号が5、名前はShare、データ・ソースのSQLには以下を記述します。
select
share_id
,share_name
,share_type
,'' storage_link_name
from user_shares
主キー列1にはSHARE_IDを選択します。
フォームのページShareが作成されます。
ページ・アイテムP5_SHARE_TYPEの識別のタイプを選択リストに変更します。LOVのタイプに静的値を選択し、静的値としてVERSIONED、LIVEのふたつ(表示値と戻り値は同じ)を設定します。追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Type -と記述します。
静的値の設定です。表示値、戻り値ともにVERSIONED、LIVEを設定します。設定順で表示するには、ソートの実行時にソートをオフにします。
ページ・アイテム
P5_STORAGE_LINK_NAMEの
タイプを
選択リストに変更します。
LOVの
タイプを
SQL問合せ、
SQL問合せとして以下を記述します。
select storage_link_name d, storage_link_name r from user_lineage_cloud_storage_links
追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Storage Link -と記述します。
Shareの作成、削除、Publishを行なうプロセスを作成します。デフォルトで作成されているプロセスプロセス・フォームShareはコメント・アウトします。
プロセスCreateでは、以下のコードを実行します。ボタンCREATEの押下で実行します。
begin
dbms_share.create_share(
share_name => :P5_SHARE_NAME
,share_type => :P5_SHARE_TYPE
,storage_link_name => :P5_STORAGE_LINK_NAME
);
end;
プロセスDeleteでは、以下のコードを実行します。ボタンDELETEの押下で実行します。
begin
dbms_share.drop_share(
share_name => :P5_SHARE_NAME
);
end;
プロセスPublishでは、以下のコードを実行します。ボタンSAVEの押下で実行します。
begin
dbms_share.publish_share(
share_name => :P5_SHARE_NAME
);
end;
レンダリング・ビューに戻り、ボタンSAVEのラベルをPublishに変更します。
以上でフォームについては完成です。
Providerのページに戻り対話モード・レポートSharesに、ボタンCREATE_SHAREを作成します。ターゲットはページ5になります。
属性のリンク列をカスタム・ターゲットへのリンクとし、ターゲットはページ5、主キーのアイテムの名前としてP5_SHARE_ID、値となる列に\#SHARE_ID#\を指定します。
ダイアログがクローズしたときに対話モード・レポートSharesをリフレッシュする動的アクションを作成します。識別の名前はonClose Dialog Shareとします。
以上でSharesについて出来上がりました。動作を確認してみます。
アプリケーションを実行し、対話モード・レポートSharesにあるボタンCreateをクリックします。
Share Nameにdemo_share、Share TypeにVERSIONED、Storage Link NameにDATA_SHARE_STORAGE_LINKを選択し、作成をクリックします。
ShareとしてDEMO_SHAREが作成されます。
Publishは表をShareに追加した後に実行します。
次にShareへ表を追加する、または、Shareから表を削除する機能を実装します。
作成する対話モード・レポートShare TablesのソースのSQL問合せは以下になります。
select * from user_share_tables
Shareに表を追加したり削除したりするフォームのページは、ページ番号が6、名前はShare Table、データ・ソースのSQLには以下を記述します。
select
share_table_id
,share_name
,table_name
,share_table_name
from user_share_tables
主キー列1にはSHARE_TABLE_IDを選択します。
フォームのページShare Tableが作成されます。
ページ・アイテムP6_SHARE_NAMEの識別のタイプを選択リストに変更します。LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select share_name d, share_name r from user_shares
追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Share -と記述します。
ページ・アイテムP6_TABLE_NAMEの識別のタイプをポップアップLOVに変更します。LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select table_name from user_tables
追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Table -と記述します。
ページ・アイテムP6_SHARE_TABLE_NAMEの識別のタイプをテキスト・フィールドに変更します。このページ・アイテムの値はDBMS_SHARE.ADD_TO_SHAREの引数share_table_nameに与えられる値ですが、デフォルトをP6_TABLE_NAMEとするために検証の必須の値はオフにします。あわせて、外観のテンプレートをOptional - Floatingに変更します。
Shareへの表の追加および削除を行なうプロセスを作成します。デフォルトで作成されているプロセスプロセス・フォームShare Tableをコメント・アウトします。
プロセスCreateでは、以下のコードを実行します。ボタンCREATEの押下で実行します。
begin
dbms_share.add_to_share(
share_name => :P6_SHARE_NAME
,table_name => :P6_TABLE_NAME
,share_table_name => coalesce(:P6_SHARE_TABLE_NAME,:P6_TABLE_NAME)
);
end;
プロセスDeleteでは、以下のコードを実行します。ボタンDELETEの押下で実行します。
begin
dbms_share.remove_from_share(
share_name => :P6_SHARE_NAME
,share_table_name => :P6_SHARE_TABLE_NAME
);
end;
以上でフォームは完成です。
Providerのページに戻り対話モード・レポートShare Tablesに、ボタンCERATE_SHARE_TABLEを作成します。ターゲットはページ6になります。
属性のリンク列をカスタム・ターゲットへのリンクとし、ターゲットはページ6、主キーのアイテムの名前としてP6_SHARE_TABLE_ID、値となる列に\#SHARE_TABLE_ID#\を指定します。
ダイアログがクローズしたときに対話モード・レポート
Share Tablesを
リフレッシュする
動的アクションを作成します。
識別の
名前は
onClose Dialog Share Tableとします。
以上でShare Tablesについて出来上がりました。動作を確認してみます。
アプリケーションを実行し、対話モード・レポートShare TablesにあるボタンCreateをクリックします。
Share NameにDEMO_SHARE、Tables NameにCUSTSALESを選択し、作成をクリックします。
ShareのDEMO_SHAREに表CUSTSALESが、Share Table NameがCUSTSALESとして追加されます。
この後、ShareのDEMO_SHAREをPublishすることにより表CUSTSALESが共有できるようになります。
その作業の前に、Publishされた状況を一覧する対話モード・レポートを作成します。
作成する対話モード・レポートShare VersionsのソースのSQL問合せは以下になります。
select * from user_share_versions
今回はShare Versionの削除といった処理を組み込まず、単にShare Versionの表示のみを行います。
最新の状態のShare Versionsを表示するため、対話モード・レポートをリフレッシュするボタンを作成します。
ボタン名はREFRESH_SHARE_VERSIONS、ラベルはRefreshとします。レイアウトのスロットは対話モード・レポートの検索バーの右を選択します。動作のアクションは動的アクションで定義です。
ボタンREFRESH_SHARE_VERSIONSに動的アクションを作成します。識別の名前はonClick Refresh Share Versions、タイミングのイベントは、ボタンのデフォルトのクリックです。
TRUEアクションにはリフレッシュ、影響を受ける要素の選択タイプにリージョンを選択し、リージョンとしてShare Versionsを選びます。
これからアプリケーションを実行し、ShareをPublishします。
Always FreeのAutonomous Databaseで作業を行っている場合は、あらかじめ以下のコマンドを実行します。
BEGIN
DBMS_SHARE.UPDATE_DEFAULT_SHARE_PROPERTY('job_type', 'DBMS_CLOUD');
END;
LiveLabsでは、この設定を行なう理由について説明されていませんが、おそらく表をオブジェクト・ストレージにエクスポートする際にDBMS_CLOUD.EXPORT_DATAを使うように設定していると思われます。デフォルトはODI - Oracle Data Integratorを使用します。
対話モード・レポートSharesのDEMO_SHAREのフォームを開きます。
開いたドロワーにあるボタンPublishをクリックします。
ドロワーが閉じます。
ボタンPublishを押してドロワーが閉じたときに自動的に対話モード・レポートShare Versionsがリフレッシュされないため、ボタンRefreshをクリックします。
対話モード・レポートShare VersionsにDEMO_SHAREの行が表示されます。StatusはEXPORTINGで、時間が経つとCURRENTに変わります。
少し時間をおいてRefreshを再度クリックすると、StatusがCURRENTに変わっていることが確認できます。
この状態で、オブジェクト・ストレージのバケットにparquetファイルがエクスポートされていることが確認できます。
データに関する設定は以上で完了です。
これから、Consumer側で使用する受信者、つまりShare Recipientの一覧、作成、削除を実装します。
作成する対話モード・レポートShare RecipientsのソースのSQL問合せは以下になります。
select * from user_share_recipients
Share Recipientの作成や削除を行なうフォームのページは、ページ番号が7、名前はShare Recipient、データ・ソースのSQLには以下を記述します。
select
recipient_id,
recipient_name,
'' email,
'' recipient_property,
'' new_value
from user_share_recipients
主キー列1にはRECIPIENT_IDを選択します。
フォームのページShare Recipientが作成されます。
ページ・アイテムP7_RECIPIENT_NAMEの識別のタイプをテキスト・フィールドに変更します。
この他のページ・アイテムも、タイプがテキスト・フィールドでない場合、テキスト・フィールドに変更します。
Share Recipientの作成、削除、更新を行なうプロセスを作成します。デフォルトで作成されているプロセスプロセス・フォームShare Recipientをコメント・アウトします。
プロセスCreateでは、以下のコードを実行します。ボタンCREATEの押下で実行します。
begin
dbms_share.create_or_replace_share_recipient(
recipient_name => :P7_RECIPIENT_NAME
,email => :P7_EMAIL
);
end;
プロセスDeleteでは、以下のコードを実行します。ボタンDELETEの押下で実行します。
begin
dbms_share.drop_recipient(
recipient_name => :P7_RECIPIENT_NAME
);
end;
プロセスSaveでは、以下のコードを実行します。ボタンSAVEの押下で実行します。
begin
dbms_share.update_recipient_property(
recipient_name => :P7_RECIPIENT_NAME
,recipient_property => :P7_RECIPIENT_PROPERTY
,new_value => :P7_NEW_VALUE
);
end;
以上でフォームは完成です。
Providerのページに戻り対話モード・レポートShare Recipientsに、ボタンCREATE_SHARE_RECIPIENTを作成します。ターゲットはページ7になります。
属性のリンク列をカスタム・ターゲットへのリンクとし、ターゲットはページ7、主キーのアイテムの名前としてP7_RECIPIENT_ID、値となる列に\#RECIPIENT_ID#\を指定します。
ダイアログがクローズしたときに対話モード・レポートShare Recipientsをリフレッシュする動的アクションを作成します。識別の名前はonClose Dialog Share Recipientとします。
以上でShare Recipientsについて出来上がりました。動作を確認してみます。
アプリケーションを実行し、対話モード・レポートShare RecipientsにあるボタンCreateをクリックします。
Recipient Nameに
training_user、
Emailに
training_user@oracle.comを入力し、
作成をクリックします。
Share Recipientsとして
TRAINING_USERが追加されます。
Share RecipientのTRANING_USERのプロパティを更新します。編集アイコンをクリックし、ドロワーを開きます。
Recipient PropertyにTOKEN_LIFETIMEを入力し、New Valueとして90 00:00:00を入力します。
変更の適用をクリックします。
ドロワーが閉じます。
Share RecipientがShareにアクセスする権限を与える機能を実装します。
作成する対話モード・レポートShare Recipient GrantsのソースのSQL問合せは以下になります。
select * from user_share_recipient_grants
Share RecipientがShareにアクセスする権限を与えるフォームは、ページ番号が8、名前はShare Recipient Grant、データ・ソースのSQLには以下を記述します。
select
recipient_id,
share_id,
recipient_name,
share_name
from user_share_recipient_grants
主キー列1として
RECIPIENT_ID、
主キー列2として
SHARE_IDを選択します。
フォームのページ
Share Recipient Grantが作成されます。
ページ・アイテムP8_RECIPIENT_NAMEの識別のタイプを選択リストに変更します。LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select recipient_name d, recipient_name r from user_share_recipients
追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Share Recipient -と記述します。
ページ・アイテムP8_SHARE_NAMEの識別のタイプを選択リストに変更します。LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select share_name d, share_name r from user_shares
追加値の表示はオフ、NULL値の表示はオン、NULL表示値は- Select Share -と記述します。
Share RecipientにShareへアクセスする権限を与えるプロセスを作成します。デフォルトで作成されているプロセスプロセス・フォームShare Recipient Grantはコメント・アウトします。
プロセスCreateでは、以下のコードを実行します。ボタンCREATEの押下で実行します。
begin
dbms_share.grant_to_recipient(
share_name => :P8_SHARE_NAME
,recipient_name => :P8_RECIPIENT_NAME
);
end;
プロセス
Deleteでは、以下のコードを実行します。ボタン
DELETEの押下で実行します。
begin
dbms_share.revoke_from_recipient(
share_name => :P8_SHARE_NAME
,recipient_name => :P8_RECIPIENT_NAME
);
end;
以上でフォームは完成です。
Providerのページに戻り対話モード・レポートShare Recipient Grantsに、ボタンCREATE_SHARE_RECIPIENT_GRANTを作成します。ターゲットはページ8になります。
属性のリンク列をカスタム・ターゲットへのリンクとし、ターゲットはページ8、主キーのアイテムの名前としてP8_RECIPIENT_ID、値となる列に\#RECIPIENT_ID#\、また、名前としてP8_SHARE_ID、値となる列に\#SHARE_ID#\の2行を指定します。
ダイアログがクローズしたときに対話モード・レポートShare Recipient Grantsをリフレッシュする動的アクションを作成します。識別の名前はonClose Dialog Share Recipient Grantとします。
以上でShare Recipient Grantsについて出来上がりました。動作を確認してみます。
アプリケーションを実行し、対話モード・レポートShare Recipient GrantsにあるボタンCreateをクリックします。
Recipient Nameに
TRAINING_USER、
Share Nameに
DEMO_SHAREを選択し、
作成をクリックします。
Recipient NameのTRAINING_USERにShare NameのDEMO_SHAREにアクセスする権限が割り当てられました。
以上で、Share RecipientのTRAINING_USERがDEMO_SHAREへアクセスする権限が割り当てられました。
Delta SharingのConsumerが使用するプロファイルを取得します。
最初にプロファイルが記載されたJSONファイルをダウンロードするリンクを生成します。SQLコマンドで以下を実行します。
BEGIN
DBMS_OUTPUT.PUT_LINE(DBMS_SHARE.GET_ACTIVATION_LINK('TRAINING_USER'));
END;
一度だけ利用できる、プロファイルのダウンロード・リンクが出力されます。
リンクをブラウザにコピペして開きます。本来であれば、Consumerとなる人にこのリンクを安全な方法で送信します。
Delta Sharingのプロファイルをファイルとして取得するページが表示されます。Get Profile Informationをクリックします。
なぜか、リンクがすでに使用済みか期限切れか不正かのどれかの理由で、プロファイルのダウンロードを拒否されます。
仕方がないので、SQLclでワークスペース・スキーマwksp_dwapexに直接接続し、以下のSQLコマンドを実行しました。
set serveroutput on
set lines 180 pages 100 trims on trimo on
declare
v_share_profile sys.json_object_t;
v_share_profile_text varchar2(4000);
begin
dbms_share.populate_share_profile(
recipient_name => 'TRAINING_USER',
share_profile => v_share_profile
);
v_share_profile_text := v_share_profile.to_string;
dbms_output.put_line (json_query(v_share_profile_text, '$' pretty));
end;
/
Delta SharingのConsumerが必要とするプロファイルが、JSONドキュメントとして印刷されます。
% sql -cloudconfig Wallet_DWAPEX.zip wksp_dwapex@dwapex_low
SQLcl: 水 7月 10 19:03:45 2024のリリース23.4 Production
Copyright (c) 1982, 2024, Oracle. All rights reserved.
パスワード (**********?) **************
接続先:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.24.0.1.0
SQL> set serveroutput on
SQL> set lines 180 pages 100 trims on trimo on
SQL> declare
v_share_profile sys.json_object_t;
v_share_profile_text varchar2(4000);
begin
dbms_share.populate_share_profile(
recipient_name => 'TRAINING_USER',
share_profile => v_share_profile
);
v_share_profile_text := v_share_profile.to_string;
dbms_output.put_line (json_query(v_share_profile_text, '$' pretty));
end;
/
{
"shareCredentialsVersion" : 1,
"endpoint" : "https://ge***********f-dwapex.adb.ca-toronto-1.oraclecloudapps.com/ords/dwapex/_delta_sharing/",
"bearerToken" : "**********************",
"tokenEndpoint" : "https://ge***********f-dwapex.adb.ca-toronto-1.oraclecloudapps.com/ords/dwapex/oauth/token",
"clientID" : "**********************",
"clientSecret" : "**********************"
}
PL/SQLプロシージャが正常に完了しました。
このプロファイルを使って、Consumerの設定を行います。
続く