プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Managed File Transferの使用
12c リリース(12.2.1.2)
E82801-03
目次へ移動
目次

前
次

3 カスタム・コールアウトによる転送の処理

Oracle Managed File Transfer (MFT)におけるファイル転送の前処理と後処理のためのカスタム・コールアウトの作成方法と使用方法を説明します。

コールアウトを作成するには、JavaおよびXMLコードに習熟しており、「アーティファクト(転送、ソースおよびターゲット)の設計」に説明されている転送の作成方法を習得している必要があります。

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

3.1 カスタム・コールアウトの理解

Oracle Managed File Transferには、転送の前処理および後処理のアクションに対して、組込みの圧縮、圧縮解除、暗号化および復号化の各アクションが用意されています。

カスタム・コールアウトと呼ばれる前処理アクションおよび後処理アクションを新しく作成できます。詳細は、転送の前処理と後処理のアクションの設定ソース処理アクションの設定を参照してください。

カスタム・コールアウト使用の例は、次のとおりです。

  • コピーライト・ヘッダーおよびフッターの追加

  • 内容の検証

  • 配信が成功または失敗した場合の個別のアプリケーションへの通知

  • 配信が成功または失敗した場合の個別のアプリケーションの起動

  • MFTデータベースに永続化されているカスタム・ヘッダーまたはプロパティの追加

  • 代替暗号化技術の追加

この章では、改行変換コールアウト例を使用します。その他のコールアウト・サンプルについては、http://www.oracle.com/technetwork/middleware/mft/index.htmlを参照してください。

カスタム・コールアウトは、ソースまたはターゲットと関連付けることができます。転送時の処理アクションの実行順序は次のとおりです。

  1. ソース前処理アクション

  2. ターゲット前処理アクション

  3. ペイロード配信

  4. ターゲット後処理アクション

注意:

MFTコンソールでは、ターゲット処理アクションは転送時に構成されます。「アーティファクト(転送、ソースおよびターゲット)の設計」では、これらのアクションは転送処理アクションと呼ばれています。この章では、これらのアクションをターゲット処理アクションと呼びます。

注意:

後処理は、ファイル配信の後に実行されます。したがって、配信が成功して後処理が失敗した場合、「監視」ページの「ダッシュボード」タブの「アクティブな配信」ビューと「ファイル・ファインダ」ビューに表示されるステータスは異なります。具体的には、「アクティブな配信」ビューでは「完了」ステータスが表示されますが、「ファイル・ファインダ」ビューでは「失敗」ステータスが表示されます。

表3-1は、作成できるコールアウトのタイプをまとめたものです。

表3-1 コールアウトのタイプ

コールアウトのタイプ インタフェース名 ペイロードの変更 ヘッダーおよびプロパティの変更

前処理

PreCalloutPlugin

使用可能

使用可能

後処理

PostCalloutPlugin

不可

使用可能

後処理 PostDeliveryFailureCalloutPlugin 不可  

3.2 カスタム・コールアウトの作成: 概略手順

カスタム・コールアウトの作成方法を説明します。

カスタム・コールアウトの作成の概略手順は次のとおりです。

  1. 該当するインタフェースに基づいてJavaソース・コードを作成し、JARファイルにパッケージ化します。「コードの作成」を参照してください。
  2. コールアウト・スキーマに基づいてコールアウト定義XMLファイルを作成します。「コールアウト定義ファイルの作成」を参照してください。
  3. JARファイルとXMLファイルをコールアウト・ディレクトリにコピーします。「コールアウト・ディレクトリの位置特定」を参照してください。
  4. createCallouts WLSTコマンドを実行して、MFTでコールアウトを構成します。「createCalloutsコマンドの実行」を参照してください。
  5. コールアウトをファイル転送で使用して、コールアウトをテストします。「コールアウトのテスト」を参照してください。

