ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Enterprise Scheduler開発者ガイド
11g リリース1 (11.1.1.7)
B66615-04
  目次へ移動
目次

前
 
次
 

17 ジョブ・リクエスト・ログと出力の作成

この章では、Oracle Enterprise Schedulerを使用して、管理者とユーザーが後で使用できるように保存する必要があるジョブ・リクエスト・ログと出力を生成する方法について説明します。

ジョブ・リクエストによって生成されるログは、管理者が問題を診断したり、ジョブ固有の状態を確認するのに役立ちます。ログには、Fusion Middleware Controlからアクセスできます。さらに、一部のジョブでは、ジョブの完了後にユーザーが確認できるジョブ固有のデータに関するレポートなどの出力が、その作業の一環として生成されます。コードで、リクエスト・ログ情報およびリクエストの出力を作成および格納できます。

この章では、次の項目について説明します。

17.1 リクエスト・ログの作成

ジョブ・コードからジョブ・リクエスト・ログを作成できます。Oracle Enterprise Schedulerには、ログの作成と書き込み、およびコンテンツ・ストアとの相互作用のためのAPIが備えられています。

Oracle Enterprise Schedulerでは、リクエストごとに1つのログがサポートされます。このログにはREQUESTID.logという形式の名前が付けられます。ロギングAPIでは、コンテンツ・ストアに直接ログが記録され、ログ・コンテンツはロールバックできません。

Fusion Middleware Controlを使用したジョブ・リクエスト・ログの表示の詳細は、『Oracle Fusion Middleware Oracle Enterprise Scheduler管理者ガイド』のジョブ・リクエスト・ログの表示に関する項を参照してください。

17.1.1 システム・プロパティ

JavaおよびPL/SQLジョブのログを記録する場合、実際にログに表示される内容は、SYS_EXT_requestLogLevelシステム・プロパティの設定内容によって制限されます。このプロパティによって、JavaおよびPL/SQLのリクエスト・ロギングAPIでサポートされるロギング・レベルが決定します。

プロパティの値は、デフォルトでINFOに設定されます。有効な値の完全なセットは、SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINESTです。JavaおよびPL/SQL APIを使用して、リクエストのログ・レベルを検出します。

プロセス・ジョブではロギングAPIを使用しないため、ロギング・レベルはサポートされないことに注意してください。

17.1.2 リクエスト・ログを処理するためのAPI

oracle.as.scheduler.RuntimeServiceクラスのメソッドを使用して、Oracle Enterprise Schedulerコンテンツ・ストアに格納されているログを処理できます。最初に、RuntimeServiceHandleインスタンスを取得する必要があります。このインスタンスを、これらのRuntimeServiceメソッドそれぞれの引数として渡します。

RuntimeServiceHandleの詳細は、第14.2.1項「ランタイム・サービスへのアクセスおよびランタイム・サービス・ハンドルの取得方法」を参照してください。

表17-1 リクエスト・ログを処理するためのRuntimeServiceメソッド

メソッド 説明

getLogContentDetail(RuntimeServiceHandle handle, long requestId )

リクエストに対してContentDetailインスタンスをログ・コンテンツの詳細とともに返すか、ログが存在しない場合はNULLを返します。

openLogContent( RuntimeServiceHandle handle, long requestId )

指定されたリクエストに対して、リクエスト・ログを開いてログ・データを取得し、ContentHandleインスタンスを返します。ハンドルを使用して出力データを取得できます。ハンドルを解放するには、コンテンツを閉じる必要があります。

getLogLines( RuntimeServiceHandle handle, ContentHandle contentHandle, int maxLines )

リクエスト・ログから最大maxLines行の文字列配列を返します。最後のコールからこのメソッドまで続けられます。コンテンツ・ハンドルは、前のコールからopenLogContentまでです。これにより、ログから行の文字列配列が行終了文字なしで返されます。行がない場合、配列は空になります。

getTextContent( RuntimeServiceHandle handle, ContentHandle contentHandle, int maxChars )

ログまたは出力テキスト・コンテンツから、最大maxChars文字の文字配列を返します。

closeContent( RuntimeServiceHandle handle, ContentHandle contentHandle )

以前開いたログまたは出力コンテンツを閉じ、ハンドルを解放します。


17.1.3 ログ・ヘッダー

ロギング・コードにより、次のヘッダー情報で始まるエントリがログに書き込まれます。このヘッダーは、ログに書き込まれる各レコードの先頭に付けられます。

例17-1

####[TIMESTAMP] [LOGLEVEL]
 
Sample log lines:
####[2011-07-11T14:20:32.276-07:00] [INFO] This is a log record.
####[2011-07-11T14:20:32.282-07:00] [INFO] This is the first line of a multi-line log record:
second line of multi-line log record.

17.1.4 Javaジョブからのリクエスト・ログの作成

Javaリクエスト・ログ出力を使用して、Javaまたは非同期Javaジョブの実行および更新ステージ中、およびすべてのジョブ実行タイプの前処理および後処理中にログを記録できます。

ジョブ・ロジックでは、ContentFactory APIを使用してリクエスト・ログ出力を取得する必要があります。Oracle Enterprise Schedulerでは、ログ出力が取得されるたびに、SYS_EXT_requestLogLevelシステム・プロパティの現行値を使用して、ロギング・レベルを制限します。

17.1.4.1 Javaジョブ・ログ出力用API

Javaジョブのロジックで、oracle.as.scheduler.request.ContentFactoryクラスのgetRequestLoggerメソッド(表17-2を参照)を使用して、ログ・エントリを追加するためのRequestLoggerインスタンスを取得できます。リクエスト・ログ出力では、リソース・バンドルはサポートされていないことに注意してください。

ログの処理に使用できるJava APIは次のとおりです。

  • ContentFactoryクラスは、ログの作成やエントリの追加に使用できるRequestLoggerのインスタンスを取得するために使用します。表17-2を参照してください。

  • RequestLoggerクラスは、ログを書き込むために使用します。表17-3を参照してください。

oracle.as.scheduler.request.ContentFactoryクラスには、コードが、出力コンテンツ・フレームワークにアクセスしたり、出力自体を作成するために使用できるインスタンスにアクセスできるようにするメソッドが備えられています。

