ヘッダーをスキップ
Oracle® GoldenGate Application Adapters Oracle GoldenGateアダプタの管理
12c (12.1.2.1.1)
E67383-01
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

16 カスタム・フィルタ、フォーマッタおよびハンドラの開発

この章では、イベント・フィルタ、組込みハンドラ用のカスタム・フォーマッタまたはカスタム・イベント・ハンドラを実装するJavaコードの記述について説明します。Velocityテンプレートを介したカスタム形式の指定についても取り上げます。

この章の内容は次のとおりです。

16.1 イベントのフィルタリング

デフォルトでは、すべてのトランザクション、操作およびメタデータ・イベントがDataSourceListenerイベント・ハンドラに渡されます。イベント・フィルタを実装して、ハンドラに送信するイベントをフィルタできます。たとえば、フィルタで、特定の列値を含む特定の表に対する特定の操作を選択できます。

フィルタは相加的です。複数のフィルタがハンドラに設定されている場合、イベントがハンドラに渡されるには、すべてのフィルタがtrueを返す必要があります。

フィルタは、Javaアプリケーション・プロパティ・ファイルを使用して構成できます。

# handler "foo" only receives certain events
gg.handler.one.type=jms
gg.handler.one.format=mytemplate.vm
gg.handler.one.filter=com.mycompany.MyFilter

フィルタをアクティブにするには、フィルタを記述し、ハンドラに設定します。追加のロジックを特定のハンドラに追加する必要はありません。

16.2 カスタム・フォーマット

次のようにして、組込みハンドラの出力フォーマットをカスタマイズできます。

  • Javaでのカスタム・フォーマッタの記述。または

  • Velocityテンプレートの使用

16.2.1 Javaでのカスタム・フォーマッタのコーディング

これより前の例で、同じフォーマッタ(com.mycompany.MyFormatter)を使用するJMSハンドラとファイル出力ハンドラを示しています。次の例は、このフォーマッタの実装方法の例です。

例16-1 カスタム・フォーマットの実装

package com.mycompany.MyFormatter;
import com.goldengate.atg.datasource.DsOperation;
import com.goldengate.atg.datasource.DsTransaction;
import com.goldengate.atg.datasource.format.DsFormatterAdapter;
import com.goldengate.atg.datasource.meta.ColumnMetaData;
import com.goldengate.atg.datasource.meta.DsMetaData;
import com.goldengate.atg.datasource.meta.TableMetaData;
import java.io.PrintWriter;
public class MyFormatter extends DsFormatterAdapter {
        public MyFormatter() { }
        @Override
        public void formatTx(DsTransaction tx,
DsMetaData meta,
PrintWriter out)
        {
            out.print("Transaction: " );
            out.print("numOps=\'" + tx.getSize() + "\' " );
            out.println("ts=\'" + tx.getStartTxTimeAsString() + "\'");
            for(DsOperation op: tx.getOperations()) {
TableName currTable = op.getTableName();
TableMetaData tMeta = dbMeta.getTableMetaData(currTable);
String opType = op.getOperationType().toString();
String table = tMeta.getTableName().getFullName();
out.println(opType + " on table \"" + table + "\":" );
int colNum = 0;
for(DsColumn col: op.getColumns())
{
ColumnMetaData cMeta = tMeta.getColumnMetaData( colNum++ );
out.println(
cMeta.getColumnName() + " = " + col.getAfterValue() );
}
        }
        @Override
        public void formatOp(DsTransaction tx,
DsOperation op,
TableMetaData tMeta,
PrintWriter out)
        {
            // not used...
        }
}

フォーマッタは、トランザクション全体のフォーマット(コミット後)、または各操作のフォーマット(受信後、コミット前)の方法を定義します。フォーマッタが操作モードの場合、formatOp(...)がコールされます。そうではない場合、トランザクション・コミット時にformatTx(...)がコールされます。

このカスタム・フォーマッタをコンパイルして使用するには、Java用Oracle GoldenGate jarをクラスパスに含め、コンパイルした.classファイルをgg_install_dir/dirprmに配置します。

javac -d gg_install_dir/dirprm
-classpath ggjava/ggjava.jar MyFormatter.java

結果のクラス・ファイルは、resources/classesに(正しいパッケージ構造で)配置されます。

gg_install_dir/dirprm/com/mycompany/MyFormatter.class

あるいは、カスタム・クラスをjarに含めることもできます。この場合、jarファイルをユーザー・イグジット・プロパティを介してJVMクラスパスに含める(jvm.bootoptionsプロパティでjava.class.pathを使用)か、Javaアプリケーション・プロパティ・ファイルを設定してカスタムjarを含めます。

# set properties on 'one'
gg.handler.one.type=file
gg.handler.one.format=com.mycompany.MyFormatter
gg.handler.one.file=output.xml
gg.classpath=/path/to/my.jar,/path/to/directory/of/jars/*

16.2.2 Velocityテンプレートの使用

Velocityテンプレートは、カスタム・フォーマット用のJavaコードを記述するかわりの方法として、フォーマッタのプロトタイプを簡単に作成するよい代替方法です。たとえば、次のテンプレートをJMSまたはファイル・ハンドラの形式として指定します。

Transaction: numOps='$tx.size' ts='$tx.timestamp'
#for each( $op in $tx )
operation: $op.sqlType, on table "$op.tableName":
#for each( $col in $op )
$op.tableName, $col.meta.columnName = $col.value
#end
#end

テンプレートの名前がsample.vmとすると、次のようにクラスパスに配置します。

gg_install_dir/dirprm/sample.vm

注意:

Velocityテンプレートを使用する場合、ファイル名は接尾辞.vmで終わる必要があります。そうでない場合、フォーマッタはJavaクラスとみなされます。

テンプレートを使用するようJavaアプリケーション・プロパティ・ファイルを更新します。

# set properties on 'one'
gg.handler.one.type=file
gg.handler.one.format=sample.vm
gg.handler.one.file=output.xml

テンプレートを変更する場合、Javaソースを再コンパイルする必要はありません。テンプレートを保存してJavaアプリケーションを再実行するのみです。アプリケーションを実行すると、次の出力が生成されます(表の名前はSCHEMA.SOMETABLEで、列はTESTCOLAおよびTESTCOLBとします)。

Transaction: numOps='3' ts='2008-12-31 12:34:56.000'
operation: UPDATE, on table "SCHEMA.SOMETABLE":
SCHEMA.SOMETABLE, TESTCOLA = value 123
SCHEMA.SOMETABLE, TESTCOLB = value abc
operation: UPDATE, on table "SCHEMA.SOMETABLE":
SCHEMA.SOMETABLE, TESTCOLA = value 456
SCHEMA.SOMETABLE, TESTCOLB = value def
operation: UPDATE, on table "SCHEMA.SOMETABLE":
SCHEMA.SOMETABLE, TESTCOLA = value 789
SCHEMA.SOMETABLE, TESTCOLB = value ghi

16.3 Javaでのカスタム・ハンドラのコーディング

カスタム・ハンドラは、AbstractHandlerを拡張して実装できます。

import com.goldengate.atg.datasource.*;
import static com.goldengate.atg.datasource.GGDataSource.Status;
public class SampleHandler extends AbstractHandler {
        @Override
        public void init(DsConfiguration conf, DsMetaData metaData) {
            super.init(conf, metaData);
            // ... do additional config...
        }
        @Override
        public Status operationAdded(DsEvent e, DsTransaction tx, DsOperation op) { ... }
        @Override
        public Status transactionCommit(DsEvent e, DsTransaction tx) { ... }
        @Override
        public Status metaDataChanged(DsEvent e, DsMetaData meta) { .... }
        @Override
        public void destroy() { /* ... do cleanup ... */ }
        @Override
        public String reportStatus() { return "status report..."; }
}

