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

2023年1月20日金曜日

Microsoft OneDriveを操作するAPEXアプリの作成(7) - ODataプラグイン

 せっかくMicrosoft Azure ADによるOIDC認証の構成を行ったので、RESTデータ・ソースを簡易HTTPからODataプラグインに置き換えてみました。

Oracle APEXのODataプラグインについては、以下のAPEX Office Hourで紹介されています。

APEX and OData? REST Data Sources at your service!
https://asktom.oracle.com/pls/apex/asktom.search?oh=19326


ODataプラグインのインストール


ODataプラグインは、GitHubの以下のリンクから取得できます。

odata_connector_sample_app.zipをダウンロードし、APEXのワークスペースに一般的なAPEXアプリケーションとしてインポートします。


ODataプラグインは以下のパッケージに実装されています。

PLG_ODATA_CONNECTOR
PLG_ODATA_FILTERS
PLG_ODATA_METADATA
PLG_ODATA_ORDER_BYS

これらのパッケージの作成は、サンプル・アプリケーションのインストール・スクリプトに含まれています。そのため、サンプル・アプリケーションをインポートする際にサポートするオブジェクトのインストールは必ずONにします。


ODataプラグインの実装であるweb_source_type_plugiin_odata-connector.sqlを、プラグインとしてインポートするだけでは上記のパッケージが作成されません。そのため、プラグインのインポートだけではODataプラグインは動作しません。

サンプル・アプリケーションのインポートが、ODataプラグインをインストールする最も簡単な方法です。


ODataプラグインの作成



共有コンポーネントプラグインを開きます。


作成済みのプラグインが一覧されます。作成をクリックします。


プラグインの作成として既存のプラグインのコピーを選択します。

へ進みます。


アプリケーションからコピーとしてSample ODATA-Connectorを選択します。

へ進みます。


コピー対象として、タイプRESTデータ・ソース名前OData REST Serviceというプラグインが表示されます。

コピーしますか?として、はいまたはコピーおよびサブスクライブのどちらかを選択します。

プラグインのコピーをクリックします。


ODataプラグインが作成されました。


OData REST ServiceプラグインによるRESTデータ・ソースが作成できるようになりました。


RESTデータ・ソースの作成



今までの記事で作成したRESTデータ・ソース、My Drives、My Root、My Folderと同じRESTデータ・ソースを、OData REST Serviceプラグインを使用して作成します。

作成済みのRESTデータ・ソースのエンドポイントURLをメモしておきます。OData REST Serviceプラグインでは、簡易HTTPでのエンドポイントURLを、エンドポイントURLResource Pathに分割して登録します。


はじめにMy Drivesと同じRESTデータ・ソースを作成します。

RESTデータ・ソース・タイプとしてOData REST Serivce[プラグイン]を選択します。名前OData My Drivesとします。URLエンドポイントとして、以下を指定します。

https://graph.microsoft.com/v1.0/me/

へ進みます。


リモート・サーバーおよびサービスURLパスは自動的に決まります。

変更せずにへ進みます。


OData REST Serviceプラグインとしての設定になります。

Resource Pathdrivesとします。エンドポイントURL + Resource Pathが実際にリクエストされるGraph APIのURLです。

へ進みます。


認証を設定します。

これ以降は、タイプが簡易HTTPで作成したRESTデータ・ソースMy Drivesと同じ作業を行います。サンプル・レスポンスdrives.jsonを使用してデータ・プロファイルを更新します。


OData REST SerivceプラグインによるRESTデータ・ソースでは、ODataとしてサポートされている機能を選択する必要があります。サポートされていない機能が有効になっていると、REST APIの発行時にエラーが発生します。

Microsoftのドキュメントより、サポートされている機能を確認します。

Microsoft Graphでのファイルの作業

ドライブを一覧表示するでは、以下のように$expand$select$skipToken$top$orderbyがサポートされているとのことです。


設定項目のオンライン・ヘルプに、対応するODataのクエリパラメーターの説明が記述されています。

このRESTデータ・ソースでは、Basic OptionsSource supports orderingSource supports querying of specific columnsにチェックを入れます。


Source supports client-driven paginationですが、ページネーションはOData REST Serivceプラグインではクエリパラメーターの$top$skipを使って実施します。Microsoftの以下のドキュメントによると、$skipは問題があるため$skipTokenを代わりに使うとのことです。

Use $skiptoken for server-driven paging
https://learn.microsoft.com/en-us/odata/webapi/skiptoken-for-server-side-paging

OData REST Serviceプラグインは$skipTokenを使用したページネーションをサポートしていないため、Graph APIが$skipではなく$skipTokenを実装している場合は、Source supports clilent-driven paginationにチェックを入れることはできません。

続いてMy Rootと同じRESTデータ・ソースOData My Rootを作成します。