表17-2 リクエスト・ログを作成するためのContentFactoryメソッド

メソッド 説明

getRequestLogger( long requestId )

指定されたrequestIdに対してRequestLoggerインスタンスを返し、requestId.logという名前のログ・コンテンツをOracle Enterprise Schedulerコンテンツ・ストアに作成します。


ログ出力インスタンスを取得すると、エントリを追加するために、表17-3に示されているメソッドを使用できます。

表17-3 リクエスト・ログを作成するためのRequestLoggerメソッド

メソッド 説明

log( Level level, String msg )

fine( String msg )

finer( String msg )

finest( String msg )

これらのメソッドによって、指定されたレベルでメッセージがログに記録されます。

指定されたロギング・レベルが、SYS_EXT_requestLogLevelシステム・プロパティで指定されたログ・レベル以上である場合にのみ、メッセージがログに記録されます。このプロパティが設定されていない場合のデフォルト・ログ・レベルはINFOです。

logメソッドを使用する場合、java.util.logging.Levelでは、次に降順で示す値をサポートします。

  • SEVERE

  • WARNING

  • INFO

  • CONFIG

  • FINE

  • FINER

  • FINEST


17.1.4.2

例17-2に、ロギングを行う非常に単純なJavaジョブの例を示します。

例17-2 Javaのリクエスト・ロギングの例

import oracle.as.scheduler.request.ContentFactory;
import oracle.as.scheduler.request.RequestLogger;
import java.util.logging.Level;

class ExampleJavaLogger{
 
  private boolean m_loggingEnabled = false;
  private RequestLogger m_requestLogger = null;
 
  public void execute( RequestExecutionContext ctx,
                       RequestParameters params )
  {
    try
    {
      m_requestLogger = ContentFactory.getRequestLogger(ctx.getRequestId());
      m_loggingEnabled = true;
    }
    catch (Exception ex)
    {
      // failed to get request logger
    }
 
    log(Level.INFO, "Starting the job.");
    // ...
    log(Level.INFO, "Ending the job.");
  }
 
  private void log( Level level, String message )
  {
    if (m_loggingEnabled)
    {
        m_requestLogger.log(level, message);
    }
  }
}

17.1.5 PL/SQLジョブからのリクエスト・ログの作成

PL/SQLからログを作成する場合は、ログ・エントリを書き込むために、コードでESS_JOB PL/SQLパッケージを使用できます。

17.1.5.1 ログを作成するためのESS_JOBパッケージ・サポート

Oracle Enterprise Schedulerには、PL/SQLコードからログを作成するためのファンクションおよびプロシージャを含むESS_JOBパッケージが備えられています。

表17-4 リクエスト・ロギング用のESS_JOBファンクションおよびプロシージャ

メソッド 説明

procedure write_log( p_level in integer, p_text in varchar2 );

現行セッションに関連付けられているOracle Enterprise Schedulerリクエストに対して、p_textをメッセージとしてリクエスト・ログ・コンテンツに書き込みます。

指定されたロギング・レベルが、SYS_EXT_requestLogLevelシステム・プロパティで指定されたログ・レベル以上である場合にのみ、メッセージがログに記録されます。このプロパティが設定されていない場合のデフォルト・ログ・レベルはLEVEL_INFOです。

ログ・レベルの値は、java.util.logging.Levelで定義された値に対応します。

p_levelパラメータに次の値を使用します(降順で示します)。

  • LEVEL_SEVERE

  • LEVEL_WARNING

  • LEVEL_INFO

  • LEVEL_CONFIG

  • LEVEL_FINE

  • LEVEL_FINER

  • LEVEL_FINEST


17.1.5.2 PL/SQLのリクエスト・ロギングの例

SQLリクエスト・ジョブ・プロシージャによるリクエスト・ロギングの例を次に示します。

例17-3 PLSQLのリクエスト・ロギングの例

create or replace procedure log_example_job
( request_handle in varchar2 )
as
  v_request_id  number := null;
begin
  ess_job.write_log(ess_job.level_fine,
                    'LOG_EXAMPLE_JOB Procedure Begin');
 
  -- Oracle Enterprise Scheduler request id being executed.
  begin
    v_request_id := ess_runtime.get_request_id(request_handle);
  exception
    when others then
      ess_job.write_log(ess_job.level_severe,
                        'Bad request handle: '||request_handle);
      raise_application_error(-20000,
         'Failed to get request id for request handle '||request_handle,
         true);
  end;
 
  -- Job logic
  ess_job.write_log(ess_job.level_info,
                    'Executing job logic...');
 
  ess_job.write_log(ess_job.level_fine,
                    'LOG_EXAMPLE_JOB Procedure End');
end;
/

17.1.6 プロセス・ジョブからのリクエスト・ログの作成

プロセス・ジョブからジョブ・リクエスト・ログに書き込むことができます。この動作は、特定のレベルでエントリを書き込むためのAPIに実行コードからアクセスできる、JavaおよびPL/SQLジョブとは大きく異なります。プロセス・ジョブでは、かわりに、ジョブの標準出力および標準エラーが、リクエストのログ作業ディレクトリ(Oracle Enterprise Schedulerにより設定される場所)にあるファイルにリダイレクトされます。Oracle Enterprise Schedulerによって、このファイルがインポートされ、コンテンツ・ストア内のリクエスト・ログに付加されます。

つまり、プロセス・ジョブからログを記録するために必要なのは、ジョブ・ロジック・コードから標準出力に書き込むことのみです。

ログ・ファイルを読み取るために使用されるエンコーディングは、次のように決定されます。アプリケーションのess-config.xmlでEnvプロパティにLANGが定義されている場合、Oracle Enterprise Schedulerではそのエンコーディングを使用します。そうでない場合、Oracle Enterprise Schedulerではコンテナのデフォルト・エンコーディングを使用します。

プロセス・ジョブから特定のレベルでログを記録できないことに注意してください(レベルを設定するためのAPIが使用できないため)。このため、ログ・コンテンツはSYS_EXT_requestLogLevelシステム・プロパティによって制限されません。Oracle Enterprise Schedulerでは、常にログ・ファイルのコンテンツをコンテンツ・ストア内のリクエスト・ログに付加します。

