9 カスタム・フック・ルールの実装

フック・ルールは、標準のノード・ルールの解析済ファイル・データとは対照的に、効率的にOracle JAF監査エンジンにフックを付け、監査の特定フェーズでコールされます。

フック・ルール呼出しについて

Oracle JAF監査のライフサイクルの特定フェーズに応じて作成したルールは、フック・ルールと呼ばれます。ノード・ルールとは異なり、フック・ルールは、アプリケーション・ファイル・データの解析に応答して呼び出されません。

startupclosedownstartupRPstartauditendauditclosedownRPまたはfileタイプに登録するルールは、JAF監査のライフサイクルにおける特定のフェーズに対応します。JAF監査のライフサイクルについては、フック・ルール呼出しの順序を理解するのに役立つように、次で説明します。

  1. 起動フェーズ

    初期化、構成分析およびファイル・セット拡張が実行されます。

  2. ルール・パック・ロード

    ルールは、ロード(インスタンス化)され、監査エンジンによって評価されます:

    → 最初にregister()がルール・パック内のすべてのルールでコールされ、ルール・リスナーが実行されます。

  3. 監査前フェーズ

    → startupフック・ルールが起動されます。

    → startupRPフック・ルールが、ルール・パックごとに起動されます。

  4. 監査フェーズ

    → startauditフック・ルールが、ファイル・セット内のファイルごとに起動されます。

    {

    → fileフック・ルールが起動されます。

    → その後、非フック(ノード)ルールが起動されます。

    }

  5. 終了フェーズ

    → endauditフック・ルールが起動されます。

    → closedownRPフック・ルールが、ルール・パックごとに起動されます。

    → closedownフック・ルールが起動されます。

ファイル・コンテキストへのカスタム・ルールの実装

各ファイルに対して他のルールが起動される前、または各ファイルに対してすべてのルールが起動された後で、そのファイルに対して呼び出される監査ルールを作成する必要がある場合は、Oracle JAF監査エンジンのfileフックを使用します。

fileタイプのフック・ルールには、呼び出されたファイルの監査を条件付きで終了する機能があります。ルールがブール値のfalseを返す場合、ファイル監査は拒否されます。trueを返すことは、return文を省略することと同じであり、監査は続行されることに注意してください。

context.filenameプロパティには、フック・ルールが呼び出されたファイルへのフル・ファイル・パスが含まれています。ファイルのファイル・パスは、プラットフォームに関係なく、常にフォワード・スラッシュで維持されます。

context.nodeプロパティは、DOM (HTMLおよびCSSの場合)またはJavaScript ASTまたはJSON ASTの最初のノードを指定します。

フックのリスナー・タイプ 呼び出されるタイミング
file ファイルが読み取られた後、非フック・ルールが起動される前に呼び出されます。
endfile ファイルに対してすべての非フック・ルールが起動された後に呼び出されます。
startscript 埋込みJavaScript <script>が読み取られた後、非フック・ルールが起動される前に呼び出されます。
endscript 埋込みJavaScriptテキストに対してすべての非フック・ルールが起動された後に呼び出されます。

監査ライフサイクルを使用したカスタム・ルールの実装

監査ライフサイクルの特定のフェーズで呼び出される監査ルールを作成する必要がある場合は、様々なOracle JAF監査ライフサイクル・フックのいずれかを使用します。

startup、closedown、startauditおよびendauditフェーズのフック・ルール

startupルールは、監査の初期化が完了してからデータ・ファイルが読み取られる前にコールされ、closedownルールは、監査完了の直前、およびすべてのファイルが監査された後にコールされます。レジスタ・コンテキストは、ルールのregister()リスナー・メソッドに渡されます。これらのルールを使用して、ユーザー・データの初期化や、ユーザー・サポート・パッケージのロードを行うことができます(ただし、startupRPフックも参照してください)。

ルールがstartupclosedownstartauditまたはendauditに登録されると、context.phaseプロパティ値にそれぞれの値が反映されます。

startauditルールは、有効なすべてのルール・パックですべてのstartupRPルールが起動された後、ファイル・セットの監査の直前にコールされます。context.phaseプロパティは、startauditを反映します。

endauditルールは、ファイル・セット監査の完了時、およびclosedownRPルールの起動前にコールされます。context.phaseプロパティは、endauditを反映します。

startupおよびstartauditフック・ルールには、監査を条件付きで終了する機能があります。ルールがブール値のfalseを返す場合、監査は拒否されます。trueを返すことは、return文を省略することと同じであり、監査は続行されることに注意してください。

startupRPおよびclosedownRPフェーズのフック・ルール

これらのルールは、ライフサイクルのファイル監査フェーズの直前および直後にコールされます。startupRPフックは、任意のstartupフックが起動された後にコールされ、closedownRPフックは、最後のclosedownフックが起動される前にコールされます。これらの登録済リスナーは通常、共通のルール・パック・データの初期化などの起動アクティビティ、および必要に応じてルール・パック・データの終了を許可するために、ルール・パックのルールで1回定義されます。

function  register(regCtx)
{
   return {
             startupRP   : _fn,
             closedownRP : _fn
          };
}
 
function _fn(ruleCtx)
{
    // ruleCtx.phase contains "startupRP" or "closedownRP"
}

