Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

ビジネス・オペレーションの定義

この章では、ビジネス・オペレーション・クラスの定義方法について説明します。この章は以下の節で構成されています。

Tip:

Ensemble では、特定の送信アダプタを使用する特殊なビジネス・オペレーション・クラスが提供されており、これらのクラスのいずれかがユーザのニーズに適合している可能性があります。そのため、プログラミングの必要がありません。部分リストは、"Ensemble の紹介" の “接続オプション” を参照してください。

概要

ビジネス・オペレーションは、Ensemble から外部のアプリケーションまたはシステムに要求を送信します。下の図は、そのしくみを示しています。

generated description: business operation

この図は、データの入力フローだけで、オプションの応答は含まれていないことに注意してください。

ビジネス・オペレーションは、以下のアクティビティを実行します。

  • ビジネス・サービスまたはビジネス・プロセスからの要求を待ちます。

  • メッセージ・マップを通して、ビジネス・オペレーション内の特定のメソッドに要求をディスパッチします。ビジネス・オペレーション・クラス内の各メソッドは、外部アプリケーション内の特定のアクションを表しています。

  • 要求オブジェクトを、関連する送信アダプタで使用できる形式に変換し、送信アダプタに対しては要求を外部アプリケーションに送信するように指示を出します。

  • 必要に応じて、応答オブジェクトを呼び出し側に返します。

各ビジネス・オペレーションには、受信した要求メッセージのタイプに応じて実行すべき外部オペレーションを指定するメッセージ・マップが 1 つずつ含まれています。このメッセージ・マップは 1 つ以上のエントリで構成されており、それぞれのエントリは関連する送信アダプタの 1 回の呼び出しに対応しています。

基本原理

初めに、“Ensemble のプログラミング” の章をお読みください。

規則では、ビジネス・オペレーションは、非常に具体的なオペレーションで、ロジックはほとんど含まれておらず、別のオペレーションを呼び出したり、何らかの形で分岐したりせずに要求を処理します。プロダクションの設計にロジックが必要な場合は、ビジネス・プロセスに組み込まれます。

多くのプロダクションがきわめて単純なビジネス・オペレーションの大規模なセットを提供しています。このような場合は、ビジネス・プロセスに、各オペレーションの呼び出し時期を決定するロジックが組み込まれています。

ビジネス・サービスの定義” の章の “基本原理” も参照してください。

ビジネス・オペレーション・クラスの定義

ビジネス・オペレーション・クラスを作成するには、次のようにクラスを定義します。

  • ビジネス・オペレーション・クラスは、Ens.BusinessOperationOpens in a new tab (またはサブクラス) を拡張する必要があります。

  • クラス内では、ADAPTER パラメータを、使用するビジネス・サービス用のアダプタ・クラスの名前と一致させる必要があります。

    または、関連する送信アダプタ・クラスなしでもビジネス・オペレーションを定義できます。この場合、ビジネス・オペレーション自体が、外部アプリケーションとの通信に必要なロジックを持つ必要があります。

  • クラス内では、INVOCATION パラメータで、使用する呼び出しスタイルを指定する必要があります。このスタイルは以下のいずれかにする必要があります。

    • Queue は、メッセージが 1 つのバックグラウンド・ジョブ内で作成され、元のジョブが解放された段階でキューに配置されることを意味します。その後、メッセージが処理された段階で、別のバックグラウンド・ジョブがそのタスクに割り当てられます。これは最も一般的な設定です。

    • InProc は、メッセージが、作成されたジョブと同じジョブで生成、送信、および配信されることを意味します。このジョブは、メッセージがターゲットに配信されるまで、送信者のプール内で再び使用可能になることはありません。これは特殊なケースのみに該当します。

  • クラスでは、少なくとも 1 つのエントリを含むメッセージ・マップを定義します。メッセージ・マップは、以下の構造を持つ XData ブロック・エントリです。

    XData MessageMap
    {
    <MapItems>
      <MapItem MessageType="messageclass">
        <Method>methodname</Method>
      </MapItem>
      ...
    </MapItems>
    }
    

    メッセージ・マップの定義” を参照してください。

  • クラスは、メッセージ・マップ内で指定されたすべてのメソッドを定義する必要があります。これらのメソッドは、メッセージ・ハンドラと呼ばれます。各メッセージ・ハンドラは、以下のシグニチャを持っている必要があります。

    Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status
    

    ここで、Sample はメソッド名、RequestClass は Ensemble 要求メッセージ・クラスの名前、ResponseClass は Ensemble 応答メッセージ・クラスの名前です。通常、これらのメソッドは、ビジネス・オペレーションの Adapter プロパティのプロパティおよびメソッドを参照します。詳細は、“メッセージ・ハンドラ・メソッドの定義” を参照してください。

  • クラスは設定を追加または削除できます。前述した “設定の追加と削除” を参照してください。

  • クラスは任意のまたはすべてのスタートアップ・メソッドおよびティアダウン・メソッドを実装できます。後述する “開始動作と停止動作の上書き” を参照してください。

    Ensemble は他の多くの異なるデバイスと通信する可能性のある統合プラットフォームであるため、プロパティ値は、サーバ・プラットフォーム、タイム・ゾーン、タイム・フォーマットなど、当てはまるおそれがあるローカリゼーションの問題に依存しません。このようなケースは、プロダクションの実装において処理することをお勧めします。プロパティ値に異なる初期設定を必要とするプロダクションの場合、ビジネス・オペレーションの OnInit() メソッドに値を設定します。後述する “開始動作と停止動作の上書き” を参照してください。

  • クラスにはその内部で作業を完了するためのメソッドを含めることができます。

