2024年1月12日金曜日

Google Cloud StorageにCloud Storage JSON APIでアクセスする

Cloud Storage JSON APIを呼び出してGoogle Cloud StorageにアクセスするAPEXアプリケーションを作成します。

作成したアプリケーションは以下のように動作します。


GoogleのVertex AIにアクセスするサービス・アカウントは、以前の記事「GoogleのGemini APIをOracle APEXから呼び出す」で作成したものを使います。また、APEXからアクセスするために使用するWeb資格証明GOOGLE_GEMINI_API_TOKENとして保存されていることを前提とします。

以前の記事よりパッケージUTL_CRED_GOOGLEを少し更新しています。サービス・アカウントの秘密キーより生成したJWTを一旦APEXのWeb資格証明として保存できるようにプロシージャcreate_or_update_jwt_credentialを追加しました。

以下のコードでは生成したJWTをcreate_or_update_jwt_credentialを呼び出し、Web資格証明GOOGLE_GEMINI_API_JWTに保存しています。

保存したWeb資格証明GOOGLE_GEMINI_API_JWTを使ってアクセス・トークンを取得し、取得したアクセス・トークンをWeb資格証明GOOGLE_GEMINI_API_TOKENに保存します。

以前の記事で作成したバケット(名前はmy-gemini-data-1234)に権限を追加します。

新しいプリンシパルにVertex AI Gemini APIにアクセスするために作成したサービス・アカウントのメールを指定し、ロールStorageオブジェクトユーザーを指定します。

作成をクリックして、権限を追加します。


Google Cloud Storageの準備は以上です。

空のアプリケーションを作成します。名前Sample Google Object Storage JSON APIとします。


アプリケーションが作成されたら、アプリケーション定義置換置換文字列としてG_BUCKET_NAME置換値としてmy-gemini-data-1234(または自分で作成したバケット名)を設定します。また、G_CREDENTIALとしてWeb資格証明静的IDであるGOOGLE_GEMINI_API_TOKENを設定します。


Object Storage JSON APIのlistを呼び出すRESTデータ・ソースを作成します。

OpenAPIによるドキュメントがあれば、それを基にRESTデータ・ソースを作成することができるので、Google Bardに聞いてみました。無いみたいです。


APIのリファレンスより、最初からRESTデータ・ソースを作成することにします。

バケットには最低でも1つファイルをアップロードしておきます。ファイルがないとレスポンスに含まれる列が自動検出されません。

共有コンポーネントRESTデータ・ソースを開きます。


作成をクリックします。


RESTデータ・ソースの作成として最初からを選びます。

へ進みます。


データ・ソース・タイプとして簡易HTTPを選びます。名前Google Cloud Storage JSON APIとします。

URLエンドポイントは以下を指定します。バケット名の部分は:bucketとし、URLパラメータとして認識させます。

https://storage.googleapis.com/storage/v1/b/:bucket/o

URLパラメータ1としてbucketが認識されます。my-gemini-data-1234を設定します。これはデフォルト値になります。RESTデータ・ソースを作成した後に変更することも可能です。

へ進みます。


自動的に設定されるベースURLなどを確認します。通常は変更不要です。

へ進みます。


APIの仕様から、パラメータstartOffset、endOffset、pageToken、maxResultsに値を指定することによりページングが可能なようです。APEXが提供しているページ区切りタイプで、これらのパラメータを扱える設定がないのため、ページ区切りタイプとしてページ区切りなしを選択します。

今回の用途ではほとんどバケットにファイルを配置しないためページングを実装する必要はありませんが、maxResultsの推奨値が1000となっているので(デフォルト値は不明)、それ以上のファイルをバケットに含める場合はページングの実装が必要になりそうです。

へ進みます。


認証が必要ですオンにし、静的IDGOOGLE_GEMINI_API_TOKENであるWeb資格証明を選択します。

検出をクリックします。


バケット中のファイルが一覧されていることを確認します。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースGoogle Cloud Storage JSON APIが作成されます。


作成されたRESTデータ・ソースGoogle Cloud Storage JSON APIを編集します。

このRESTデータ・ソースからフォームのページを生成する際に作成削除のボタンが自動的に生成されるように、データベース・アクションとして行の挿入行の削除に対応する操作を追加します。ただし、行の挿入はファイルのアップロード処理になるためRESTデータ・ソースに実装できません。作成ボタンを自動生成するためだけの定義になります。

操作の追加をクリックします。


Google Cloud Storage JSON APIのdelete操作については、以下のAPIリファレンスを参照します。

URLパターンとして/:objectHTTPメソッドとしてDELETEデータベース操作として行の削除を選択します。