17.2 リクエスト出力の作成

実行時に、ジョブでファイルを出力として書き込むようにできます。たとえば、ユーザーへのレポートで有用なデータをジョブで収集するとします。実行時に生成した出力は、クライアント・ユーザー・インタフェースまたはFusion Middleware Controlを使用して後から取得できます。

コードにより作成される出力は、Oracle Enterprise Schedulerコンテンツ・ストアにインポートでき、後から取得することができます。これを行うには、通常の方法でファイル・システムに書き込むか、Oracle Enterprise Scheduler APIを使用してストアに直接インポートします。

ファイル・システムを使用する場合は、Oracle Enterprise Schedulerのess-config.xmlファイルで構成された場所にある特定のディレクトリに書き込みます。Oracle Enterprise Schedulerにより、すべてのリクエストから書き込まれたファイルを格納するためのリクエスト・ファイル・ディレクトリが作成されます。コードでは、リクエスト用に作成されたこのディレクトリのサブディレクトリに書き込みます。Oracle Enterprise Schedulerによって、すべてのリクエストの出力が自動的にコンテンツ・ストアにインポートされ、リクエスト固有のサブディレクトリは削除されます。

Oracle Enterprise Schedulerには、コンテンツ・ストアにアクセスし、JavaおよびPL/SQL両方のコードから出力を書き込むためのAPIが備えられています。

17.2.1 リクエスト・ファイル・ディレクトリの使用

リクエスト・ファイル・ディレクトリは、Oracle Enterprise Schedulerのess-config.xmlファイルで指定されます。Oracle Enterprise Schedulerでは、リクエストごとに、このリクエスト・ファイル・ディレクトリのリクエスト固有のサブディレクトリを作成できます。これは、一時ファイル用の作業ディレクトリおよびコンテンツ・ストアに保存する必要がある出力ファイル用の出力ディレクトリです。

コードでは実行時に、それぞれのリクエスト固有のディレクトリに一時ファイルおよび出力ファイルを書き込むことができます。Oracle Enterprise Schedulerにより、リクエストの出力ディレクトリ内のファイルがコンテンツ・ストアにインポートされます。第17.2.1.1項第17.2.1.2項および第17.2.1.3項で説明されているように、コンテンツがインポートされるタイミングは、リクエスト・ファイル・ディレクトリが共有されているかローカルであるかによって異なります。

リクエストのすべての出力がコンテンツ・ストアに自動的にインポートされた後、Oracle Enterprise Schedulerによって、リクエスト固有の出力ディレクトリとそのコンテンツが削除されます。

リクエスト・ファイル・ディレクトリはローカルにすることもでき、この場合、単一のサーバーでの作業にのみ使用することを意味します。または共有することもでき、この場合、複数のサーバーで実行される作業によって単一のディレクトリが使用されます。実行時の動作は、ディレクトリがローカルまたは共有のいずれに構成されているかによって異なります。

例17-4に示されているように、ディレクトリはess-config.xmlファイルで指定されます。

例17-4 ess-config.xmlファイルによるリクエスト・ファイル・ディレクトリの構成

<ess:EssConfig xmlns:ess="http://ess.oracle.com"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ess:EssProperties>
        <ess:EssProperty key="RequestFileDirectory" value="/etc/outputfiles" 
                   immutable="true"/>
        <ess:EssProperty key="RequestFileDirectoryShared" value="false" 
            immutable="true"/>
    </ess:EssProperties>
</ess:EssConfig>

17.2.1.1 リクエスト・ファイル・ディレクトリの共通動作

Oracle Enterprise Schedulerにより、出力ディレクトリからすべてのリクエスト出力ファイルがコンテンツ・ストアに自動的にインポートされ、リクエスト作業ディレクトリとそこに含まれるすべてのファイルが削除されます。

既存のコンテンツが以前にインポートされたものである場合には、常に、インポートされたファイルによって同じファイル名の既存のコンテンツが上書きされます。既存のコンテンツがAPIを使用して作成された場合は、新しいファイルと異なるものとみなされ、新しいファイルで上書きされずに無視されます。つまり、APIにより作成されたコンテンツが優先されます。

Oracle Enterprise Schedulerでは、長さゼロの出力ファイルはインポートされません。

17.2.1.2 共有リクエスト・ファイル・ディレクトリの動作

リクエストによって作成されたすべてのファイルは、リクエストが完了して終了状態になるまで、その作業ディレクトリおよび出力ディレクトリに保持されます。共有ファイル・ディレクトリにあるリクエストによって作成されたすべてのファイルは、リクエストのすべてのステージで使用できます。

17.2.1.2.1 共有リクエスト・ファイル・ディレクトリを使用する場合のエラー処理

Oracle Enterprise Schedulerによって、ジョブ・リクエストがRUNNING状態に遷移する前に、リクエスト作業ディレクトリが作成されます。ディレクトリの作成中にエラーが発生すると、常に、リクエストのシステム・エラーが発生します。

ジョブの処理では、ログのインポートはリクエストが終了状態に遷移した後に行われます。ログのインポート中にエラーが発生すると、エラーがログに記録され、リクエスト・ログがファイル・システム内に残されます。ログはコンテンツ・ストアに手動でインポートする必要があります。

すべてのジョブ・タイプで、出力ファイルのインポートはリクエストが終了状態に遷移した後に行われます。出力ファイルのインポート中にエラーが発生すると、エラーがログに記録され、ファイル・システム上の該当ディレクトリに出力ファイルが残されます。出力ファイルはユーザーが削除する必要があります。

17.2.1.3 ローカル・リクエスト・ファイル・ディレクトリの動作

ステージのリクエストが実行される前には必ず、Oracle Enterprise Schedulerによって、リクエスト固有のディレクトリが作成されます。リクエスト・ファイル・ディレクトリがローカルである場合は、どのサーバーのローカルにも存在することが保証されている場所である必要があります。この場合、あるステージのリクエストによって作成されたファイルが、次のステージでも使用できるとは保証されません。これは、各ステージは独立した作業単位であり、異なるサーバーで実行される可能性があるためです。