トランザクションがExtractから処理される際、ハンドラへのコール順序は次のようになります。

  1. 初期化:

    • まず、ハンドラが構築されます。

    • 次に、インスタンスでプロパティ・ファイルの値を使用してすべてのセッターがコールされます。

    • 最後に、ハンドラが初期化されます。トランザクションを受信する前にinit(...)メソッドがコールされます。init(...)メソッドでsuper.init(...)をコールして基底クラスを適切に初期化することが重要です。

  2. メタデータが受信されます。ユーザー・イグジットが、この実行時にまだ出現していない表での操作を処理する場合、メタデータ・イベントが発行され、metadataChanged(...)メソッドがコールされます。通常は、このメソッドを実装する必要はありません。DsMetaDataは、新規データ・ソース・メタデータが受信されると自動的に更新されます。

  3. トランザクションが開始されます。トランザクション・イベントが発行され、ハンドラでtransactionBegin(...)メソッドが起動されます(記載していません)。この時点ではトランザクションに操作がないため、これは通常使用されません。

  4. 操作が順次トランザクションに追加されます。これによって、各操作の追加のたびにハンドラでoperationAdded(...)メソッドがコールされます。データ・ソース・メタデータ(この時点までに出現したすべての表メタデータを含む)とともに、これを含むトランザクションもメソッドに渡されます。トランザクションはまだコミットされておらず、コミットが受信される前に異常終了される可能性があることに注意してください。

    各操作にはトランザクションの列値が含まれます(Extractが圧縮更新を処理する場合、変更された値のみの可能性があります)。列値には、ビフォア値とアフター値の両方が含まれることがあります。

  5. トランザクションがコミットされます。これによって、transactionCommit(...)メソッドがコールされます。

  6. 定期的にreportStatusがコールされます。プロセスの停止時にもコールされます。通常、これによって処理の統計が表示されます(操作数/処理されたトランザクション、など)。

単純なプリンタ・ハンドラの完全な例を次に示します。トランザクション、操作およびメタデータの非常に基本的なイベント情報を単に出力するだけです。ハンドラには、出力ファイル名を設定するためのプロパティmyoutputもあります。これは、Javaアプリケーション・プロパティ・ファイルで次のように設定できます。

