Oracle APEX 23.1から、アプリケーション定義の詳細にECIDを渡すという設定が追加されました。
APEXのページ・リクエスト時に受け取っているHTTPヘッダーECID-Contextを、APEX_WEB_SERVICEを使ってREST APIを呼び出す際に、同じHTTPヘッダーECID-Contextとして設定する、という機能です。最初にAPEXのアプリケーションから呼び出されるRESTサービスを作成します。
モジュールはecid、テンプレートはechoとしています。GETハンドラのソース・タイプはPL/SQL、ソースにはHTTPヘッダーECID-Contextの値を呼び出し元に返すコードを記述します。
begin
htp.p(owa_util.get_cgi_env('ECID-Context'));
end;
完全なURLをコピーしておきます。
APEXのページに動的コンテンツのリージョンを作成し、CLOBを返すPL/SQLファンクション本体として、以下のコードを記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_ecid_request varchar2(80); | |
l_response clob; | |
begin | |
-- APEXのページ・プロセスに割り当てられているECIDを取り出す。 | |
l_ecid_request := owa_util.get_cgi_env('ECID-Context'); | |
-- 呼び出しRESTサービスが受け取ったECIDを取り出す。 | |
l_response := apex_web_service.make_rest_request( | |
p_url => :G_ECID_ECHO_URL | |
,p_http_method => 'GET' | |
); | |
l_response := | |
l_ecid_request || '<b> : APEX page process ECID</b><br>' || | |
l_response || '<b> : REST servcie ECID</b>'; | |
return l_response; | |
end; |
構成によっては以下のように、ECIDが表示されない場合もあり得ます。
Oracle HTTP Serverに含まれるモジュールmod_contextおよびWebLogicサーバーにはECIDを生成する機能があります。
スタンドアロンのORDSにECIDを生成する機能を見つけることはできませんでした。また、現時点ではAutonomous Databaseで動作するAPEXは、HTTPヘッダーECID-Contextを受け取っていません。
上位コンポーネントからECID-Contextが渡されていると、ビューAPEX_WORKSPACE_ACTIVITY_LOGの列ECIDに記録されます。
先ほどのページがECIDとして以下の値を返してきたと仮定します。
1.005yrKcsvJOFw0KimTpmWJ0002n900075v;kXjE : APEX page process ECID
1.005yrKcsvJOFw0KimTpmWJ0002n900075v;kXjE : REST servcie ECID
1.005yrKcsvJOFw0KimTpmWJ0002n900075v;kXjE : REST servcie ECID
このECIDでのAPEXのページ・プロセスのログを、ビューAPEX_WORKSPACE_ACTIVITY_LOGから取り出すことができます。
select * from apex_workspace_activity_log where ecid = '1.005yrKcsvJOFw0KimTpmWJ0002n900075v;kXjE'
また、このページ・プロセス中に発行されたREST APIをビューAPEX_WEBSERVICE_LOGから取り出すことができます。
select * from apex_webservice_log where ecid = '1.005yrKcsvJOFw0KimTpmWJ0002n900075v;kXjE'
APEXのページ・プロセスがHTTPヘッダーECID-Contextを受け取っていない、または、自動化などのバックグランド処理からREST APIを呼び出しているためECIDが割り当たらないといった場合は、APEX 23.1で追加されたプロシージャAPEX_WEB_SERVICE.SET_REQUEST_ECID_CONTEXTを呼び出します。このプロシージャは以下のように定義されています。REST APIに割り当てるECIDが生成されますが、このSET_REQUEST_ECID_CONTEXTを呼び出しているプロセス(APEX_WORKSPACE_ACTIVITY_LOGのECID)は更新されません。つまり、このプロシージャを呼び出してECIDを割り当てた場合は、APEX_WORKSPACE_ACTIVITY_LOGとAPEX_WEBSERVICE_LOGをECIDで突合させることはできません。
--======================================================================================
-- Adds an execution context ID (ECID) HTTP request header to g_request_headers.
-- This will override the application level security setting "Pass ECID".
--
-- PARAMETERS
-- * p_ecid the identifier for the execution context
-- if set to null, no ECID header will be added
-- if set to AUTO_ECID (the default) an automatic determined
-- ECID header will be added
-- if set to something else, substrb(p_ecid, 1, 64) will be
-- used as the ECID header
--
-- EXAMPLE 1:
-- On application level sending of ECID header is switched off. By
-- calling set_request_ecid_context without parameter the following
-- call to make_rest_request will have an "ECID-Context" request
-- header with an automatic determined ECID.
--
-- begin
-- apex_web_service.set_request_ecid_context;
-- end;
--
-- EXAMPLE 2:
-- On application level sending of ECID header is switched off. By providing a
-- ECID value the following call to make_rest_request will have an "ECID-Context"
-- request header.
--
-- begin
-- apex_web_service.set_request_ecid_context(
-- p_ecid => 'my-123456' );
-- end;
--
-- EXAMPLE 3:
-- On application level sending of ECID header is switched on. By providing a
-- ECID value of null the following call to make_rest_request will not have an
-- "ECID-Context" request header.
--
-- begin
-- apex_web_service.set_request_ecid_context(
-- p_ecid => null );
-- end;
--
-- EXAMPLE 4:
-- On application level sending of ECID header is switched on. By providing a
-- ECID value, the following call to make_rest_request will use that instead
-- of an automatic determined ECID.
--
-- begin
-- apex_web_service.set_request_ecid_context(
-- p_ecid => 'my-123456' );
-- end;
--
--======================================================================================
procedure set_request_ecid_context (
p_ecid in varchar2 default AUTO_ECID);
この設定に関連して、RESTデータ・ソースの詳細にECIDを渡すという属性が追加されています。
アプリケーション設定の使用、はい、いいえのどれかを、RESTデータ・ソースごとに設定することができます。
Oracle APEXとしてのECIDの扱いは以上です。
以下、オラクル・データベースのV$SESSIONの列ECIDとの関連について、確認したことを記述します。
主にWebLogicやFusion Middlewareの説明になりますが、ECIDがV$SESSIONの列ECIDに設定され、V$ACTIVE_SESSION_HISTORYなどから参照できるとの記述を見かけます。
またOracle CloudのAutonomous DatabaseではV$SESSIONのECIDに値が設定されていますが、これはECID-Contextの値とは別の仕組みにより設定されています。
先ほど作成したRESTサービスのコードを以下に変更します。
declare
l_ecid varchar2(80);
begin
select ecid into l_ecid from v$session where sid = sys_context('USERENV','SID');
htp.p(owa_util.get_cgi_env('ECID-Context') || ':' || l_ecid);
end;
Autonomous Database上で実行する場合は、ビューV$SESSIONのSELECT権限をワークスペース・スキーマに与えておきます。
先ほどのAPEXアプリケーションを実行すると、HTTPヘッダーのECID-Contextの値とV$SESSIONの列ECIDの値が異なることが確認できます。
DBMS_SESSION.SET_CONTEXTを呼び出してHTTPヘッダーのECID-Contextの値をV$SESSIONのECIDに割り当てています。
ORDSの属性request.traceHeaderNameの使用が、サポートされるV$SESSIONの列ECIDにECIDを設定する手順です。
How to test if ECID is being set in session state in the Database (v$session) (Doc ID 2151716.1)
この中で使用されているコンテキストE2E_CONTEXTは、すでに使用不可になっています。そのため、上記のドキュメントによる手順は無効だと考えた方がよいでしょう。
最後に、apex.oracle.comで作成したAPEXアプリケーションとRESTサービスの間でECIDを渡すと、以下のようにECIDが変わります。
これはapex.oracle.comの環境固有の問題で、他の環境では発生していません。
ECIDについての説明は以上になります。
完