ローカル・リクエスト・ファイル・ディレクトリには、Oracle Enterprise Schedulerによって各ステージに対するアクションが実行されることを除き、共通動作が適用されます。これは、各ステージが異なるサーバーで実行される場合があり、次のステージではファイルが存在しない可能性があることから、Oracle Enterprise Schedulerでは各ステージのファイルを取得してクリーン・アップする必要があるためです。

以前にインポートされたすべての出力ファイルにリクエストからアクセスする必要がある場合は、パラメータSYS_EXT_executeAutoExportをtrueに設定できます。これが設定されている場合、実行ステージの始めに、以前にインポートされた出力ファイルがOracle Enterprise Schedulerによって自動的にリクエストの作業出力ディレクトリにエクスポートされます。これにより、実行ステージの終わりにファイルがコンテンツ・ストアに再びインポートされる前に、ファイルを更新できるようになります。(コンテンツがエクスポートされても、コンテンツ・ストアからコンテンツは削除されないことに注意してください。)さらに、Oracle Enterprise Schedulerには、以前にインポートされた出力ファイルをリクエストによって選択的にエクスポートするためのAPIが備えられています。

17.2.1.3.1 ローカル・リクエスト・ファイル・ディレクトリを使用する場合のエラー処理

ローカル・リクエスト・ファイル・ディレクトリを使用する場合、ファイルのインポートは各ステージ(前処理、実行、更新、後処理)の終わりに行われます。ログまたは出力ファイルのインポート中にエラーが発生した場合、インポートに失敗したログおよび出力ファイルは<request_file_directory>/preserveにあるミラー・ディレクトリに移動されます。たとえば、リクエスト18の場合は、<request_file_directory>/preserve/18になります。

前処理ステージでは、ステージの始めにリクエスト・ディレクトリを作成するときか、またはステージの終わりに出力ファイルをインポートするときにエラーが発生すると、リクエストに対するシステム・エラーが発生します。

後処理ステージでは、ステージの始めにリクエスト・ディレクトリを作成するときか、またはステージの終わりに出力ファイルをインポートするときにエラーが発生すると、リクエストに対する警告が発生します。

Javaジョブ、非同期Javaジョブおよびプロセス・ジョブ・リクエストの実行ステージでは、ステージの始めにリクエスト・ディレクトリを作成するときか、以前にインポートされた出力ファイルを自動的にエクスポートするとき(SYS_EXT_executeAutoExportシステム・プロパティを使用する場合など)、またはステージの終わりに出力ファイルをインポートするときにエラーが発生すると、リクエストに対するシステム・エラーが発生します。

リクエストがプロセス・ジョブの場合、リクエスト・ログをインポートするときに発生したエラーはログに記録され、エラーとして処理されません。ログはファイル・システム内に残され、コンテンツ・ストアに手動でインポートできます。プロセス・ジョブの実行中に内部エラーが発生した場合は、ジョブの実行を続行できるため、ジョブおよび出力ファイルはインポートされません。ログおよび出力ファイルは、ジョブの終了時に自動的またはユーザーにより手動でインポートされます。ジョブがERROR_MANUAL_RECOVERYに遷移した場合は、ユーザーがリクエスト・ログおよび出力ファイルをクリーン・アップする必要があります。

更新ステージでは、リクエスト・ディレクトリを作成するときか、または出力ファイルをインポートするときに発生したエラーは、ログに記録されるのみです。

17.2.2 システム・プロパティ

リクエスト・ファイル・ディレクトリを使用して出力ファイルを自動的にインポートする場合は、SYS_EXT_supportOutputFilesシステム・プロパティを設定する必要があります。

リクエストの出力ディレクトリを使用して出力ファイルを作成するには、ジョブでシステム・プロパティSYS_EXT_supportOutputFilesを使用してパラメータを定義する必要があります。ジョブで作成するファイルの種類に応じて、プロパティは次のいずれかの方法で設定できます。

  • コンテンツ・ストアにインポートするファイルをリクエストの出力ディレクトリに書き込むには、「output」に設定します。

  • 一時ファイルなど、インポートしないファイルをリクエスト作業ディレクトリに書き込むには、「work」に設定します。

  • ジョブで出力ファイルや一時ファイルが作成されない場合は、「none」に設定するか、未定義のままにします。

表17-5 リクエスト出力を作成するためのシステム・プロパティ

メソッド 説明

SYS_EXT_supportOutputFiles

ジョブによりファイル・システムにファイルが作成されるかどうかを示す文字列プロパティ。サポートされる値は、work、outputおよびnoneです。無効な値はnoneとして処理されます。

SYS_EXT_executeAutoExport

以前にインポートされた出力ファイルを実行ステージの始めにエクスポートするかどうかを示すブール型プロパティ。コンテンツが自動的にエクスポートされても、コンテンツ・ストアからコンテンツは削除されません。


17.2.3 リクエスト出力を処理するためのAPI

oracle.as.scheduler.RuntimeServiceクラスのメソッドを使用して、Oracle Enterprise Schedulerコンテンツ・ストアに格納されているリクエスト出力を処理できます。最初に、RuntimeServiceHandleインスタンスを取得する必要があります。このインスタンスを、これらのRuntimeServiceメソッドそれぞれの引数として渡します。RuntimeServiceHandleの詳細は、第14.2.1項「ランタイム・サービスへのアクセスおよびランタイム・サービス・ハンドルの取得方法」を参照してください。

表17-6 リクエスト出力を処理するためのRuntimeServiceメソッド

メソッド 説明

getOutputContentDetail( RuntimeServiceHandle handle, long requestId, String contentName )

指定されたリクエストに対する指定された出力コンテンツのContentDetailインスタンスを返すか、コンテンツが存在しない場合はNULLを返します。

getOutputContentDetail( RuntimeServiceHandle handle, long requestId )

リクエストに対するすべての出力コンテンツのContentDetailリスト・インスタンスを返します。出力コンテンツがない場合、リストは空になります。

openOutputContent( RuntimeServiceHandle handle, long requestId, String contentName )