gg.handlerlist=sample
# set properties on 'sample'
gg.handler.sample.type=sample.SampleHandler
gg.handler.sample.myoutput=out.txt

カスタム・ハンドラを使用するには、次のようにします。

  1. クラスをコンパイルします。

  2. クラスをアプリケーション・クラスパスに含めます。

  3. Javaアプリケーション・プロパティ・ファイルのアクティブ・ハンドラのリストにハンドラを追加します。

ハンドラをコンパイルするには、Java用Oracle GoldenGate jarをクラスパスに含め、コンパイルした.classファイルをgg_install_dir/javaue/resources/classesに配置します。

javac -d gg_install_dir/dirprm
-classpath ggjava/ggjava.jar SampleHandler.java

結果のクラス・ファイルは、次のようにresources/classesに(正しいパッケージ構造で)配置されます。

gg_install_dir/dirprm/sample/SampleHandler.class

注意:

サンプル"hello world"以外のJavaアプリケーションの開発では、AntまたはMavenを使用してアプリケーションをコンパイル、テストおよびパッケージ化します。javacを示した例は、例示目的のみです。

あるいは、カスタム・クラスをjarに含め、クラスパスに含めることができます。カスタムjarファイルをユーザー・イグジット・プロパティを介してJVMクラスパスに含める(jvm.bootoptionsプロパティでjava.class.pathを使用)か、Javaアプリケーション・プロパティ・ファイルを設定してカスタムjarを含めます。

# set properties on 'one'
gg.handler.one.type=sample.SampleHandler
gg.handler.one.myoutput=out.txt
gg.classpath=/path/to/my.jar,/path/to/directory/of/jars/*

任意のハンドラで、追加の個別jar、ディレクトリ(リソースまたはjarになっていないクラス・ファイルを含む)またはjarのディレクトリ全体を含めるようクラスパス・プロパティを設定できます。jarのディレクトリ全体を含めるには、Java 6形式の構文を使用します。

c:/path/to/directory/* (or on Unix: /path/to/directory/* )

ワイルドカード*のみ指定できます。ファイル・パターンは使用できません。これは、.jar接尾辞で終わるディレクトリ内のすべてのファイルに自動的に一致します。複数のjarまたは複数のディレクトリを含めるには、システム固有のパス区切り文字(UNIXではコロン、Windowsではセミコロン)を使用するか、前述のようにプラットフォームに依存しないカンマを使用します。

ハンドラに多数のプロパティを設定する必要がある場合、パラメータ・ファイルにプロパティを含めるだけで、ハンドラの対応するセッターがコールされます。次に例を示します。

gg.handler.one.type=com.mycompany.MyHandler
gg.handler.one.myOutput=out.txt
gg.handler.one.myCustomProperty=12345

前述の例では、カスタム・ハンドラ内の次のメソッドが起動されます。

public void setMyOutput(String s) {
        // use the string...
} public void setMyCustomProperty(int j) {
        // use the int...
}

int、long、String、booleanなどの標準のJava型を使用できます。カスタム型の場合、カスタム・プロパティ・エディタを作成してStringをカスタム型に変換できます。

16.4 追加リソース

Java APIにはJavadocが用意されています。Javadocは、カスタマイズおよび拡張に有用なインタフェースおよびクラスのみを配布するために、コア・パッケージ、クラスおよびインタフェースのセットに意図的に縮小されています。

各パッケージでは、わかりやすくするために一部のクラスが意図的に省略されています。重要なクラスは次のとおりです。

  • com.goldengate.atg.datasource.DsTransaction: データベース・トランザクションを表します。トランザクションには、0個以上の操作が含まれます。

  • com.goldengate.atg.datasource.DsOperation: データベース操作(挿入、更新、削除)を表します。操作には、データ変更イベントを表す0個以上の列値が含まれます。列索引は、Java APIで0でオフセットされます。

  • com.goldengate.atg.datasource.DsColumn: 列値を表します。列値は、ビフォア値とアフター値のコンポジットです。列値は存在する(値があるかnull)場合も欠落している(ソース証跡に含まれていない)場合もあります。

    • com.goldengate.atg.datasource.DsColumnCompositeは、コンポジットです。

    • com.goldengate.atg.datasource.DsColumnBeforeValueは、操作前の列値です(これはオプションで、操作に含まれていない場合があります)。

    • com.goldengate.atg.datasource.DsColumnAfterValueは、操作後の値です。

  • com.goldengate.atg.datasource.meta.DsMetaData: 出現するすべてのデータベース・メタデータを表します。オブジェクトは最初空です。DsMetaDataには、TableNameをキーとして使用するTableMetaDataの0個以上のインスタンスのハッシュ・マップが含まれます。

  • com.goldengate.atg.datasource.meta.TableMetaData: 1つの表のすべてのメタデータを表します。0個以上のColumnMetaDataを含みます。

  • com.goldengate.atg.datasource.meta.ColumnMetaData: データベースまたはOracle GoldenGateソース定義ファイルに定義されている列名およびデータ型を含みます。

詳細は、Javadocを参照してください。