Resource Pathdrive/root/childrenになります。その他は、My Rootの作成と同じ手順になります。


ドライブの項目子を一覧表示するオプションのクエリパラメーターは以下です。


先ほどと同じなので、Basic OptionsSource supports orderingSource supports querying of specific columnsにチェックを入れます。


最後にMy Folderと同じRESTデータ・ソースOData My Folderを作成します。

Resource Pathとしてdrive/items/:item_id/childrenを指定します。Resource Pathに含まれるパラメータはURLエンドポイントとは異なり、パラメータとして自動的に検出されません。そのため、RESTデータ・ソース作成後に手作業でパラメータitem_idを追加します。

これ以降の作業はRESTデータ・ソースMy Folderと同じです。


RESTデータ・ソースOData My Folderを作成し、Basic Optionsの設定を行った後に、パラメータの追加を行います。


パラメータの追加をクリックします。


パラメータタイプとしてURLパターン変数を選択します。名前item_idデフォルト値になります。フォルダのDriveItemのIDを入力しておきます。空でも問題ありません。

目的入力詳細必須ONにします。

以上で、パラメータの追加をクリックします。


パラメータが追加されました。変更の適用をクリックします。


以上で、RESTデータ・ソースOData My DrivesOData My RootOData My Folderの作成は完了です。




対話モード・レポートの更新



作成済みの対話モード・レポートのデータ・ソースを入れ替えます。

レポートMy Drivesについては、ソースRESTソースをMy DrivesからOData My Drivesに変更するだけです。


レポートMy Rootでは、ソースの変更前にローカル後処理SQL問合せコピーを取得しておきます。


ソースRESTソースOData My Rootに変更します。ローカル後処理が初期化されるため、先ほどコピーした値で設定を回復します。


レポートFolderRESTソースOData My Folderに変更します。ローカル後処理SQL問合せは元の設定をコピーし、ソース変更後に回復させます。


レポートFolderの場合、パラメータの設定もリセットされます。

パラメータitem_idを選択し、タイプアイテムアイテムP3_ITEM_IDに設定し直します。


以上で対話モード・レポートの更新は完了です。


ODataプラグインのデバッグ



以上の設定でアプリケーションを実行すると、レポートの表示でエラーが発生しました。


最初にデバッグ出力を有効にして、エラー・メッセージを確認します。


エラー・メッセージは以下です。\"@microsoft, という部分が悪いことはわかりますが、これだけだとデバッグは難しいです。

Parsing OData Select and Expand failed: Syntax error: character '\"' is not valid at position 128 in 'eTag,file,size,lastModifiedBy,createdDateTime,folder,webUrl,fileSystemInfo,cTag,shared,reactions,name,createdBy,parentReference,\"@microsoft,specialFolder,lastModifiedDateTime,id

APEXから発行されたREST APIへのリクエストは、ビューAPEX_WEBSERVICE_LOGから確認できます。

アプリケーション・ビルダーワークスペース・ユーティリティから、Oracle APEXビューを開きます。


ビューの一覧よりAPEX_WEBSERVICE_LOGを探して、開きます。


としてURLHTTP_METHODSTATUS_CODEREQUEST_DATEを含めて、結果をクリックします。


フィルタを設定するなどして行を絞り込み、エラーが発生したURLを特定します。

特定したURLをコピーしておきます。


Graph APIを直接発行する画面より、コピーしたURLを呼び出します。同じエラーが発生します。


"@microsoft,の部分の除き、APIを発行すると成功します。


以上より、ODataのクエリパラメータ$selectに渡されている引数に問題があることがわかります。

RESTデータ・ソースのデータ・プロファイルより、@microsoftで始まるセレクタを確認します。

DOWNLOADURLが見つかりました。


DOWNLOADURLのセレクタは"@microsoft.graph.downloadUrl"ですが、このような形式のセレクタをOData REST Sourceプラグインは正しく扱えないようです。


列DOWNLOADURLはアプリケーションで使用しているため、削除することはできません。

設定Source supports querying of specific columnsのチェックを外すことで対応します。


RESTデータ・ソースOData My RootOData My Folderともに、この設定を外すことにより、ODataプラグインによるRESTデータ・ソースに変更したアプリケーションが動作するようになります。

$skipTokenやセレクタなど、OData REST ServiceプラグインのMicrosoft Graph APIとの互換性については残念な部分もありますが(オープンソースなので自分で修正することもできます)、OData自体は将来性があると思います。

変更後のアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/onedrive-operation-odata.zip

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

追記