指定されたリクエスト出力を開いて指定されたコンテンツの出力データを取得し、ContentHandleインスタンスを返します。ハンドルを使用して出力データを取得できます。ハンドルを解放するには、コンテンツを閉じる必要があります。

getTextContent( RuntimeServiceHandle handle, ContentHandle contentHandle, int maxChars )

ログまたは出力テキスト・コンテンツから、最大maxChars文字の文字配列を返します。

getBinaryContent( RuntimeServiceHandle handle, ContentHandle contentHandle, int maxBytes )

バイナリ・コンテンツから最大でmaxBytesバイトのバイト配列を返します。

closeContent( RuntimeServiceHandle handle, ContentHandle contentHandle )

以前開いたログまたは出力コンテンツを閉じ、ハンドルを解放します。


17.2.4 Javaジョブからのリクエスト出力の作成

Javaからリクエスト出力を作成するには、ジョブのコードで、Oracle Enterprise Scheduler APIを使用してコンテンツ・ストアに直接インポートするか、コンテンツ・ストアに自動的にインポートされるファイルをリクエストの出力ディレクトリに作成できます。

ジョブでは、APIを使用してテキストまたはバイナリ出力コンテンツを作成できます。インポートされる出力ファイルは常にバイナリ・コンテンツとしてインポートされます。つまり、バイトは解釈されません。

17.2.4.1 Javaジョブからのリクエスト出力を処理するためのAPI

リクエスト出力の処理に使用できるJava APIは次のとおりです。

  • ContentFactoryクラスを使用して、コンテンツを作成して出力を書き込むために使用できるその他のクラスのインスタンスを取得します。表17-7を参照してください。

  • RequestOutputクラスを使用して出力を書き込みます。表17-8を参照してください。

  • OutputContentHelperクラスを使用して、コンテンツ・ストアおよびリクエスト・ファイル・ディレクトリと相互作用します。表17-9を参照してください。

oracle.as.scheduler.request.ContentFactoryクラスには、コードが出力コンテンツ・フレームワークにアクセスしたり、出力自体を作成するために使用可能なインスタンスにアクセスできるメソッドが備えられています。

表17-7 Javaリクエスト出力用のContentFactoryメソッド

メソッド 説明

getRequestOutput( RuntimeServiceHandle rsh, long requestId, ContentType contentType, String contentName )

指定されたリクエストに対して出力とともにRequestOutputインスタンスを返し、そのリクエストの出力コンテンツを作成します。各書込みでは、指定されたリクエスト・サービス・ハンドルが使用されます。トランザクションのコミットまたはロールバックは、コール側のコードで行う必要があります。

getOutputContentHelper( long requestId )

標準または拡張リクエスト・モードで、リクエストに対して出力コンテンツを作成するためのOutputContentHelperインスタンスを返します。各操作が個別のトランザクションで実行されます。

getOutputContentHelper( long requestId, RuntimeServiceHandle rsh )

標準または拡張リクエスト・モードで、リクエストに対して出力コンテンツを作成するためのOutputContentHelperインスタンスを返します。各操作では指定されたハンドルが使用され、トランザクションのコミットまたはロールバックはコール元が行います。


oracle.as.scheduler.request.RequestOutputクラスは、コードによって作成される出力を表します。ContentFactory.getRequestOutputからこのクラスのインスタンスを取得してから、そのwriteメソッドを使用して作成中の出力にコンテンツを追加します。

表17-8 Javaリクエスト出力用のRequestOutputメソッド

メソッド 説明

writeln( String str )

テキスト出力コンテンツに、strとそれに続く改行文字を付加します。

write( String str )

テキスト出力コンテンツにstrを付加します。

write( String str, int offset, int length )

テキスト出力コンテンツにstrを付加します。

write( char[] chars )

テキスト出力コンテンツにcharsを付加します。

write( char[] chars, int offset, int length )

テキスト出力コンテンツにcharsを付加します。

write( byte[] bytes )

バイナリ出力コンテンツにbytesを付加します。

write( byte[] bytes, int offset, int length )

バイナリ出力コンテンツにbytesを付加します。


oracle.as.scheduler.request.OutputContentHelperクラスのメソッドは、Javaジョブにおいて多くの出力処理を行います。コードでは、これらのメソッドを使用してリクエスト・ファイル・ディレクトリおよびコンテンツ・ストアそのものを操作できます。

コンテンツ・ストアにコンテンツをインポートするためのメソッドでは、インポート中にトランザクション・セマンティクスを指定するために使用できるOutputContentHelper.CommitSemantics列挙インスタンスを取得することに注意してください。詳細は、表17-10を参照してください。

表17-9 Javaリクエスト出力用のOutputContentHelperメソッド

メソッド 説明

workDirectoryExists( )

リクエストの作業ディレクトリが存在する場合にtrueを返します。任意のステージにあるジョブで、一時ファイルの作成を試行する前に、作業ディレクトリが存在するかどうかを判別できるようにします。

Oracle Enterprise Schedulerによって作業ディレクトリが作成されるようにするには、ジョブでSYS_EXT_supportOutputFilesシステム・プロパティにworkまたはoutputの値を定義する必要があります。

outputDirectoryExists( );

リクエストの出力ディレクトリが存在する場合にtrueを返します。更新などの任意のステージにあるジョブで、出力ファイルの作成を試行する前に、出力ディレクトリが存在するかどうかを判別できるようにします。

Oracle Enterprise Schedulerによって出力ディレクトリが作成されるようにするには、ジョブでSYS_EXT_supportOutputFilesシステム・プロパティにoutputの値を定義する必要があります。

isRequestWorkDirectoryShared( );

リクエスト・ファイル・ディレクトリが共有されている場合にtrueを返します。その場合、リクエストの作業ディレクトリまたは出力ディレクトリに、いずれかのステージにおいて作成されたすべてのファイルが、リクエストのそれ以降のすべてのステージで使用できるようになります。

getResolvedWorkDirectory( );

現在のサーバーに解決されるリクエスト作業ディレクトリを含む文字列を返します。ジョブでは作業ディレクトリに一時ファイルを作成でき、作業ディレクトリは、リクエストの実行終了時(RequestFileDirectoryが共有されている場合)または各ステージ(前処理、実行、更新、後処理)の終わり(RequestFileDirectoryがローカルである場合)に、Oracle Enterprise Schedulerによって自動的に削除されます。