作成をクリックします。


パラメータを追加するため、操作DELETEを再度開きます。

編集鉛筆アイコンをクリックします。


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


URLパターンに含めた:objectをパラメータとして設定します。

タイプURLパターン名前object静的オフデータ型文字列です。必須オンにします。

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


行の挿入操作を追加します。行の削除のときと同様に、操作の追加をクリックします。

APIリファレンスとしては以下を参照します。ただし、Object StorageへのファイルのアップロードlはRESTデータ・ソースには実装せず、別にプロセスを作成して実装します。

HTTPメソッドとしてPOSTデータベース操作として行の挿入を設定します。

作成をクリックします。


パラメータbucketを編集します。

編集鉛筆アイコンをクリックします。


デフォルト値削除し、必須オンに変更します。デフォルト値の削除は必ずしも必要ではありませんが、意図していないときにデフォルトのバケットが選択されないようにしています。

変更の適用をクリックします。


今回は省略しますが、Google Cloud StorageのObjectsのResource representationsを参照して、データ・プロファイルを調整することにより、フォームに自動生成されるページ・アイテムをより適切に生成することができます。

データ・プロファイルの編集を開きます。


データ型VARCHAR2の列が複数検出されています。


自動検出されたこれらの列の設定を確認すると、長さがPL/SQLのVARCHAR2の最大値32767になっています。そのため大抵の場合、この列に対応するページ・アイテムはタイプテキスト領域になります。


RESTデータ・ソースの編集を完了します。

変更の適用をクリックします。


作成したRESTデータ・ソースを基にした、対話モード・レポートとフォームのページを作成します。

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


対話モード・レポートを選択します。


対話モード・レポートのページの名前Filesとします。ページ番号です。フォーム・ページを含めるオンにし、フォーム・ページ名としてFileを設定します。フォームページ番号とします。

データ・ソースとしてRESTデータ・ソースを選択し、RESTデータ・ソースに先ほど作成したGoogle Cloud Storage JSON APIを選択します。

ナビゲーションはデフォルトから変更せず、ブレッドクラムの使用ナビゲーションの使用ともにオンにします。

へ進みます。


主キー列1としてID (Varchar2)を指定します。

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


対話モード・レポートとフォームのページが作成されます。

対話モード・レポートのパラメータbucketを選択し、静的値&G_BUCKET_NAME.を設定します。

RESTデータ・ソースが呼び出される際に、パラメータbucketに置換文字列G_BUCKET_NAMEに設定した値(今回の例ではmy-gemini-data-1234)が渡されます。

保存をクリックします。


ページ・デザイナでフォームのページを開きます。

フォームのパラメータbucketについても、静的値として&G_BUCKET_NAME.を設定します。


フォームのパラメータobjectとして、タイプアイテムアイテムP3_NAMEを指定します。


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

ページ作成ウィザードによって作成されたプロセスプロセス・フォームFileは、削除処理のみを実行します。

サーバー側の条件ボタン押下時DELETEを設定します。

また、今回のRESTデータ・ソースでは失われた更新の防止行のロックは実装できません。失われた更新の防止オフ行のロックいいえ挿入後に主キーを返すオフに変更します。


左ペインでレンダリング・ビューを表示します。

アップロードするファイルを選択するページ・アイテムを作成します。

識別名前P3_FILESタイプファイルのアップロードラベルFilesとします。

ストレージタイプ表APEX_APPLICATION_TEMP_FILESファイルをパージするタイミングリクエストの終わりを選択します。一度に複数のファイルをアップロードできるように、複数ファイルの許可オンにします。

セッション・ステートストレージリクエストごと(メモリーのみ)とします。

作成ボタンを押してフォームを開いたときに限り、このページ・アイテムが表示されるよう、サーバー側の条件タイプアイテムはNULLを選択し、アイテムとしてP3_IDを指定します。


ページ・アイテムP3_IDP3_FILESを除いたすべてのページ・アイテムは、ファイルのアップロード時に表示する必要がありません。

これらのページ・アイテムをすべて選択します。サーバー側の条件タイプアイテムはNULLではないを選択し、アイテムとしてP3_IDを指定します。


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

ファイルをアップロードするプロセスを作成します。

識別名前Upload Filesタイプコードを実行とします。

ソースPL/SQLコードとして以下を記述します。

サーバー側の条件ボタン押下時CREATEを指定します。

ページを保存します。


以上でアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

Googleのサービス・アカウント・キーを使って取得したアクセス・トークンの有効期限は最長で1時間のようで、アクセス・トークンを更新する仕組みは別途実装する必要があるでしょう。

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

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