2024年4月4日木曜日

PL/SQL Gateway mode of pool |default|lo| is set to proxied but ORDS could not read the proxy configuration from the databaseという警告について

Oracle REST Data Servicesの稼働ログに表題の警告が出力されることがあります。以下のように出力されます。

2024-04-04T04:34:21.581Z WARNING     PL/SQL Gateway mode of pool |default|lo| is set to proxied but ORDS could not read the proxy configuration from the database

oracle.dbtools.url.mapping.db.DatabaseURLMappingBase$PlsqlGatewayConfigurationException: PL/SQL Gateway mode of pool |default|lo| is set to proxied but ORDS could not read the proxy configuration from the database

at oracle.dbtools.url.mapping.db.DatabaseURLMappingBase$PlsqlGatewayProxyUserLoader.call(DatabaseURLMappingBase.java:1350)

at oracle.dbtools.url.mapping.db.DatabaseURLMappingBase$PlsqlGatewayProxyUserLoader.call(DatabaseURLMappingBase.java:1304)

at oracle.dbtools.common.util.AtomicLoader.get(AtomicLoader.java:52)

at oracle.dbtools.url.mapping.db.DatabaseURLMappingBase.getPlsqlGatewayProxyUser(DatabaseURLMappingBase.java:674)


レベルがWARNINGですが、あまりログに出力されるのも気になるので、少し調べてみました。

エラーメッセージは「コネクション・プールがproxiedに設定されているが、proxyに関する構成が見つからない」と言っています。この警告が出力されていても、ORDSはデータベースにプロキシー接続をしています。

ORDSがデータベースに接続する方法は、プールごとに設定するプロパティplsql.gateway.modeによって決まります。

Oracle REST Data Services Installation and Configuration Guide, Release 23.4
C About the Oracle REST Data Services Configuration Files

マニュアルのplsql.gateway.modeには、以下のような説明がされています。

Indicates if the PL/SQL Gateway functionality should be available for a pool or not.

Value can be one of disableddirect, or proxied.

  • If the value is direct, then the pool serves the PL/SQL Gateway requests directly.
  • If the value is PLSQL_GATEWAY_CONFIG, view is used to determine the user to whom to proxy.
マニュアルではデフォルト値はproxiedとなっていますが、これはdisabledの間違いだと思います。

最新のORDS 23.4で確認した範囲では、plsql.gateway.modedirectまたはproxiedを明示的に設定していないとAPEXは動作しませんでした。また、directに設定した場合はORDS_PUBLIC_USERを接続ユーザーとして(APEX_PUBLIC_USERまたはORDS_PLSQL_GATEWAYといったPL/SQLゲートウェイ・ユーザーではなく)APEXが実行されます。ORDS_PUBLIC_USERが持つ権限はAPEXを動かすことは考慮されていないため、正常に動く保証がありません。APEXを動かすためだけの専用のコネクション・プールが作成されていた頃と、互換性を保つための設定と思われます。

確認した範囲では、Oracle APEXを動作させるためには、明示的にplsql.gateway.modeproxiedを設定する必要がありました。標準的な手順でORDSをインストールしていると、意識しなくてもplsql.gateway.modeproxiedに設定されます。

Oracle REST Data Servicesのコネクション・プールの構成ファイルpool.xmlでは、データベースへの接続ユーザーはdb.usernameとして指定されています。一般的な構成ではORDS_PUBLIC_USERが使われます。

<entry key="db.username">ORDS_PUBLIC_USER</entry>

これはプロキシー・ユーザーで、実際に処理を実行する宛先ユーザーではありません。宛先ユーザーは、プロシージャORDS_ADMIN.CONFIG_PLSQL_GATEWAYの引数p_plsql_gateway_userへの値として設定します。
begin
      ords_admin.config_plsql_gateway(
          p_runtime_user    => 'ORDS_PUBLIC_USER',
          p_plsql_gateway_user => 'APEX_PUBLIC_USER'
     );
     end;
/
標準的な手順でORDSをインストールしていると、このプロシージャもインストール時のひとつの作業として実行されています。