次の各項では、改行変換コールアウト例を使用してこれらの手順を詳しく説明します。改行(行末中断や行端(EOL)マーカーとも呼ばれる)は、テキストの行の末尾を示す特殊文字または特殊文字列です。UNIXオペレーティング・システムでは、DOS (およびWindows)オペレーティング・システムとは異なる改行文字を使用します。このコールアウトを使用すると、改行文字をDOSからUNIXへ、またはUNIXからDOSへ変換できます。

3.3 コードの作成

カスタム・コールアウトの作成手順の1つは、Javaコードの作成です。

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

3.3.1 Javaコードに関する要件とヒント

Javaコードでコールアウト・アクションを定義します。次の最低要件を満たす必要があります。

  • java.io.IOExceptionjava.io.InputStreamjava.io.OutputStreamおよびjava.util.Mapの各クラスをインポートする必要があります。

  • com.oracle.tip.mft.engine.processor.pluginパッケージ内のPluginOutputクラスとPluginContextクラスをインポートする必要があります。

  • com.oracle.calloutパッケージ内のPreCalloutPluginインタフェースまたはPostCalloutPluginインタフェースを実装する必要があります。

    インタフェースの内容については、「PreCalloutPluginインタフェース」または「PostCalloutPluginインタフェース」を参照してください。

  • JARファイルにパッケージ化される必要があります。

    複数のコールアウトを同じJARファイルに含めるか、個別のJARファイルにパッケージ化できます。

コールアウトでヘッダー変数を設定するには、次のようなコードを使用します。

context.getCustomPropertyMap().put("name", "value");
context.getTransportHeaderMap().put("name", "value");

コールアウトでペイロード・ファイル名前を変更するには、次のようなコードを使用します。

PluginOutput pOutput = new PluginOutput();
    pOutput.setNewFileName("abc.xyz");
  return pOutput;

コールアウトでソース前処理、ソース後処理、ターゲット前処理およびターゲット後処理の各種アクションを実行するには、次のようなコードを使用します。

if(message instanceof oracle.tip.mft.bean.SourceMessage){
    // in case of source pre and post processing
} else if(message instanceof oracle.tip.mft.bean.Instance){
    // in case of target pre
} else if(message instanceof oracle.tip.mft.bean.TargetMessage ){
    // in case of target post
} 

コードをコンパイルするには、クラスパスにコアMFT JARファイルを指定して次のようなコマンドを使用します。

javac -classpath $MW_HOME/mft/modules/oracle.mft/core.jar <class>

JARファイルを作成するには、次のコマンドを使用します。

jar cf newlineConversion.jar

3.3.2 改行変換例のJavaコード

改行変換例のJavaクラスは、次のアクションを実行します。

  1. コールアウトがペイロードを変更するように指定します。

  2. Typeパラメータ値を受け入れ、コールアウトがDos2UnixUnix2Dosのいずれであるかを指定します。

  3. Type値を指定しないとnullが返されます。

  4. doLineConversionメソッドを使用してペイロードの各行を、選択した改行文字で書き直します。

  5. 改行が変更されたペイロード・ファイルのコピーが返されます。

「例 - 改行変換コード」は、改行変換例のJavaクラス・コードを示しています。

package com.oracle.callout.sample;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Map;

import oracle.tip.mft.engine.processsor.plugin.PluginContext;
import oracle.tip.mft.engine.processsor.plugin.PluginOutput;
import oracle.tip.mft.engine.processsor.plugin.PreCalloutPlugin;

public class NewlineConversion implements PreCalloutPlugin {

    @Override
    public boolean isPayloadChangeRequired(PluginContext context,
            Map<String, String> calloutParams) {
        return true;
    }

    @Override
    public PluginOutput process(PluginContext context, InputStream input,
            OutputStream out, Map<String, String> calloutParams) {
        String type = calloutParams.get("Type");
        boolean isDos = false;
        if ("Unix2Dos".equals(type)) {
            isDos = true;
        }
        doLineConversion(input, out, isDos);
        return new PluginOutput();
    }

    @Override
    public PluginOutput process(PluginContext context, InputStream input,
            Map<String, String> calloutParams) {
        return null;
    }