パッケージplg_odata_connector.pkbに以下の記述があり、この部分(regexp_replace)がOneDriveのGraph APIと互換性がないようです。セレクタにはピリオドが含まれないという前提になっています。Graph APIは属性valueにJSONオブジェクトの配列が返しますが、一行にあたるJSONオブジェクトはスカラー値のみを含みJSONオブジェクトは含まない、と想定されているようです。
        --
        -- Cleanup the requested attribute before selection
        --
        l_requested_column_list := regexp_replace( l_requested_column_list, '\.[^\,]*' );

        select distinct
            regexp_replace( column_value, '\.[^\,]*' )
        bulk collect into
            l_arr_requested_attribute
        from
            apex_string.split( l_requested_column_list, ',' );

        l_requested_column_list := apex_string.join( l_arr_requested_attribute, ',' );

さて、どうしたものかとは思いますが、オープンソースだと自分で調べることはできます。

2023年1月19日木曜日

Microsoft OneDriveを操作するAPEXアプリの作成(6) - その他

 アプリケーションを作成していて気付いたことを紹介します。


アクセストークンの有効期間


Microsoft社のドキュメントに、Azure ADが発行するアクセストークンの有効期間について説明があります。

https://learn.microsoft.com/ja-jp/azure/active-directory/develop/access-tokens#access-token-lifetime

アクセス トークンの既定の有効期間は、可変です。 発行されると、アクセス トークンの既定の有効期間には、60 分から 90 分 (平均 75 分) の範囲のランダムな値が割り当てられます。

 APEXアプリケーションのセッションの有効期限は、アプリケーション定義セキュリティセッション管理に、最大セッションの長さ(秒)として設定できます。


指定がない場合、インスタンスに設定されている値になります。

この値はアクセストークンの有効期間以下に設定する必要があります。

最大セッションの長さ(秒)がアクセストークンの有効期間より長いと、アクセストークンの有効期間が過ぎた時点でGraph APIのエラーが発生します。


再度、APEXアプリケーションにサインインし直してアクセス・トークンを取得すれば回復します。しかし、APEXアプリケーションよりサインアウトを行うとAzure ADからもサインアウトします。


以下のページに遷移します。


APEXのセッションのみを再確立する場合は、URLのsession=の値を0に変更してアプリケーションを呼び出します。

https://ホスト名/ords/r/ワークスペース/アプリケーション別名/ページ別名?session=0

Azure ADによるサインイン時に、サインインの状態を維持しますか?と聞かれています。それにはいと答えていれば、APEXのセッションを再確立する際に再度ユーザー認証を要求されることはありません。

APEXの最大セッションの長さのデフォルトは28800秒=8時間と長いので、あまり以下のようなセッション・タイムアウト警告を見ることはありません。


上記の警告は、ユーザーにAPEXアプリケーションに再度サインインを行うことを要求しています。サインインをし直すまでは警告が表示され続けますが、今まで説明しているようにナビゲーション・メニューからサインアウトすると、Azure ADからサインアウトします。

実際にはAPEXのセッションのみを再確立すれば良いので、引数sessionに0を渡すようなアクセスが必要です。

最終的にセッションがタイムアウトすると、以下のポップアップが表示されます。


ここで再度サインインしてくださいをクリックすると、Azure ADからはサインアウトしていないため、Azure ADによるユーザー認証なしで新しいAPEXセッションが確立します。

セッション・タイムアウト警告(秒)0に設定すると、警告のポップアップを抑止することはできます。


この場合、警告ポップアップは表示されませんが、例えばフォームにいろいろデータを入力した後に送信ボタンを押した時点でタイムアウトが発生する可能性が出てきます。それまでの作業は無くなってしまいます。

一つの例ですが、ナビゲーション・バーに以下のようなエントリを作成して対応することもできます。

ターゲットタイプとしてURLを選択し、URLターゲットに以下を指定します。sessioin=0を含めています。(ワークスペース名を直書きしています。異なる場合は変更の必要があります。)

/ords/r/apexdev/onedrive-operation/home?session=0


ナビゲーション・バーにセッションの継続というエントリが追加され、このリンクをクリックすることにより再認証をせずにアクセストークンの更新ができるようになります。

Azure ADでのアプリケーションのアクセス許可としてoffline_accessを含めているため、Azure ADとしてはリフレッシュ・トークンの発行は可能です。

しかし、APEXのWeb資格証明のストアド・トークンを確認すると、リフレッシュ・トークンが増えることはありません。


よって、アクセス・トークンの更新をするために、セッションのタイムアウトの度(最長でも1時間おき)に、APEXセッションの再確立が必要になります。


WEBURLについて



DriveItemの一覧を取得すると、属性としてWEBURLというのがありました。対話モード・レポートの列WEBURLのタイプリンクに変更し、ターゲットタイプURLターゲット#WEBURL#に変更して、表示されているリンクをクリックしてみました。


PowerPointファイルでは、ブラウザ版のPowerPointが起動して選択したファイルが開きました。


PDFではPDFのツールが開きました。


便利。その他にも沢山の属性があるようです。

Microsoft OneDriveを操作するAPEXアプリケーションに関する記事は、これで完了です。

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