getResolvedOutputDirectory( );

現在のサーバーに解決されるリクエストの出力ディレクトリを含む文字列を返します。ジョブでは、Oracle Enterprise Schedulerコンテンツ・ストアに自動的または手動でインポートできる出力ファイルを出力ディレクトリに作成できます。

importOutputFiles( List<String> fileNames, CommitSemantics semantics );

解決された出力ディレクトリから、指定されたファイルをインポートして、ImportExportResultインスタンスを返します。既存のコンテンツがAPIを使用して作成されている場合を除き、インポートされたコンテンツによって、同じ名前を持つ既存のコンテンツが上書きされます。その場合、ファイルはインポートされません。

importOutputFiles( CommitSemantics semantics );

解決された出力ディレクトリから、すべてのファイルをインポートして、ImportExportResultインスタンスを返します。既存のコンテンツがAPIを使用して作成されている場合を除き、インポートされたコンテンツによって、同じ名前を持つ既存のコンテンツが上書きされます。その場合、ファイルはインポートされません。

exportOutputContent( List<String> contentNames );

リクエストの出力ディレクトリ内のファイルに、指定された以前にインポート済の出力コンテンツをエクスポートして、ImportExportResultを返します。エクスポートされたファイルによって、同じ名前を持つすべての既存のファイルが上書きされます。APIを使用して作成された出力コンテンツはエクスポートできないことに注意してください。

exportOutputContent( );

以前にインポートされたすべての出力コンテンツをリクエストの出力ディレクトリ内のファイルにエクスポートして、ImportExportResultインスタンスを返します。エクスポートされたファイルによって、同じ名前を持つすべての既存のファイルが上書きされます。APIを使用して作成された出力コンテンツはエクスポートできないことに注意してください。

queryOutputContent( )

コンテンツ・ストア内にある既存の出力コンテンツすべての詳細情報とともにContentDetailインスタンスのリストを返します。ここでは、インポートされた出力コンテンツとAPIを使用して作成された出力コンテンツ両方の情報が返されます。

queryOutputContent( String contentName )

コンテンツ・ストア内に出力コンテンツがある場合は、その詳細情報とともにContentDetailインスタンスを返し、ない場合はNULLを返します。ここでは、インポートされた出力コンテンツとAPIを使用して作成された出力コンテンツ両方の情報が返されます。

outputContentExists( String contentName )

リクエストに対して、コンテンツ・ストア内に指定された出力コンテンツが存在する場合にtrueを返します。ここでは、インポートされた出力コンテンツとAPIを使用して作成された出力コンテンツの情報が返されます。

deleteOutputContent( List<String> contentNames )

リクエストに対して、コンテンツ・ストアから、指定された出力コンテンツを削除します。インポートされた出力コンテンツとAPIを使用して作成された出力コンテンツを削除できます。


コンテンツ・ストアにコンテンツをインポートしているときにエラーが発生した場合の動作を指定するには、oracle.as.scheduler.request.OutputContentHelper.CommitSemantics列挙を使用します。

表17-10 コミット・セマンティクスを表すCommitSemantics列挙メンバー

フィールド 説明

StopOnFirstError

1つのファイルにエラーがある場合に、すべてのファイルに対する操作を停止します。ハンドルが内部である場合、これはコミットされます。

IgnoreErrors

エラーに関係なく、すべてのファイルに対する操作を行います。ハンドルが内部である場合、これはコミットされます。

Transactional

いずれかのファイルにエラーがある場合に、すべてのファイルに対する操作を停止します。ユーザー指定のハンドルでは、これは無効です。


17.2.4.2

次の例では、リクエストの出力ディレクトリに出力ファイルを作成する方法を示します。ジョブでSYS_EXT_supportOutputFilesシステム・プロパティをoutputとして定義する必要があることに注意してください。この例は、Javaジョブ、非同期Javaジョブ、プリプロセッサまたはポストプロセッサに適用されます。

例17-5 出力ファイルの作成

import oracle.as.scheduler.request.ContentFactory;
import oracle.as.scheduler.request.OutputContentHelper;

class ExampleOutputCreator{ 
 
    OutputContentHelper helper = ContentFactory.getOutputContentHelper(requestId);
    String outputDir = helper.getResolvedOutputDirectory();
 
    File f = new File(outputDir, "myfile");
    f.createNewFile();
    if (f.exists())
    {
        // write to file
    }
}

次の例では、出力ファイルを手動でエクスポートおよびインポートする方法を示します。これは、更新中にファイルからコンテンツを作成する必要がある場合に役立ちます。インポートされたファイルのみをエクスポートでき、APIを使用して作成されたファイルはエクスポートできないことに注意してください。

例では、以前に作成された可能性のあるファイルを更新してインポートする必要があるというシナリオを示します。

例17-6 リクエスト出力の手動エクスポートおよびインポート

import oracle.as.scheduler.request.ContentFactory;
import oracle.as.scheduler.request.ImportExportResult;
import oracle.as.scheduler.request.ImportExportResult.ImportExportStatus;
import oracle.as.scheduler.request.OutputContentHelper;
import oracle.as.scheduler.request.OutputContentHelper.CommitSemantics;

class ExampleExportImport{
 
    OutputContentHelper helper = ContentFactory.getOutputContentHelper(requestId);
 
    if (!helper.outputDirectoryExists())
    {
        // error - make sure job definition defines SYS_EXT_supportOutputFiles
    }
 
    String outputDir = helper.getResolvedOutputDirectory();
    String fileName = "myfile.out";
    List<String> fileNamesList = new ArrayList<String>();
    fileNamesList.add(fileName);
 
    // Export the file if it exists; otherwise, create it.
 
    if (helper.outputContentExists(fileName))
    {
        ImportExportResult exportResult = exportOutputContent(fileNamesList);
        if (exportResult.getStatus() != ImportExportStatus.Success)
        {
          // handle error
        }
    }
    else
    {
        File f = new File(outputDir, fileName);
        f.createNewFile();
    }
 