    public static final String DOS_NEW_LINE = "\r\n";
    public static final String UNIX_NEW_LINE = "\n";

    private void doLineConversion(InputStream in, OutputStream out,
            boolean isDos) {
        String newLineChar = null;
        if (isDos) {
            newLineChar = DOS_NEW_LINE;
        } else {
            newLineChar = UNIX_NEW_LINE;
        }
        BufferedReader bufferIn = null;
        BufferedWriter bufferOut = null;
        try {
            DataInputStream dataIn = new DataInputStream(in);
            bufferIn = new BufferedReader(new InputStreamReader(dataIn));
            DataOutputStream dataOut = new DataOutputStream(out);
            bufferOut = new BufferedWriter(new OutputStreamWriter(dataOut));
            // For each line in the un-normalized file
            String line;
            while ((line = bufferIn.readLine()) != null) {
                // Write the original line plus the operating-system dependent
                // newline
                bufferOut.write(line);
                bufferOut.write(newLineChar);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bufferIn.close();
                bufferOut.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3.4コールアウト定義ファイルの作成

定義ファイルでMFT構成のコールアウト構造を指定します。ファイルは、特定の要件、たとえば、xml形式、属性値、入力パラメータ値が正しいという条件を満たす必要があります。

コールアウト定義ファイルの作成要件は次のとおりです。

  • callout.xsdスキーマ・ファイルで指定したXML形式に準拠している必要があります。スキーマ・ファイルの内容については、「コールアウト定義スキーマ」を参照してください。

    複数のコールアウトを同じ定義ファイルに含めるか、個別の定義ファイルにパッケージ化できます。

  • デバッグが不十分な、無限ループを含むコールアウトが非常に長い時間実行されるのを防止するため、Callout要素のtimeout属性に値(秒単位)が指定されている必要があります。

  • Callout要素のimplementationClass属性は、パッケージ名などのJavaクラス名を参照する必要があります。

  • Callout要素のlibraryName属性は、JARファイル名を参照する必要があります。

  • Javaクラスに入力パラメータがある場合は、対応するParameter要素を指定する必要があります。

「例 - 改行変換コールアウト定義ファイル」は、改行変換例のコールアウト定義ファイルを示しています。

<?xml version="1.0" encoding="UTF-8"?>
<mft:Callouts xmlns:mft="http://xmlns.oracle.com/mft" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://xmlns.oracle.com/mft callout.xsd ">
    <mft:Callout description="New line conversion"
        helpText="New line conversion"
        groupName="Source-pre,Target-pre" timeout="300" 
        implementationClass="com.oracle.callout.sample.NewlineConversion"
        libraryName="newlineConversion.jar" name="New line conversion">
        <mft:Parameter description="Type" mandatory="true" helpText="Type"
            name="Type" listValue="Dos2Unix,Unix2Dos"
            parameterType="string" defaultValue="Dos2Unix"/>
    </mft:Callout>
</mft:Callouts>

3.5 コールアウト・ディレクトリの位置特定

JARファイルと定義ファイルを作成したら、それらのファイルをMFTコールアウト・ディレクトリにコピーする必要があります。コールアウト・ディレクトリのデフォルトの場所は、MFT構成で確認できます。

このディレクトリのデフォルトの場所は次のとおりです。

FMW_HOME/user_projects/domains/soainfra/mft/callouts

この場所を確認するには、MFT構成を調べます。

このプロセスの手順は次のとおりです。

  1. 「管理」ページに移動します。

  2. 左側のナビゲーション・ペインで、「サーバー・プロパティ」をクリックします。

  3. ページの上端付近にある「コールアウト・ディレクトリ」設定を調べます。

3.6 createCalloutsコマンドの実行

JARファイルと定義ファイルをMFTコールアウト・ディレクトリにコピーした後、createCalloutsコマンドを使用してコールアウト定義をMFT構成にアップロードします。

次の手順に従って、createCalloutコマンドを実行します。

  1. 「WLSTコマンドの実行」で説明されている手順を使用してWLSTを起動します。
  2. createCalloutsコマンドを使用してコールアウト定義ファイルのフルパスを指定します。
    crtCalls('/home/user_projects/domains/soainfra/mft/callouts/Newline.xml')
    

    例では、crtCallsという省略形を使用します。

  3. listCalloutsコマンドを使用してコールアウトが追加されたことを確認します。
    listCallouts()
    
  4. 「WLSTコマンドの実行」で説明されている手順を使用してWLSTを終了します。

MFT WLSTコマンドの詳細は、SOA Suite WLSTコマンド・リファレンスMFTのWLSTコマンドの要約およびMFTカスタムWLSTコマンドを参照してください。

3.7 コールアウトのテスト

コールアウトを作成してコールアウト定義をアップロードした後、コールアウトをテストして設計どおりに確実に機能するようにする必要があります。

カスタム・コールアウトのテストの概略手順は次のとおりです。

  1. コールアウトをソースとターゲットに追加して、関連付けられた転送をデプロイします。「ソースへのコールアウトの追加」または「ターゲットへのコールアウトの追加」を参照してください。
  2. 転送を実行したら、ソースまたはターゲットのレポートを調べます。「コールアウト・アクションを確認するためのレポートの表示」を参照してください。
  3. エラー修正や改善が必要な場合はコールアウトを更新します。「コールアウトの更新」を参照してください。

注意:

createCalloutsコマンドを実行するときにMFTコンソールにログインした場合は、コールアウトをソースまたはターゲットに追加するには、事前にMFTコンソールからログアウトして再度ログインする必要があります。

3.7.1 ソースへのコールアウトの追加

改行変換コールアウトをソースに追加する手順は次のとおりです。

  1. 左側のペインのナビゲータで「ソース」の左にある矢印をクリックします。

    ソースがリストされます。

  2. ソース名をクリックするか、ソース名を右クリックして「開く」メニュー・アイテムを選択します。

    そのソースのタブが開きます。

  3. 「アクション」の左にある矢印をクリックします。

    「アクション」セクションが開きます。

  4. 「処理アクションの追加」をクリックします。

    「処理アクション」ダイアログが開きます。

  5. 「すべてのアクション」ドロップダウン・リストで、改行変換を選択します。
  6. 「リストに追加」をクリックします。

    リストからアクションを削除するには、アクションの右にある「削除」アイコンをクリックします。

  7. 「タイプ」テキスト・ボックスにDos2UnixまたはUnix2Dosと入力します。
  8. 「OK」をクリックします。

    アクションの追加を取り消すには、「取消」をクリックします。

  9. ソースを保存して、オプションでデプロイします。
  10. ソースを転送に追加し、「デプロイ」を選択して転送をデプロイします。

    詳細は、「転送のデプロイとテスト」を参照してください。

3.7.2 ターゲットへのコールアウトの追加

改行変換コールアウトをターゲットに追加する手順は次のとおりです。

  1. 左側のペインのナビゲータで「転送」の左にある矢印をクリックします。

    転送がリストされます。

  2. 転送名をクリックするか、転送名を右クリックして「開く」メニュー・アイテムを選択します。

    その転送のタブが開きます。

  3. ターゲットの左にある矢印をクリックします。

    ターゲット設定が表示されます。

  4. 「前処理アクションの追加」をクリックします。

    「前処理アクション」ダイアログが開きます。

  5. 「すべてのアクション」ドロップダウン・リストで、改行変換を選択します。
  6. 「リストに追加」をクリックします。

    リストからアクションを削除するには、アクションの右にある「削除」アイコンをクリックします。

  7. 「タイプ」テキスト・ボックスにDos2UnixまたはUnix2Dosと入力します。
  8. 「OK」をクリックします。

    アクションの追加を取り消すには、「取消」をクリックします。

  9. 転送を保存してデプロイします。

    詳細は、「転送のデプロイとテスト」を参照してください。

3.7.3 コールアウト・アクションを確認するためのレポートの表示

ソースまたはターゲットのレポートにアクセスするには、「監視」ページに移動し、「ソース、転送およびターゲットのレポートの解釈」を参照してください。

改行変換コールアウトは、ソース・レポートの「ソース前処理」表または、ターゲット・レポートの「ターゲット前処理」表に表示されています。コールアウト・アクションが成功した場合は、どちらの表の「ステータス」列にも「処理済」と表示されます。

さらに、コールアウト・アクションが成功した場合は、レポートの「拡張」セクションの「メッセージ・プロパティ」フィールドにpayloadModified=yesと表示されます。

詳細は、「ソース・レポート」または「ターゲット・レポート」を参照してください。

3.7.4 コールアウトの更新

コールアウトを更新するときは次の点に留意してください。

  • コールアウトを作成または更新するときは、MFTサーバーの再起動は必要ありません。

  • Javaコードのみを変更してパラメータを変更しない場合は、必要な作業は新しいJARファイルをコールアウト・ディレクトリにコピーすることのみです。

  • 定義ファイルを変更してパラメータを変更しない場合は、必要な作業はupdateCalloutsコマンドを使用して新しいコールアウト定義に再ロードすることのみです。

  • コールアウト・パラメータの追加、削除または変更を行った場合は、次の手順を実行する必要があります。

    1. deleteCalloutコマンドを使用してコールアウトを削除します。

    2. createCalloutsコマンドを使用してコールアウトを再作成します。

    3. 新しいコールアウト・バージョンを使用するようにソースまたはターゲットを再構成します。

MFT WLSTコマンドの詳細は、『SOA Suite WLSTコマンド・リファレンス』「MFTのWLSTコマンドの要約」およびMFTコールアウト・コマンドに関する項を参照してください。

3.8 参照ファイル

参照ファイルは、カスタム・コールアウトの一例を示しています。

この項では、次のファイルの内容を示します。

3.8.1 PreCalloutPluginインタフェース

「例 - PreCalloutPluginインタフェース」は、com.oracle.callout.PreCalloutPluginインタフェースのJavaコードを示しています。

例 - PreCalloutPluginインタフェース

 public interface PreCalloutPlugin {
 
    /**
     * Depending on the return of this function output stream for changing the
     * pay load content will be passed. Only if the payload change is required
     * return true.
     *
     * @param context
     * @param calloutParams
     * @return
     */
    public boolean isPayloadChangeRequired(final PluginContext context,
            final Map<String, String> calloutParams);
 
    /**
     * This function will be called only if the isPayloadChangesRequired returns
     * true. This method must write final pay load content to the output stream.
     * Any custom properties or the header properties can be set at the context
     * level.
     *
     * @param context
     * @param input
     * @param out
     * @param calloutParams
     * @return
     */
    public PluginOutput process(final PluginContext context,
            final InputStream input, OutputStream out,
            final Map<String, String> calloutParams);
 
    /**
     * This function will be called only if the isPayloadChangesRequired returns
     * false. Any custom properties or the header properties can be set at the
     * context level.
     *
     * @param context
     * @param input
     * @param out
     * @param calloutParams
     * @return
     */
    public PluginOutput process(final PluginContext context,
            final InputStream input, final Map<String, String> calloutParams);
}

3.8.2 PostCalloutPluginインタフェース

「例 - PostCalloutPluginインタフェース」は、com.oracle.callout.PostCalloutPluginインタフェースのJavaコードを示しています。

例 - PostCalloutPluginインタフェース

public interface PostCalloutPlugin {
 
    /**
     * Any custom properties or the header properties can be set at the
     * context level.
     *
     * @param context
     * @param input
     * @param out
     * @param calloutParams
     * @return
     */
    public PluginOutput process(final PluginContext context,
            final InputStream input, final Map<String, String> calloutParams);
}

3.8.3 コールアウト定義スキーマ

callout.xsdファイルでは、コールアウト定義XMLファイルの形式を定義します。「例 - コールアウト定義スキーマ」はコンテンツを表示します。

例 - コールアウト定義スキーマ

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://xmlns.oracle.com/mft"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:mft="http://xmlns.oracle.com/mft"
    elementFormDefault="qualified">
 
<xsd:element name="Callouts">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="Callout" minOccurs="0" maxOccurs="unbounded">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element minOccurs="0" maxOccurs="unbounded" ref="mft:Parameter"/>
                    </xsd:sequence>
                    <xsd:attribute name="name" use="required">
                        <xsd:simpleType>
                            <xsd:restriction base="mft:non-empty-string">
                                <xsd:maxLength value="128"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:attribute>
                    <!-- multiple values separated by comma are supported, possible values
                         Source-pre, Target-pre, Target-post -->
                    <xsd:attribute name="groupName" type="mft:non-empty-string" use="optional"/>
                    <xsd:attribute name="implementationClass" type="mft:non-empty-string"/>
                    <!-- jar name -->
                    <xsd:attribute name="libraryName" type="mft:non-empty-string"/>
                    <xsd:attribute name="timeout" type="xsd:integer" use="optional"
                               default="30"/>
                    <xsd:attribute name="description" type="mft:non-empty-string"/>
                    <xsd:attribute name="helpText" type="mft:non-empty-string"/>
                </xsd:complexType>
                <xsd:unique name="Callout_UK">
                    <xsd:selector xpath="mft:Callout"/>
                    <xsd:field xpath="@name"/>
                </xsd:unique>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>
        
<xsd:element name="Parameter">
    <xsd:complexType>
      <xsd:attribute name="name" type="mft:non-empty-string" use="required"/>
      <xsd:attribute name="parameterType" type="mft:parameterTypeLOV"
                 use="required"/>
      <xsd:attribute name="basic" type="boolean" use="optional" default="false"/>
      <xsd:attribute name="mandatory" type="boolean" use="optional"
                 default="false"/>
      <xsd:attribute name="hidden" type="boolean" use="optional" default="false"/>
      <!-- multiple values separated by comma is supported -->
      <xsd:attribute name="groupName" type="mft:non-empty-string"
                 use="optional"/>
      <!-- sub-groups can have multiple values separated by comma. -->
      <xsd:attribute name="sub-groups" type="mft:non-empty-string"
                 use="optional"/>
      <!-- VRule: defaultValue and parameterTypeLOV MUST match -->
      <xsd:attribute name="defaultValue" type="mft:non-empty-string"
                 use="optional"/>
      <xsd:attribute name="listValue" type="mft:non-empty-string"
                 use="optional"/>
      <xsd:attribute name="mapValue" type="mft:non-empty-string"
                 use="optional"/>
      <!-- changed refValue from IDREF to non-empty-string as IDREF does not allow ",". In the
      future refValue can have value separated by ",". Ex: "xPathaParams, someOtherParams" -->
      <xsd:attribute name="refValue" type="mft:non-empty-string" use="optional"/>
      <!--attribute name="tpOverrideable" type="boolean" use="optional" default="true"/-->
      <xsd:attribute name="overrideLevel" type="mft:overrideLevelLOV"
                 use="optional" default="all"/>
      <xsd:attribute name="displayName" type="mft:non-empty-string"/>
      <xsd:attribute name="description" type="mft:non-empty-string"/>
      <xsd:attribute name="helpText" type="mft:non-empty-string"/>
    </xsd:complexType>
  </xsd:element>
 
<xsd:simpleType name="overrideLevelLOV">
    <xsd:restriction base="string">
      <xsd:enumeration value="admin"/>
      <xsd:enumeration value="tp"/>
      <xsd:enumeration value="host"/>
      <xsd:enumeration value="tpa"/>
      <xsd:enumeration value="all"/>
    </xsd:restriction>
</xsd:simpleType>
 
<xsd:simpleType name="non-empty-string">
    <xsd:restriction base="string">
      <xsd:minLength value="1"/>
    </xsd:restriction>
</xsd:simpleType>
 
<xsd:simpleType name="parameterTypeLOV">
    <xsd:restriction base="string">
      <xsd:enumeration value="float"/>
      <xsd:enumeration value="integer"/>
      <xsd:enumeration value="string"/>
      <xsd:enumeration value="boolean"/>
      <xsd:enumeration value="date"/>
      <xsd:enumeration value="SO"/>
      <xsd:enumeration value="MO"/>
      <xsd:enumeration value="credential"/>
      <xsd:enumeration value="list"/>
      <xsd:enumeration value="map"/>
      <xsd:enumeration value="ref"/>
      <xsd:enumeration value="hex"/>
    </xsd:restriction>
</xsd:simpleType>
</xsd:schema>

3.8.4 PostDeliveryFailureCalloutPluginインタフェース

配信に失敗した場合は、ターゲット・ポスト・コールアウトが実行されます。例PostDeliveryFailureCalloutPluginインタフェースには、postErrorCalloutプラグイン・インタフェースのJavaコードが示されています。

例 - PostDeliveryFailureCalloutPluginインタフェース

package com.oracle.callout.sample;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;

import oracle.tip.mft.bean.SourceMessage;
import oracle.tip.mft.bean.TargetMessage;
import oracle.tip.mft.engine.processsor.plugin.PluginContext;
import oracle.tip.mft.engine.processsor.plugin.PostDeliveryFailureCalloutPlugin;
import oracle.tip.mft.notification.message.EmailMessage;
import oracle.tip.mft.system.MFTConstant.ArtifactType;
import oracle.tip.mft.system.MFTUtil;

public class FailedTransferNotification implements
		PostDeliveryFailureCalloutPlugin {

	private final String lineEnd =  System.getProperty("line.separator");
	
	@Override
	public void process(PluginContext context, InputStream input,
			Map calloutParams) throws Exception {

		File emailTemplateFile = new File(
				calloutParams.get("Email Template"));
		String toAddress = calloutParams.get("Email Address");
		
		TargetMessage tgtMessage = (TargetMessage) context.getMessage();
		tgtMessage.getFileName() ;
		SourceMessage srcMessage = tgtMessage.getInstance()
				.getTransferInstance().getSourceMessage();

		
		if (!emailTemplateFile.exists()) {
			throw new RuntimeException("Email template file doesn't exists");
		}
		
		
		FileReader reader = new FileReader(emailTemplateFile);
		BufferedReader bufferIn = new BufferedReader(reader);
		
		String fromAddress = null;

		String emailSubject = null;
		StringBuffer emailBody = new StringBuffer();
		String line = null;
		try {
			while ((line = bufferIn.readLine()) != null) {
				line = line.trim();
				if (line.length() == 0) {
					// ignore empty line
				} else {
					if (line.toUpperCase().startsWith("FROM")
							&& line.indexOf("=") != -1) {
						fromAddress = line.substring(line.indexOf("=") + 1)
								.trim();
						break;
					} else {
						throw new RuntimeException("From address not found");
					}

				}
			}


			while ((line = bufferIn.readLine()) != null) {
				line = line.trim();
				if (line.length() == 0) {
					// ignore empty line
				} else {
					if (line.toUpperCase().startsWith("SUBJECT")
							&& line.indexOf("=") != -1) {
						emailSubject = line.substring(line.indexOf("=") + 1)
								.trim();
						break;
					} else {
						throw new RuntimeException("Email subject not found");
					}

				}
			}
			boolean bodyElemFound = false;
			while ((line = bufferIn.readLine()) != null) {
				if (!bodyElemFound) {
					line = line.trim();
					if (line.length() == 0) {
						// ignore empty line
					}
					if (line.toUpperCase().startsWith("BODY")
							&& line.indexOf("=") != -1) {
						emailBody = emailBody.append(line.substring(line
								.indexOf("=") + 1));
						bodyElemFound = true;
					} else {
						throw new RuntimeException("Email body not found");
					}
				} else {
					emailBody.append(line);
					emailBody.append(lineEnd);
				}

			}

		} catch (Throwable e) {

			throw new RuntimeException(e);
		} finally {
			bufferIn.close();
			reader.close();
		}

		String emailBodyStr = emailBody.toString();

		String fileName = srcMessage.getFileName();
		if( fileName == null){
			fileName = " " ;
		}
		String userName = srcMessage.getSenderUserName();
		if( userName == null){
			userName = " " ;
		}
		

		
		String sourceName = srcMessage.getSourceName();
		double fileSizeInMB = srcMessage.getDataStorage().getPayloadSize() / 1048576.0;
		Calendar cal = Calendar.getInstance();
		DecimalFormat df = new DecimalFormat("#.####");
		String time = new SimpleDateFormat("dd MMM yyyy HH:mm:ss").format(cal.getTime());
		String transferUrl = MFTUtil.getInstance().getReportTrackingURL(
				ArtifactType.TRANSFER,
				tgtMessage.getInstance().getTransferInstance().getId(), null);
		// replace all place hoders
		emailSubject = emailSubject.replaceAll("%%FILENAME%%", fileName);
		String errorText = "";
		if( tgtMessage.getErrorInfo().getErrorTextClob() != null ){
			errorText = tgtMessage.getErrorInfo().getErrorTextClob().toString();
		}
		
		String errorDesc = "";
		if( tgtMessage.getErrorInfo().getErrorDescriptionClob() != null ){
			errorDesc = tgtMessage.getErrorInfo().getErrorDescriptionClob().toString();
		}
		
		emailBodyStr = emailBodyStr.replaceAll("%%FILENAME%%", fileName)
				.replaceAll("%%FILESIZE%%", df.format(fileSizeInMB)) 
				.replaceAll("%%USER%%", userName).replaceAll("%%DATE%%", time)
				.replaceAll("%%SOURCENAME%%", sourceName)
				.replaceAll("%%ERRORDESCRIPTION%%", errorDesc)
				.replaceAll("%%ERRORCODE%%", tgtMessage.getErrorInfo().getErrorCode())
				.replaceAll("%%ERRORTEXT%%", errorText )
				.replaceAll("%%TRANSFERURL%%", transferUrl);

		EmailMessage emailMessage = new EmailMessage();
		emailMessage.setFromEmailAddress(fromAddress);
		emailMessage.setReplyToEmailAddress(fromAddress);
		emailMessage.setReceiverEmailAddress(toAddress);
		emailMessage.setSubject(emailSubject);
		emailMessage.setMessageContent(emailBodyStr);
		emailMessage.setMimeType("text/html");
		context.sendEmailNotification(emailMessage) ;

	}

	public String convertWildcardToRegex(String express1) {
		String outstr = "";
		int strlen = express1.length();
		for (int ii = 0; ii < strlen; ii++) {
			char testch = express1.charAt(ii);
			if (testch == '.') {
				outstr = outstr + "\\.";
			} else if (testch == '*') {
				outstr = outstr + ".*";
			} else if (testch == '?') {
				outstr = outstr + ".";
			} else {
				outstr = outstr + testch;
			}
		}
		return outstr;
	}

}

3.9 カスタム・コールアウトを使用した検証

カスタム・コールアウト・アクションを検証できます。たとえば、チェックサムを検証するとき、プラグイン出力のコールアウトの実装に例外オブジェクトを設定することで検証できます。

検証用のコードは次のとおりです。
public PluginOutput process(PluginContext context, InputStream input,
Map<String, String> calloutParams) { 
PluginOutput res = new PluginOutput() ; 
boolean isValid = validateChecksum(context, input, calloutParams) ; 
if( ! isValid ){res.setException(new Exception("Checksum mismatch, corrupted payload.")) ; 

} 
return res ; 
}
前述の例のチェックサム・アクション・ステータスはインスタンス・レポート・ページで失敗します。メッセージ・ステータスは「失敗[前処理]」になります。