以下の例は、必要となる一般的な構造を示しています。

Class MyProduction.NewOperation Extends Ens.BusinessOperation 
{
Parameter ADAPTER = "MyProduction.MyOutboundAdapter";

Parameter INVOCATION = "Queue";

Method SampleCall(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status
{
  Quit $$$ERROR($$$NotImplemented)
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="Ens.Request">
    <Method>SampleCall</Method>
  </MapItem>
</MapItems>
}
}
Note:

スタジオには、上記のようなビジネス・オペレーション・スタブの作成に使用できるウィザードが用意されています。このウィザードにアクセスするには、[ファイル][新規作成] をクリックし、[プロダクション] タブをクリックします。 次に [ビジネス・オペレーション] をクリックして [OK] をクリックします。

ビジネス・オペレーション・クラスの例は、"アダプタ・ガイド" を参照してください。

メッセージ・マップの定義

メッセージ・マップは XML ドキュメントであり、ビジネス・オペレーション・ホスト・クラスの XData MessageMap ブロック内に含まれています。以下に例を示します。

Class MyProduction.Operation Extends Ens.BusinessOperation
{

XData MessageMap
{
<MapItems>
  <MapItem MessageType="MyProduction.MyRequest">
    <Method>MethodA</Method>
  </MapItem>
  <MapItem MessageType="Ens.StringRequest">
    <Method>MethodB</Method>
  </MapItem>
</MapItems>
}

}

メッセージ・マップのオペレーションは単純です。ビジネス・オペレーションは、受信要求を受け取ると、受信メッセージのタイプと一致する MessageType 属性を持つ最初の MapItem が見つかるまで、メッセージ・マップの先頭から各 MapItem を検索します。次に、この MapItem に関連のあるオペレーション・メソッドを呼び出します。

メッセージ・マップについて注意する点は以下のとおりです。

  • メッセージ・マップは先頭から最後にかけて検索されます。一致する項目が検出されたら、それ以上の検索は行われません。

  • 受信要求オブジェクトが所定の MessageTypeサブクラスである場合は、一致対象と見なされます。サブクラスを除外する場合は、サブクラスをメッセージ・マップ内でスーパー・クラスの上に配置する必要があります。

  • 受信要求がどの MapItem エントリとも一致しない場合は、Ensemble のイベント・ログにエラーが書き込まれ、要求は無視されます。

メッセージ・ハンドラ・メソッドの定義

ビジネス・オペレーション・クラスを作成するときの最大のタスクは、このアダプタで使用するためのメッセージ・ハンドラ、つまり、Ensemble メッセージを受け取ってから、プロダクションの外部のターゲットと通信するためのアダプタのメソッドを呼び出すメソッドの作成です。

各メッセージ・ハンドラ・メソッドは、以下のシグニチャを持っている必要があります。

Method Sample(pReq As RequestClass, Output pResp As ResponseClass) As %Status

ここで、Sample はメソッド名、RequestClass は Ensemble 要求メッセージ・クラスの名前、ResponseClass は Ensemble 応答メッセージ・クラスの名前です。

一般的には、メソッドで以下の一部または全部を実行する必要があります。

  1. オプションで、ビジネス・オペレーション・クラスのプロパティを設定します (適時)。“ビジネス・オペレーションのプロパティ” を参照してください。

  2. 入力オブジェクトを検査します。

  3. 応答クラスのインスタンスを作成します。

  4. アダプタの該当するメソッドを呼び出します (複数可)。これらのメソッドは、ビジネス・オペレーションの Adapter プロパティ経由で利用できます。以下に例を示します。

        Set tSc=..Adapter.SendMail(email,.pf)
    
    

    このメソッドについては、後で説明します。

    または、プロダクション内のターゲットにメッセージを送信する場合は、“プロダクション内のターゲットに対する要求の送信” を参照してください。

  5. 応答を調べます。

  6. 応答内の情報を使用して、Ensemble 応答メッセージ (Ens.ResponseOpens in a new tab またはサブクラスのインスタンス) を作成します。メソッドは出力としてこのメッセージを返します。

    メッセージ・クラスの定義方法は、“Ensemble メッセージの定義” の章を参照してください。

  7. 必ず出力引数 (pOutput) を設定します。通常、応答メッセージと同じように設定します。この手順は必須です。

  8. 適切なステータスを返します。この手順は必須です。

ビジネス・オペレーションのプロパティ

オペレーションのメソッド内では、以下のようなビジネス・オペレーション・クラスのプロパティが使用できます。

プロパティ 説明
%ConfigName このビジネス・オペレーションの構成名。
%SessionId 現在処理されているメッセージのセッション ID。
Adapter このビジネス・オペレーションに関連のある送信アダプタ。
DeferResponse このビジネス・オペレーションからの応答を延期して後で送信するには、DeferResponse プロパティを整数値の 1 (真) に設定し、ビジネス・オペレーションを終了する前に、延期された応答配信トークンを取得します。
FailureTimeout 再試行を実行できる時間 (秒)。この時間を経過すると、再試行は不可能になり、エラー・コードが返されます。"Retry" および "RetryInterval" を参照してください。
Retry 現在のメッセージを再試行する場合は、このプロパティを整数値の 1 (真) に設定します。通常、再試行機能は、外部アプリケーションから応答がなく、エラーを生成せずに再試行を行う場合に使用されます。"RetryInterval" および "FailureTimeout" を参照してください。
RetryInterval このメッセージが再試行を行うようにマーキングされている場合に、出力システムに再試行アクセスを行う頻度 (秒単位)。"Retry" および "FailureTimeout" を参照してください。
SuspendMessage ビジネス・オペレーションで現在処理中のメッセージを保留状態としてマーキングする場合は、このプロパティを整数値の 1 (真) に設定します。“保留中のメッセージ” の節を参照してください。

プロダクション内のターゲットに対する要求の送信

ビジネス・オペレーションは、主に、特定の外部アプリケーションへの要求の配信を担当しますが、必要に応じて、他のビジネス・オペレーションまたはビジネス・プロセスにメッセージを送信することもできます。プロダクション内のターゲットにメッセージを送信するには、SendRequestSync()SendRequestAsync()、または SendDeferredResponse() を呼び出します。

これらのメソッドの詳細は、“ビジネス・サービスの定義” の章の “要求メッセージの送信” を参照してください。

Ens.BusinessOperationOpens in a new tab は、DeferResponse() を使用可能な追加のメソッドを定義します。

DeferResponse() メソッド

このメソッドは、成功または失敗を示す %StatusOpens in a new tab 値を返します。これにより、1 つの参照渡しの引数、token が提供され、この引数は後で SendDeferredResponse() を呼び出すために必要な延期された応答配信トークンを返します。以下に例を示します。

   Set sc=..DeferResponse(.token)
   // Send the token out somewhere...
   Quit $$$O

遅延送信の概要は、“Ensemble のプログラミング” の章の “遅延送信の使用法” を参照してください。

保留中のメッセージ

ビジネス・オペレーションで現在処理中のメッセージを一時停止ステータスとしてマーキングする場合は、ビジネス・オペレーション・プロパティの SuspendMessage を整数値の 1 (真) に設定します。通常、ビジネス・オペレーションでは、何らかの理由で外部システムから拒否されたメッセージに対して保留状態に設定します。

一時停止メッセージは特殊なキューに入れられるため、システム管理者は問題を診断して解決してからメッセージを再送できます。また、システム管理者は、単純な再送 (元のターゲット宛て) を実行することも、新しい宛先に送信することもできます。詳細は、"Ensemble の監視" を参照してください。

以下のサンプル・メソッドは、ビジネス・オペレーションからドキュメントを外部システムに送信します。送信直前のドキュメントを検証する Validate() の呼び出しからエラーが返されると、このメソッドは SuspendMessage プロパティを 1 に設定します。

Method validateAndIndex(pDoc As MyX12.Document) As %Status
{
  If ""=..Validation||'$method($this,"OnValidate",pDoc,..Validation,.tSC) {
    Set tSC=##class(MyX12.Validator).Validate(pDoc,..Validation)
  }
  Set:'$D(tSC) tSC=$$$OK
  If $$$ISERR(tSC) {
    Set ..SuspendMessage=1
    Do ..SendAlert(##class(Ens.AlertRequest).%New($LB(
        ..%ConfigName,"Suspended document "_pDoc.%Id()_
        " because it failed validation using spec '"
        _..Validation_"' with error "_
        $$$StatusDisplayString(tSC))))
    Quit tSC
  }
  If ""'=..SearchTableClass {
    TRY {
      Set tSCStore=$classmethod(..SearchTableClass,"IndexDoc",pDoc)
      If $$$ISERR(tSCStore)
        $$$LOGWARNING("Failed to create SearchTable entries")
    }
    CATCH errobj {
      $$$LOGWARNING("Failed to invoke SearchTable class")
     }
  }
  Quit $$$OK
}
FeedbackOpens in a new tab