    // ... update the file as needed ...
 
    // Import the new or updated file.
    // Updated file overwrites previous contents.
 
    ImportExportResult importResult =
        helper.importOutputFile(fileNamesList, CommitSemantics.IgnoreErrors);
 
    if (importResult.getStatus() != ImportExportStatus.Success)
    {
        // handle error
    }
}

17.2.5 PL/SQLジョブからのリクエスト出力の作成

PL/SQLからリクエスト出力を作成する場合は、コンテンツ・ストアに直接出力コンテンツを作成するために、コードでESS_JOB PL/SQLパッケージを使用できます。

ジョブでは、パッケージ内のファンクションおよびプロシージャを使用して、テキストまたはバイナリ出力コンテンツを作成できます。

17.2.5.1 出力を作成するためのPL/SQLパッケージ・サポート

表17-11 リクエスト出力用のESS_JOBプロシージャおよびファンクション

メソッド 説明

open_text_output_content( p_content_name in varchar2 ) return varchar2

open_binary_output_content( p_content_name in varchar2 ) return varchar2

現在のセッションに関連付けられているリクエストに対して、指定された出力コンテンツを開いてハンドルを返します。

適切なコンテンツ・タイプ定数によりopen_output_contentをコールする便利なファンクションがあります。詳細は、open_output_contentを参照してください。

open_output_content( p_content_name in varchar2, p_content_type in integer ) return varchar2;

現在のセッションに関連付けられているリクエストに対して、出力コンテンツp_content_nameを開いて不透明なハンドルを返します。

指定された名前の出力コンテンツ・エントリが存在しない場合、そのエントリが新規に作成されます。すでに存在する場合は、その名前に対して確立されているコンテンツ・タイプと指定されたコンテンツ・タイプが一致する必要があります。

p_content_typeは、次のいずれかのコンテンツ・タイプ定数を持つコンテンツ・タイプを表します。

CONTENT_TYPE_TEXT (値: 1)(テキスト・コンテンツの場合)

CONTENT_TYPE_BINARY (値: 2)(バイナリ・コンテンツの場合)

これにより、出力コンテンツを操作する後続プロシージャに渡される不透明なハンドルが返されます。

このファンクションから正しい結果が返されると、コンテンツ・エントリはロックされます。このプロシージャが失敗した場合は、ロックされる場合とされない場合とがあります。コミットまたはロールバックによりロックが解放されます。テキスト・コンテンツのデータを書き込むにはwrite_text_contentまたはwrite_ntext_contentプロシージャを、バイナリ・コンテンツのデータを書き込むにはwrite_binary_contentプロシージャを使用する必要があります。

このメソッドによって返されるハンドルに関連付けられているリソースを解放するには、close_contentをコールする必要があります。クローズはトランザクションのコミットまたはロールバックの前に行う必要があります。

注意: コンテンツ出力サポートにはDMLセマンティクスが含まれます。コミットおよびロールバックは、コール元が行います。

write_ntext_content( p_content_handle in varchar2, p_data in nvarchar2 )

write_text_content( p_content_handle in varchar2, p_data in varchar2 );

指定されたハンドルに関連付けられている出力コンテンツにデータをp_dataとして書き込みます。これらの操作は、CONTENT_TYPE_TEXTコンテンツ・タイプでのみサポートされます。

p_content_handleは、以前のopen_output_contentコールからの出力ハンドルです。

注意: コンテンツ出力サポートにはDMLセマンティクスが含まれます。コミットおよびロールバックは、コール元が行います。

write_binary_content( p_content_handle in varchar2, p_data in raw );

指定されたハンドルに関連付けられている出力コンテンツにバイナリ・データをp_dataとして書き込みます。この操作は、CONTENT_TYPE_BINARYコンテンツ・タイプでのみサポートされます。

p_content_handleは、以前のopen_output_contentコールからの出力ハンドルです。

注意: コンテンツ出力サポートにはDMLセマンティクスが含まれます。コミットおよびロールバックは、コール元が行います。

close_content( p_content_handle in varchar2 );

出力コンテンツ・ハンドルをクローズします。これにより、指定されたハンドルに関連付けられているリソースが解放され、ハンドルが無効になります。このメソッドは、トランザクションのコミットまたはロールバックより前にコールしてください。

p_content_handleは、以前のopen_output_contentコールからの出力ハンドルです。

注意: コンテンツ出力サポートにはDMLセマンティクスが含まれます。コミットおよびロールバックは、コール元が行います。このメソッドでは、コミットまたはロールバックは自動的には実行されません。

output_content_exists( p_content_name in varchar2 ) return boolean;

現在のセッションに関連付けられているリクエストに対して、指定された名前を持つ出力コンテンツ・エントリがすでに存在する場合はtrueを返します。

p_content_nameは、出力コンテンツ・エンティティの名前です。

delete_output_content( p_content_name in varchar2 );

現在のセッションに関連付けられているリクエストに対して、指定された出力コンテンツを削除します。

p_content_nameは、出力コンテンツ・エンティティの名前です。


17.2.5.2 PL/SQL出力作成の例

例17-7では、テキスト・コンテンツを出力に書き込む方法およびログ・エントリを書き込む方法を示します。

例17-7 PL/SQLのリクエスト・テキスト出力

create or replace procedure text_output_example_job
( request_handle in varchar2 )
as
  v_request_id  number := null;
  v_content_name  varchar2(100) := 'mycontent.txt';
  v_content_handle  varchar2(100);
  v_ntext nvarchar2(100);