ルール・パックのフックは次のように呼び出されます。

フックのリスナー・タイプ 呼び出されるタイミング
startupRP
監査の初期化が完了した後、startupフックが起動された後、およびデータ・ファイルが読み取られる前。ルールは、有効なルール・パック(構成ファイルのプロパティrulePack)ごとに1回コールされます。このルールを使用すると、ユーザー・データを初期化したり、ルールに必要なカスタム・ユーザー・サポート・パッケージ/サービス(ルール・パック拡張機能と呼ばれる)をロードしたり、context.rulePack.setExtension()をコールして作成された拡張機能を渡すことによって、ルール・パックに関連付けることができます。
// Here is a skeleton rule pack extention:
 
 context.utils.setExtension({
                              lib : get_some_lib(),
                              package : require('some package'),
                              table :  [ . . . ]
                              . . .
                            });

ルール・パックの標準ルールでは、context.rulePack.getExtension()をコールすることによって、ルール・パックに対して宣言されている拡張機能を取得できます。

startupRPフック・ルールには、監査を条件付きで終了する機能があります。ブール値のfalseを返す場合、監査は拒否されます。trueを返すことは、return文を省略することと同じであり、監査は続行されることに注意してください。

ルールの実行が必須であり、ユーザー構成ファイルによってこのルールが無効化されることをパックが許容できない場合は、そのルールのパックのrules.jsonファイルで$requiredプロパティをtrueに設定する必要があります。

closedownRP すべてのファイルが監査された後、closedownフックが起動される前。startupRPに対するこの補完ルールは、有効なルール・パックごとに1回コールされ、startedRPを介して生成されたカスタム・サポート・サービスの必要な終了を処理するために、必要に応じて使用できます。

ルールの実行が必須であり、ユーザー構成ファイルによってこのルールが無効化されることをパックが許容できない場合は、そのルールのパックのrules.jsonファイルで$requiredプロパティをtrueに設定する必要があります。

サンプルの監査フック・ルールのウォークスルー

startupclosedownstartupRPstartauditendauditclosedownRPまたはfileのリスナー・タイプに登録する監査ルールは、Oracle JAF監査エンジン・ライフサイクルの特定のフェーズでコールされます。これらのルールは、解析されたファイル・データに応答してコールされるノード・タイプのルールとは異なります。

このウォークスルーでは、アプリケーションのHTMLファイル内での<oj-xxx>要素の使用方法を分類するために連携する2つの監査ルールの簡単な使用について説明します。1つ目のルールは、標準のHTMLデータ・ノード・ルールであり、rulepack拡張オブジェクトを使用して、すべての監査対象ファイルでの様々な<oj-xxx>要素への参照の数を保存します。2つ目のルールでは、監査エンジンのstartupRPフックを使用して、rulepack拡張オブジェクトにカウンタを設定し、closedownRPフックを使用して、監査の完了時に累積された要素数をコンソールに表示します。

まず、ノード・ルールojtag-counterを作成し、解析されたHTMLファイルにojtagイベント・リスナーを登録することで、<oj-xxx>要素の使用方法の数を維持します。カウントを維持するために、このルールは、フック・ルールを使用してファイル監査を開始する直前に作成する必要がある、tagStats rulepack拡張オブジェクトに依存しています。

... // for clarity, the getName(), getDescription(), and getShortDescription() methods have been omitted

function register(regContext)
 {
   return { ojtag : function(ruleCtx, tagName)
                    {
                      let tagStats = ruleCtx.rulePack.getExtension().tagStats;
                      if (tagStats[tagName] === undefined)
                      {
                        // first use - create an entry for the tag
                        tagStats[tagName] = 0;
                      }
                      tagStats[tagName]++;
                    }
          };
};

次に、フック・ルールojtag-count-displayによって監査の開始時にカウントが設定され、監査の終了時に累積された統計がコンソールに表示されます。このフック・ルールは、startupRPフックに依存してrulepack拡張オブジェクトを作成し、closedownRPフックに依存して累積数を表示します。これら2つのフックは、監査エンジン・ライフサイクルのファイル監査フェーズの直前および直後にトリガーされます。

... // for clarity, the getName(), getDescription(), and getShortDescription() methods have been omitted

function register(regCtx)
{
   return { startupRP : function(ruleCtx)
                      {
                          // Get or create an extension
                          let RPExt = ruleCtx.rulePack.getExtension() || {};
                          // Add a stats collection object to it
                          RPExt.tagStats = {};
                          // Update the extension                          
                          ruleCtx.rulePack.setExtension(RPExt);            
                      },
            closedownRP : function(ruleCtx)
                        {
                          let ojTag, tagStats = context.rulePack.getExtension().tagStats;
 
                          console.log("\n");
                          for (ojTag in tagStats)
                          {
                            console.log(`<${ojTag}> : ${tagStats[ojTag]}`);
                          }
                          console.log("\n");
                        }
        };
};

次に、これらのルールによって返される一般的なサンプル出力を示します:

<oj-option> :     1824
<oj-label> :      1413
<oj-input-text> :  545
<oj-button>     :  447
 . . .
<oj-chart-item> :    1
<oj-chart-group> :   1
<oj-bind-dom> :      1