ORDS_ADMIN.CONFIG_PLSQL_GATEWAYの実行では、少なくても以下の2つの処理が行われています。

ひとつは、PL/SQLゲートウェイ・ユーザー(上記の例ではAPEX_PUBLIC_USER)にプロキシー・ユーザーORDS_PUBLIC_USER経由で接続できるようにしています。設定された結果はビューPROXY_USERSから確認できます。

SQL> select * from proxy_users;


PROXY               CLIENT              AUTHENTICATION    FLAGS                                  

___________________ ___________________ _________________ ______________________________________ 

ORDS_PUBLIC_USER    APEX_PUBLIC_USER    NO                PROXY MAY ACTIVATE ALL CLIENT ROLES    



SQL> 


もう一つは、APEXを動作させるための宛先ユーザーとしてAPEX_PUBLIC_USERを使用する、という設定です。これはビューORDS_METADATA.PLSQL_GATEWAY_CONFIGから確認できます。

SQL> select * from ords_metadata.plsql_gateway_config;


RUNTIME_USER        PLSQL_GATEWAY_USER    COMMENTS    CREATED_BY    CREATED_ON    UPDATED_BY    UPDATED_ON    

___________________ _____________________ ___________ _____________ _____________ _____________ _____________ 

ORDS_PUBLIC_USER    APEX_PUBLIC_USER                  SYS           24-04-04      SYS           24-04-04      


SQL> 


本題の警告「PL/SQL Gateway mode of pool |default|lo| is set to proxied but ORDS could not read the proxy configuration from the database」は、コネクション・プールの属性plsql.gateway.modeがproxiedに設定されているにもかかわらず、ORDS_METADATA.PLSQL_GATEWAY_CONFIGの設定が無い場合に発生するようです。

この警告が発生する状況としては、APEXを構成せずORDSのRESTサービスだけを使う場合に、コネクション・プールのplsql.gateway.modeにproxiedが設定されている状況が想定されます。ORDSのRESTサービスはplsql.gateway.modeの設定に関係なく、REST有効化されたスキーマを宛先ユーザーとしてプロキシー接続された接続より実行されます。そのため、この警告出力は無視できます。

ちなみにORDSのRESTサービスを呼び出す接続の宛先ユーザーは、以下の手順で決められます。

ORDSのRESTサービスを実行する準備として、プロシージャORDS.ENABLE_SCHEMAを呼び出します。Web画面でREST有効化する場合も、処理としてはORDS.ENABLE_SCHEMAまたはORDS_ADMIN.ENABLE_SCHEMAが呼び出されています。

このプロシージャを呼び出すと、対象スキーマを宛先ユーザーとしたプロキシー接続が許可されます。以下はスキーマHRをREST有効化した後に、ビューPROXY_USERSを検索した結果です。PROXYORDS_PUBLIC_USERCLIENTHRのエントリが追加されています。

SQL> select * from proxy_users;


PROXY               CLIENT    AUTHENTICATION    FLAGS                                  

___________________ _________ _________________ ______________________________________ 

ORDS_PUBLIC_USER    HR        NO                PROXY MAY ACTIVATE ALL CLIENT ROLES    


SQL> 


これはAPEXの呼び出しとは異なる処理なので、ORDS_METADATA.PLSQL_GATEWAY_CONFIGに行が追加されることはありません。

ORDSのRESTサービスの呼び出しは、例えばスキーマHRに作成されたRESTサービスであれば、以下ようなURLから呼び出されます。RESTサービスを特定するURIの最初にスキーマ名(またはスキーマ別名)が現れ、そのスキーマを宛先ユーザーとします。そのため、宛先ユーザーは、ORDS_METADATA.PLSQL_GATEWAY_CONFIGに設定されていなくても決まります。

http[s]://ホスト名/ords/スキーマ名/モジュール/テンプレート

今回の記事は以上になります。警告メッセージ「PL/SQL Gateway mode of pool |default|lo| is set to proxied but ORDS could not read the proxy configuration from the database」に絡めて、Oracle APEXとORDSのデータベースへの接続の仕組みについて説明してみました。

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