begin
  ess_job.write_log(ess_job.LEVEL_FINE,
                    'TEXT_OUTPUT_EXAMPLE_JOB Procedure Begin');
 
  -- Oracle Enterprise Scheduler request id being executed.
  begin
    v_request_id := ess_runtime.get_request_id(request_handle);
  exception
    when others then
      ess_job.write_log(ess_job.LEVEL_SEVERE,
                        'Bad request handle: '||request_handle);
      raise_application_error(-20000,
         'Failed to get request id for request handle '||request_handle,
         true);
  end;
 
  begin
    -- ----------
    -- Delete content entry if it already exists.
    -- ----------
    if (not ess_job.output_content_exists(v_content_name)) then
      ess_job.write_log(ess_job.LEVEL_FINEST,
                        'Content does not exist: ' || v_content_name);
    else
      ess_job.write_log(ess_job.LEVEL_INFO,
                        'Deleting existing content: ' || v_content_name);
      ess_job.delete_output_content(v_content_name);
      commit;
    end if;
 
    -- ----------
    -- Write text content. Source data has some non-ascii chars.
    -- Illustrate multiple writes.
    -- ----------
    ess_job.write_log(ess_job.LEVEL_FINE,
                      'Write text content: '||v_content_name);
 
    v_content_handle := null;
    v_content_handle := ess_job.open_text_output_content(v_content_name);
 
    ess_job.write_text_content(v_content_handle,
                               'Data ');
    ess_job.write_ntext_content(v_content_handle,
                                unistr('(NTEXT data:\00c4\00c5)'));
    ess_job.write_text_content(v_content_handle,
                               ' for CONTENT ' || v_content_name);
 
    ess_job.close_content(v_content_handle);
    v_content_handle := null;
    commit;
  exception
    when others then
      ess_job.write_log(ess_job.LEVEL_WARNING,
                        'Error during text output operations. ' ||
                        'content: ' || v_content_name || chr(10) ||
                        'Error_Stack...' || chr(10) ||
                        dbms_utility.format_error_stack() || chr(10) ||
                        'Error_Backtace...' || chr(10) ||
                        dbms_utility.format_error_backtrace());
      if v_content_handle is not null then
        ess_job.close_content(v_content_handle);
        v_content_handle := null;
      end if;
      rollback;
      raise_application_error(-20000,
            'Output content operations failed for '||v_content_name);
  end;
 
  ess_job.write_log(ess_job.level_info,
                    'TEXT_OUTPUT_EXAMPLE_JOB Procedure End');
end;
/

例17-8では、出力にバイナリ・コンテンツを書き込む方法を示します。

例17-8 PLSQLのリクエスト・バイナリ出力の例

create or replace procedure binary_output_example_job
( request_handle in varchar2 )
as
  v_request_id  number := null;
  v_content_name  varchar2(100) := 'mycontent.bin';
  v_content_handle  varchar2(100);
  v_nchar_cs varchar2(100);
  v_dest_cs varchar2(100);
  v_ntext nvarchar2(100);
  v_raw raw(500);
begin
  ess_job.write_log(ess_job.LEVEL_FINE,
                    'BINARY_OUTPUT_EXAMPLE_JOB Procedure Begin');
 
  -- Oracle Enterprise Scheduler request id being executed.
  begin
   v_request_id := ess_runtime.get_request_id(request_handle);
  exception
    when others then
      ess_job.write_log(ess_job.LEVEL_SEVERE,
                        'Bad request handle: '||request_handle);
      raise_application_error(-20000,
         'Failed to get request id for request handle '||request_handle,
         true);
  end;
 
  begin
    -- ----------
    -- Delete content entry if it already exists.
    -- ----------
    if (not ess_job.output_content_exists(v_content_name)) then
      ess_job.write_log(ess_job.LEVEL_FINEST,
                        'Content does not exist: ' || v_content_name);
    else
      ess_job.write_log(ess_job.LEVEL_INFO,
                        'Deleting existing content: ' || v_content_name);
      ess_job.delete_output_content(v_content_name);
      commit;
    end if;
 
    -- ----------
    -- Write binary content.
    -- This will be UTF-8 representation of a string for a known byte
    -- encoding rather than whatever the charset/national charset
    -- happens to be for this database.
    -- Source data has couple non-ascii chars.
    -- ----------
 
    -- database national character set being used
    select value into v_nchar_cs
      from nls_database_parameters
      where parameter = 'NLS_NCHAR_CHARACTERSET';
    ess_job.write_log(ess_job.LEVEL_FINEST,
                      'NLS_NCHAR_CHARACTERSET = '||v_nchar_cs);
 
    ess_job.write_log(ess_job.LEVEL_FINE,
                      'Write binary content: '||v_content_name);
 
    v_content_handle := null;
    v_content_handle := ess_job.open_binary_output_content(v_content_name);
 
    v_ntext := unistr('Data (NTEXT data:\00c4\00c5) for CONTENT ' ||
                      v_content_name);
 
    v_dest_cs := 'AL32UTF8';
    v_raw := utl_raw.cast_to_raw(convert(v_ntext, v_dest_cs, v_nchar_cs));
    ess_job.write_binary_content(v_content_handle, v_raw);
    ess_job.write_log(ess_job.LEVEL_FINE,
                      'Wrote '||utl_raw.length(v_raw)||' bytes' ||
                      ' using ' || v_dest_cs || ' charset');
 
    ess_job.close_content(v_content_handle);
    v_content_handle := null;
    commit;
  exception
    when others then
      ess_job.write_log(ess_job.LEVEL_WARNING,
                        'Error during binary output operations. ' ||
                        'content_name=' || v_content_name || chr(10) ||
                        'Error_Stack...' || chr(10) ||
                        dbms_utility.format_error_stack());
      if v_content_handle is not null then
        ess_job.close_content(v_content_handle);
        v_content_handle := null;
      end if;
      rollback;
      raise_application_error(-20000,
            'Output content operations failed for '||v_content_name);
  end;
 
  ess_job.write_log(ess_job.level_info,
                    'BINARY_OUTPUT_EXAMPLE_JOB Procedure End');
end;
/

17.2.6 プロセス・ジョブからのリクエスト出力の作成

すべてのプロセス・ジョブで使用できるESS_OUTPUT_WORK_DIR環境変数により指定された場所にコンテンツを書き込むことによって、プロセス・ジョブ・ロジックから出力を作成します。他のジョブと同様に、SYS_EXT_supportOutputFilesシステム・プロパティがoutputに設定されており、ジョブに対して環境変数が定義されるようになっていることを確認してください。

プロセス・コードによりファイルが書き込まれると、Oracle Enterprise Schedulerにより自動的に、ディレクトリ内の出力ファイルがバイナリ・コンテンツとしてコンテンツ・ストアにインポートされます。