第4章 サービスの構築と使用

4.1. Listener、Notifier/Router、および Action

4.1.1. Listener

リスナー は ESB 認識のメッセージ受信用エンドポイントをカプセル化します。メッセージの受信で、listenerreplyTo エンドポイントにその結果をルーティングする前にメッセージを処理するメッセージプロセッサーの「パイプライン」にメッセージをフィードします。pipeline 内で行われるアクション処理はいくつかのステップで構成されることがあります。ここでは、特定のプロセッサーにメッセージが変換され、何らかのビジネスロジックが次のプロセッサーで適用されてから、その結果が pipeline 内の次のステップまたは別のエンドポイントにルーティングされます。

注記

リスナーに対して様々なパラメーターを設定できます。例としては、有効なワーカースレッドの数などです。これらのオプションの種類については、"Configuration" のセクションを参照してください。

4.1.2. Router

ルーターを使用して、メッセージやペイロードをエンドポイントに転送します。router によっては、unwrap プロパティに対応するものもあります。このプロパティを true に設定すると、自動的にメッセージペイロードを抽出して、次の ESB 未対応のエンドポイントに送信します。このオプションを false に設定すると、ペイロードを抽出せずに、ESB メッセージをすべて渡します (後者の場合、受け取り側のエンドポイントは ESB 対応であるため、メッセージの処理が可能です)。
action pipeline は、設定内で待機しているアクションがあったとしても、router 操作が実行されると、メッセージを処理しなくなります。このような種類の分割が必要な場合は、StaticWiretap アクションを使用します。
StaticWiretapStaticRouter などのツールは、他のサービスへのルーティングにのみ使用することができます。メッセージコンテンツをベースにしたアクションで、動的にルーティングができるプログラムもあります。コンテンツベースルーターの詳細については、サービスガイドの「コンテンツベースルーティングとは」の章を参照してください。

注記

様々な種類のルーターの使用については、「事前定義済みアクション」の章の「ルーター」の項目を参照してください。

4.1.3. Notifier

成功またはエラーの情報を ESB 認識しないエンドポイントに伝播させることができる方法が notifiers になります。ESB 認識のエンドポイントとの通信には notifiers を使用しないでください。ESB 認識のエンドポイントと ESB を認識しないエンドポイントに同じチャンネルでのリッスンを行わせることはできません。ESB 認識のエンドポイントと通信する場合はアクション内で couriersServiceInvoker を使用することを考慮してください。
ESB 認識のトランスポートがすべて notifiers に対してサポートされているわけではありません (また、その逆も同様)。notifiers は意図的に非常にシンプルになっています。byte[] または String のいずれか 1 つのみをトランスポートすることができます (ペイロードで toString() を呼び出すことにより取得)。
上記に概説したように、listener の役割とはメッセージ配信のエンドポイントとして動作し action pipeline にメッセージを配信することになります。 各 listener の設定は次に記す情報を提供する必要があります。
  • registry (service-categoryservice-nameservice-description、および EPR-description タグ名)。オプションの remove-old-service タグ名を true に設定すると、Enterprise Service Bus はこの新しいインスタンスを追加する前に registry から既存のすべてのサービスエントリを削除します。ただし、すべての エンドポイント参照 (EPR) を含むサービス全体が削除されるため注意してください。
  • listener クラスのインスタンス化 (listenerClass タグ名を参照)
  • listener が処理するエンドポイント参照 (EPR)。これはトランスポート固有となります。次の例は Java Message Service のエンドポイント参照 (JMS EPR) に該当します (connection-factorydestination-typedestination-namejndi-typejndi-URLmessage-selector のタグ名を参照)。
  • action pipeline。1 つ以上の <action> 要素を必要とし、それぞれが少なくとも class のタグ名を含んでいる必要があり、これが chain 内のそのリンクに対して、インスタンス作成する action クラスを確定します。
<?xml version = "1.0" encoding = "UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd" parameterReloadSecs="5">

<providers>
  <jms-provider name="JBossMQ" 
    connection-factory="ConnectionFactory"
    jndi-URL="jnp://127.0.0.1:1099" 
    jndi-context-factory="org.jnp.interfaces.NamingContextFactory"
    jndi-pkg-prefix="org.jboss.naming:org.jnp.interfaces">
    <jms-bus busid="quickstartGwChannel">
      <jms-message-filter dest-type="QUEUE" 
        dest-name="queue/quickstart_helloworld_Request_gw"/>
    </jms-bus>
    <jms-bus busid="quickstartEsbChannel">
      <jms-message-filter dest-type="QUEUE"
        dest-name="queue/quickstart_helloworld_Request_esb"/>
    </jms-bus>
  </jms-provider>
</providers>
      
<services>
  <service category="FirstServiceESB" 
    name="SimpleListener" description="Hello World">
    <listeners>
      <jms-listener name="JMS-Gateway" 
        busidref="quickstartGwChannel" maxThreads="1"
        is-gateway="true"/>
      <jms-listener name="helloWorld"
        busidref="quickstartEsbChannel" maxThreads="1"/>
    </listeners>

    <actions>
      <action name="action1" class="org.jboss.soa.esb.samples.
quickstart.helloworld.MyJMSListenerAction"
        process="displayMessage" />
      <action name="notificationAction" 
        class="org.jboss.soa.esb.actions.Notifier">
        <property name="okMethod" value="notifyOK" />
        <property name="notification-details"> 
          <NotificationList type="ok">
            <target class="NotifyConsole"/>
          </NotificationList>
          <NotificationList type="err">
            <target class="NotifyConsole"/>
          </NotificationList>
        </property>

     </action>    
   </actions>  
  </service>  
 </services>
</jbossesb>

この設定例では javax.jms.ObjectMessage 内でシリアライズされる受信 ESB メッセージを待機している listener オブジェクト (jms-listener 属性) のインスタンスを作成し、それぞれの受信メッセージを 2 つのステップから成る (<action> エレメント) action pipeline に配信します。
  1. action1: MyJMSListenerAction (普通のサンプルが続く)
  2. notificationAction: org.jboss.soa.esb.actions.SystemPrintln クラス
この action クラスは XML アクション設定をデバッグする際に便利であることがわかります。
public class MyJMSListenerAction 
	{
	    ConfigTree _config;
	    public MyJMSListenerAction(ConfigTree config) { _config = config; }

	    public Message process (Message message) throws Exception
	    {
	    	System.out.println(message.getBody().get());
	    	return message;
	    }
	}
action クラスを仕様して、ニーズに合わせてフレームワークをカスタマイズします。ActionProcessingPipeline クラスは少なくとも次を提供するために他のアクションクラスを必要とします。
  • ConfigTree タイプの引数を 1 つとるパブリックコンストラクター
  • message 引数をとり、メッセージを返す 1 つまたは複数のパブリックメソッド
オプションのコールバックメソッドを使用して action pipeline の各ステップの結果を通知します (以下のアイテム 5 と 6 を参照)。
org.jboss.soa.esb.listeners.message.ActionProcessingPipeline クラスは <action> エレメントを使って設定されるすべてのステップに対して次のステップを実行します。
  1. class 属性で指定されるクラスのオブジェクトをインスタンス化します。これには、ConfigTree タイプの引数を 1 つとるコンストラクターを必要とします。
  2. process 属性のコンテンツを分析します。
    コンテンツはインスタンス作成されるクラスのパブリックメソッド名をコンマで区切った一覧になり (ステップ 1)、それぞれ Message タイプの単一引数をとらなければならず、結果、pipeline 内で次のステップに渡される messagem オブジェクトを返します。
    process 属性がない場合、pipelineprocess と呼ばれる単一の処理メソッドを使用するとみなされます。
    連続的に複数の <action> エレメントを使用するのに比べ、単一の <action> エレメントで複数のメソッド名一覧を使用する方が利点があります。action クラスが一度インスタンス作成されると、複数のメソッドはそのクラスの同じインスタンスで呼び出されるからです。これによりオーバーヘッドを低減し、インスタンスオブジェクト内にステータス情報を保持することができます。
    ユーザー提供の (新しい) action クラスに対して便利な方法になりますが、 他の代替方法 (<action> エレメントの一覧) も変わらず他の既存 action クラスを再利用できる方法となります。
  3. 前のステップで返されるメッセージを使って一覧内の各メソッドを連続して呼び出します。
いずれかのステップで返される値が null の場合、pipeline は処理を直ちに停止します。
各 <action> 要素で成功するコールバックメソッドは以下のとおりです。
  • process 属性のメソッド一覧が正常に実行された場合、pipelineokMethod 属性のコンテンツを分析します。
  • メソッドが指定されていない場合、処理が次の <action> エレメントに継続されます。
  • メソッドが okMethod 属性内にある場合、ステップ3の最後のメソッドにより返されたメソッドを使用して呼び出します。パイプラインが正常に完了すると、okMethod 通知が最後ものから最初のものへ全ハンドラーに対して呼び出されます。
各 <アクション> エレメント内の失敗に対するコールバックメソッドは以下のとおりです。
  • 例外が発生すると exceptionMethod 通知が現在の (失敗している) ハンドラーから最初のハンドラーまですべてのハンドラー上で呼び出されます (現在のところ、exceptionMethod の指定がないと、得られる出力はログ記録のエラーのみになります)。
  • ActionProcessingFaultException がプロセスメソッドから送出されると次のセクションで定義されるルールに従ってエラーメッセージが返されます。エラーメッセージの内容は例外の getFaultMessage から返されるもの、またはオリジナルの例外内の情報を含むデフォルトの Fault のいずれかになります。
固有のニーズにあわせて ESB の動作を調整するためユーザーによって供給される action クラスは追加でランタイムの設定が必要な場合があります (例: 上記の XML 内の notifier クラスは <NotificationList> 子エレメントを必要とする)。各 <action> エレメントは上述の属性を利用してこれ以外の属性やオプションの子エレメントをすべて無視します。しかし、これらは必要となる ConfigTree 引数内の action クラスコンストラクターに渡されます。各アクションクラスはその該当する <action> エレメントでインスタンス作成されるので、「兄弟となる」 action エレメントを表示しません (表示してはいけない)。

注記

<action> ターゲット内の NotificationList エレメントを囲むために使用されるプロパティの名前は検証されません。

4.1.4. 注釈付きのアクションクラス

JBoss Enterprise Service Bus には、クリーンな action 実装をより簡単に作成するアクションアノテーションがあります。これにより、インターフェース、抽象クラスの実装や ConfigTree タイプの処理に関する複雑性が表面化しなくなります (jboss-esb.xml ファイル内の設定情報)。
以下がそのアノテーションです。
  • @Process
  • @ConfigProperty
  • @Initialize
  • @Destroy
  • @BodyParam
  • @PropertyParam
  • @AttachmentParam
  • @OnSuccess
  • @OnException

4.1.4.1. @Process

最も簡単な実装は、@Process のアノテーション付きの単一メソッドと基本的なplain old Java object (POJO) でアクションを作成します。
public class MyLogAction {

                @Process
 		    public void log(Message message) {
		        // log the message...
		    }
		}
@Process アノテーションは、有効な ESB action としてクラスを特定します。クラス内に複数のメソッドがある場合、メッセージインスタンスを処理するのに使用するメソッドを特定します (または、メッセージの一部。これについては、@BodyParam、@PropertyParam and @AttachmentParam アノテーションの説明時に詳しくみていきます)。
この action インスタンスを pipeline に設定するには、ロー/ベースレベルの action 実装と同じプロセスを使用します (AbstractActionPipelineProcessor を継承する、または ActionLifecycle を実装するもの、あるいはその他のサブタイプや抽象実装):
<service .....>
		    <actions>
		        <action name="logger" class="com.acme.actions.MyLogAction" />
		    </actions>
		</service>
@Process のアノテーションがついた複数のメソッドに action 実装が関連付けられている場合、process 属性を使用して、メッセージインスタンスの処理に使用するものはどれか指定します。
<service .....>
		    <actions>
		        <action name="logger" class="com.acme.actions.MyLogAction" 
                                           process="log" />
		    </actions>
		</service>

4.1.4.2. @Process メソッドの戻り値

以下を返すように @Process メソッドを実装することができます。
  • void: これは、上記の Logger アクション実装にあるように、戻り値がないという意味です。
  • message: これは ESB メッセージインスタンスです。action pipeline 上でアクティブな/現在のインスタンスになります。
  • その他のタイプ。メソッドが ESB メッセージインスタンスを返さない場合、返されたオブジェクトインスタンスは、action pipeline にある現在の ESB メッセージインスタンスに設定されます。メッセージがどこに設定されるかは、set-payload-location <action> 設定プロパティにより変わります。これは、通常の MessagePayloadProxy ルールに従いデフォルト設定します。

4.1.4.3. @Process メソッドパラメーター

@Process メソッドを使用して、様々な方法でパラメーターを指定します。
  1. メソッドパラメーターとして ESB メッセージインスタンスを指定
  2. 任意のパラメータータイプを 1 つ以上指定。Enterprise Service Bus フレームワークは、アクティブ/現在のパイプラインメッセージインスタンス内でそのタイプのデータを検索します。まず、メッセージボディ、次にプロパティ、最後に添付を検索し、そのパラメーターの値としてこのデータを渡します (該当するものが見つからない場合は null)。
最初のオプションに関する例は、Logger アクションの上記の例に記述されています。2 つ目のオプションの例を以下に示しています。
public class OrderPersister {

		    @Process
		    public OrderAck storeOrder(OrderHeader orderHeader,
								OrderItems orderItems) {
		        // process the order parameters and return an ack...
		    }
		}
この例では、@Process メソッドは、OrderHeaderOrderItem オブジェクトインスタンスの作成や、現在のメッセージへの添付について pipeline の 1 つ前のアクションに左右されます (より現実的な実装では、XML または EDI ペイロードを注文インスタンスにデコーディングする一般的なアクション実装を持ちます。OrderPersister は、単独のパラメーターとして注文インスタンスを取ります)。以下に例を示します。
public class OrderDecoder {

		    @Process
		    public Order decodeOrder(String orderXML) {
		        // decode the order XML to an ORder instance... 
		    }
		}

		public class OrderPersister {

		    @Process
		    public OrderAck storeOrder(Order order) {
		        // persist the order and return an ack...
		    }
		}

サービス設定で 2 つのアクションをつなぎます。
<actions>
    <action name="decode" class="com.acme.orders.OrderDecoder" />
    <action name="persist" class="com.acme.orders.OrderPersister" />
</actions>

アノテーションが少ないため、オプション 2 のほうが読み込みが簡単ですが、実行時に適切なパラメーターをメッセージ内から検索する処理が決定的でないため、リスクがあります。このため、Red Hat は@BodyParam、@PropertyParam、@AttachmentParam アノテーションをサポートします。
これらの @Process メソッドパラメーターのアノテーションを使用して、明示的にメッセージ内のどこから @Process メソッドの個別のパラメーター値がリトリーブされているか定義します。名前の通り、これらのアノテーションはそれぞれ、パラメーターごとに名前付きのロケーションを指定することができます。
public class OrderPersister {

  		    @Process
		    public OrderAck storeOrder(
		                   @BodyParam("order-header") OrderHeader orderHeader,
		                   @BodyParam("order-items") OrderItems orderItems) {
			
		        // process the order parameters and return an ack...
		    }
		}
指定のメッセージロケーションに値が含まれていない場合、このパラメーターについて null が渡されます (@Process メソッドインスタンスはこの処理方法を決定)。反対に指定のロケーションに誤ったタイプの値が含まれている場合、MessageDeliverException がスローされます。

4.1.4.4. @ConfigProperty

アクションは、カスタム設定がある程度必要になるものがほとんどです。ESB アクション設定では、プロパティは <action> 要素の <property> サブ要素として提供されます。
<action name="logger" class="com.acme.actions.MyLogAction">
    <property name="logFile" value="logs/my-log.log" />
    <property name="logLevel" value="DEBUG" />
</action>
これらのプロパティを活用するため、低/基本レベルのアクション実装を使用する必要があります (AbstractActionPipelineProcessor の継承または、ActionLifecycle の実装)。これは、ConfigTree クラスと連携します (コンストラクター経由でアクションに提供します) 。アクションを実装するには、以下の手順に従います。
  1. ConfigTree インスタンスを提供するアクションクラスへコンストラクターを定義します。
  2. ConfigTree インスタンスから該当のアクション設定プロパティをすべて取得します。
  3. 必須のアクションプロパティを確認して、<action> 設定に指定されていない場所で例外をあげます。
  4. プロパティの全値を文字列 (ConfigTree で提供) から、アクション実装で使用される適切なタイプにデコーディングします。例えば、java.lang.String から java.io.File に、java.lang.String から Boolean に、java.lang.String から long などにデコーディングします。
  5. 設定値が対象のプロパティタイプにデコーディングできない場所では、例外が出されます。
  6. 考えられる各種設定すべてに単体テストを実装して、さきほど表示したタスクが正しく完了するようにします。
上記のタスクは一般的に実行するのは難しくありませんが、作業が増え、エラーが発生しやすく、アクションごとに設定の間違いを処理する方法も異なってきます。結果として、比較すると全体的に明確さが欠けますが、多くのコードを追加する必要がある場合もあります。
アノテーション付きのアクションは、@ConfigProperty を使用してこのような問題に対処します。2 種の必須設定プロパティ (logFile and logLevel) を持つ、MyLogActions 実装を拡張します。
public class MyLogAction {

		    @ConfigProperty
		    private File logFile;

		    @ConfigProperty
		    private LogLevel logLevel;
 
		    public static enum LogLevel {
		        DEBUG, 
		        INFO, 
		        WARN
		    }

		    @Process
		    public void log(Message message) {
		        // log the message at the configured log level...
		    }
		}

注記

(フィールドではなく) "setter" メソッド上で @ConfigProperty アノテーションを定義することも可能です。
必要事項は以上です。Enterprise Service Bus がアクションをデプロイすると、デコーディングされた値にある実装とマップの両方を検証します (enum のサポートと上記の LogLevel enum)。 @ConfigProperty アノテーションを処理するアクションフィールドを検索します。開発者は、ConfigTree クラスを処理したり、余分のコードを開発したりする必要がありません。
デフォルトでは、@ConfigProperty アノテーションを処理するクラスフィールドはすべて必須です。必須ではないフィールドは、以下の 2 種のいずれかの方法で処理されます。
  1. フィールドの @ConfigProperty アノテーションで use = Use.OPTIONAL を指定
  2. フィールドの @ConfigProperty アノテーションで defaultVal を指定 (任意)
ログアクションのプロパティをオプションのみにするには、以下のようなアクションを実装します。
public class MyLogAction {
		
		    @ConfigProperty(defaultVal = "logs/my-log.log")
		    private File logFile;

		    @ConfigProperty(use = Use.OPTIONAL)
		    private LogLevel logLevel;

		    public static enum LogLevel {
		        DEBUG, 
		        INFO, 
		        WARN
		    }

		    @Process
		    public void log(Message message) {
		        // log the message...
		    }
		}
@ConfigProperty アノテーションは、2 つの追加フィールドをサポートします。
  1. name: これを使用して、アクションインスタンスで指定の名前のフィールドを生成する際に使用するアクション設定プロパティ名を明示的に指定します。
  2. choice: このフィールドを使用して、許容の設定値を制限します。これは、列挙型を使用することで可能です (LogLevel)
この名前フィールドは、古いアクション (低/基本レベルの実装タイプを使用) を新しいアノテーションベースの実装に以降する際などに使用できます。プロパティの古い設定名 (後方互換との関係で変更不可) は有効な Java フィールド名へのマッピングは行いません。ログアクションを例にとります。以下がログアクションの古いアクションだと仮定します。
<action ...>
		    <property name="log-file" value="logs/my-log.log" />
		    <property name="log-level" value="DEBUG" />
		</action>
ここのプロパティ名は、有効な Java フィールド名にマッピングを行わないため、@ConfigProperty アノテーションで名前を指定します。
public class MyLogAction {
		
		    @ConfigProperty(name = "log-file")
		    private File logFile;

		    @ConfigProperty(name = "log-level")
		    private LogLevel logLevel;

		    public static enum LogLevel {
		        DEBUG, 
		        INFO, 
		        WARN
		    }

		    @Process
		    public void log(Message message) {
		        // log the message...
		    }
		}

4.1.4.5. プロパティの値のデコード

Bean 設定のプロパティ値は、文字列の値からデコーディングされます。適切な POJO bean プロパティタイプと一致させるには、以下のシンプルなルールを使用します。
  1. プロパティタイプに単一引数の文字列コンストラクターがある場合、これを使用します。
  2. Primitive な場合、オブジェクトタイプの単一引数文字列コンストラクターを使用します。例えば、int の場合、整数のオブジェクトを使用します。
  3. 列挙型の場合 Enum.valueOf を使用して設定の文字列を列挙型の値に変換します。

4.1.4.6. @Initialize と @Destroy

ときに、アクション実装はデプロイメント時に初期化タスクを実行する必要があります。また、アンデプロイ時にはクリーンアップも行う必要があります。このような理由から、@Initialize および @Destroy メソッドアノテーションがあります。
これについて例を挙げます。デプロイメント時に、ロギングアクションはチェックをいくつか行います (例えばファイルやディレクトリが存在するかなど)。アンデプロイされると、アクションはクリーンアップタスクを実行する必要があります (ファイルを閉じるなど)。以下がこれらのタスクを実行するためのコードです。
public class MyLogAction {

		    @ConfigProperty
		    private File logFile;

		    @ConfigProperty
		    private LogLevel logLevel;

		    public static enum LogLevel {
		        DEBUG, 
		        INFO, 
		        WARN
		    }

		    @Initialize
		    public void initializeLogger() {
			// Check if file already exists… check if parent folder 
			// exists etc...
			// Open the file for writing...
		    }
 
		    @Destroy
		    public void cleanupLogger() {
		        // Close the file...
		    }

		    @Process
		    public void log(Message message) {
		        // log the message...
		    }
		}

注記

@ConfigProperty アノテーションはすべて、ESB デプロイヤーが @Initialize メソッドを呼び出す前に処理されます。そのため、@Initialize メソッドは、カスタマイズの初期化を行う前に準備が整ったこれらのフィールドに依存します。

注記

これらのアノテーションを両方使用して、メソッドを指定する必要はありません。必要がある場合のみ指定します。つまり、メソッドが初期化のみ必要な場合、@Initialize アノテーションのみを使用します (@Destroy アノテーションで注釈をつけた matching メソッドを提供する必要はありません)。

注記

単一のメソッドを指定して、@Initialize と @Destroy 両方でアノテーションをつけることができます。

注記

@Initialize メソッドに ConfigTree パラメーターをオプションで指定可能です。これを行うと ConfigTree インスタンスを基本とするアクションにアクセスできるようになります。

4.1.4.7. @OnSuccess と @OnException

アクションが設定されている pipeline の中で、実行が成功した際、または失敗した際にこれらのメソッドを実行すべきか指定するため、これらのアノテーションを使用します。
public class OrderPersister {

		    @Process
		    public OrderAck storeOrder(Order order) {
		        // persist the order and return an ack...
		    }

		    @OnSuccess
		    public void logOrderPersisted(Message message) {
		        // log it...
		    }

		    @OnException
		    public void manualRollback(Message message, 
                                           Throwable theError) {
		        // manually rollback...
		    }
		}
これらのアノテーションの場合、パラメーターはパラメーターに渡すかはオプションです。上記のパラメーターの一部、すべてを提供、何も提供しないといった選択ができます。Enterprise Service Bus フレームワークは、それぞれの場合で該当のパラメーターを解決します。

4.1.5. アクションとメッセージ

Action は Message が到着することで起動されます。特定の Action 実装は Message 内のどこにデータが存在しているか認識している必要があります。サービスは Action の任意の番号を使って実装される場合があるため、単一入力の Message が複数の Action の代表として情報を含んでいる可能性があります。このような場合、Message Body 内にそのデータ用の固有の場所を 1 つまたは複数選択してサービスを使用する側に対してこれを伝えるのは Action 開発者の義務となります。

注記

さらに、Action 同士はチェーン化される場合があるため、チェーンの始めの方の Action にオリジナル入力の Message を修正させるまたは完全に置き換えさせることが可能です。

重要

セキュリティ上、サービスチェーン内で未知の Action を使用する場合は注意が必要です。情報の暗号化を推奨します。

重要

複数のアクションが入力メッセージのデータを共有、変更する場合、チェーンを介して情報が流れるため、オリジナルの情報を保持するよう Red Hat は推奨しています。チェーンの先のほうに進んでも最初の情報にアクセスできるようにするためです (これができない状況もあります)。
入力されたデータを変更するアクションは、org.jboss.soa.esb.actions.post のボディの場所に追加することもできます。つまり、チェーン内に N 個のアクションがある場合、N 番目のアクションは、通常検索する箇所でオリジナルデータを検索します。また、N-1 番目のアクションがデータを変更した場合、N は他の指定の場所で検索を行います。アクションチェーンをスムーズじ実行するには、N 番目のアクションが org.jboss.soa.esb.actions.pre をチェックして、N-2 番目のアクションがデータを変更していないか確認します。

警告

デフォルトのボディロケーションを使用するアクションをチェーン化する場合はコンフリクトが起こらないように注意が必要です。

4.1.6. レスポンスの処理

JBoss Enterprise Service Bus は、action pipeline レスポンスの処理を目的とする2種類の処理メカニズムに対応しています。このメカニズムは、明示的および暗黙的処理メカニズムとよばれ、後者はアクションのレスポンスをベースとしています。
暗黙的メカニズムを使用した場合、レスポンスは次のように処理されます。
  • pipeline 内のアクションが null メッセージを返す場合、レスポンスは送信されません。
  • pipeline 内の最後のアクションがエラー以外の応答を返した場合、要求メッセージの ReplyTo EPR に返信が送信されます。これが設定されていない場合は、要求メッセージの From EPR に送信されます。応答をルーティングできない事態が発生すると、エラーメッセージがシステムによりログ記録されます。
明示的なメカニズムを使用した場合、レスポンスは次のように処理されます。
  • pipelineOneWay で指定されている場合、レスポンスは送信されません。
  • pipelineRequestResponse で指定されている場合、要求メッセージの ReplyTo EPR に返信が送信されます。これが設定されていない場合は、要求メッセージの From EPR に送信されます。EPR に指定がない場合、システムによるエラーメッセージはログ記録されません。

重要

すべてのアクションパイプラインに明示的な処理のメカニズムを使用させることを推奨します。mep 属性を jboss-esb.xml ファイル内の actions エレメントに追加するだけでこれを行えます。この属性の値は OneWay または RequestResponse のいずれかにします。

4.1.7. アクション処理中のエラーの扱い方

アクションチェーンを処理しているあいだにエラーが発生する可能性があります。このようなエラーは pipeline から例外として送出され、これによりパイプラインの処理を終了させるはずです。前述のように、失敗メッセージが ActionProcessingFaultException として返されます。送信者 (または仲介者) に返されるエラー情報が重要である場合、FaultTo EPR を設定してください。これを設定しないと JBoss Enterprise Service BusReplyTo EPR に基づいてエラーメッセージの配信を試行し、ReplyTo EPR も設定されていない場合は From EPR に配信を試行します。いずれの EPR も設定されていない場合、エラー情報はローカルにロギングされます。
アクション実装は、様々な種類のエラーメッセージを返すことができます。しかし、JBoss Enterprise Service Bus は、以下の "system" エラーメッセージに対応しています。例外が送出され、アプリケーション固有の失敗メッセージがある場合、統一のリソース識別子により特定される場合があります。
urn:action/error/actionprocessingerror
これは、chain 内のアクションが ActionProcessingFaultException を送出したが返す失敗メッセージを含んでいなかったという意味になります。例外の詳細は Faultreason String 内に含まれます。
urn:action/error/unexpectederror
つまり、処理中に予期しない例外が出現していることになります。例外に関する詳細は Faultreason String 内にあります。
urn:action/error/disabled
アクション処理が無効になります。
Action チェーン内で例外が送出される場合、FaultMessageException 内のクライアントに伝播して戻されます。これは CourierServiceInvoker のクラスから再度送出されます。Fault メッセージが受信されるときにも必ず送出されるこの例外は、Fault のコードおよび理由の他に伝播された例外を含みます。

4.2. メタデータとフィルター

Enterprise Service Bus を通ってメッセージが循環されるため、メタデータを添付したい場合があります。また、トランザクションやセキュリティ情報を追加するなど、動的にメッセージを補強する必要があるかもしれません。これらの機能はいずれもゲートウェイと ESB ノード群両方に対して filter mechanism を使って Enterprise Service Bus でサポートされます。
org.jboss.soa.esb.filter.InputOutputFilter クラスは 2 種類のメソッドを持ちます。
  • public Message onOutput (Message msg, Map<String, Object> params) は CourierException をスローします。これははトランスポートへのメッセージの流れとして呼び出されます。実装はメッセージを修正して新しいバージョンを返すことができます。追加情報は追加のパラメーターの形式で呼び出し側により提供することが可能です。
  • public Message onInput (Message msg, Map<String, Object> params) は、CourierException をスローします。これは、トランスポートからのメッセージの流れとして呼び出されます。実装はメッセージを修正して新しいバージョンを返すことができます。追加情報は追加のパラメーターの形式で呼び出し側により提供することが可能です。
フィルターは jbossesb-properties.xml ファイルの filters セクションで定義します (jbossesb.sar アーカイブにあり)。これには、org.jboss.soa.esb.filter.<number> プロパティを使います。<number> の部分は何の値でも構いません。複数のフィルターを呼び出す順序を示すのに使用します (低い値から高い値)。

注記

この環境にデプロイする各 ESB インスタンスに、jbossesb-properties.xml への変更を置く必要があります。こうすることで、すべてのインスタンスが同じメタデータを処理できるようにします。
JBoss Enterprise Service Bus には以下が含まれています。
  • org.jboss.internal.soa.esb.message.filter.MetaDataFilter
  • org.jboss.internal.soa.message.filter.GatewayFilter
  • org.jboss.internal.soa.esb.message.filter.EntryExitTimeFilter
これらは、指定のプロパティ名や返された文字列の値を持つプロパティとして、以下のメタデータをメッセージに追加します。

ゲートウェイ関連のメッセージプロパティ

org.jboss.soa.esb.message.transport.type
ファイル、FTP、JMS、SQL、Hibernate
org.jboss.soa.esb.message.source
これは、メッセージが読み込まれたファイルの名前
org.jboss.soa.esb.message.time.dob
メッセージが ESB に入った時間 (送信された時間またはゲートウェイに到着した時間)
org.jboss.soa.esb.mesage.time.dod
メッセージが ESB から出た時間 (受信した時間)
org.jboss.soa.esb.gatway.original.queue.name
メッセージが JMS ゲートウェイノード経由で受信された場合、このエレメントは受信された元のキューの名前を含む
org.jboss.soa.esb.gateway.original.url
メッセージが SQL ゲートウェイノード経由で受信された場合、このエレメントはオリジナルのデータベース URL を含む

注記

すべての Enterprise Service Bus ノードで GatewayFilter のデプロイは安全ですが、gateway node にデプロイされる場合は、メッセージへの情報追加しか行いません。
適切なフィルターを作成して登録することで、メッセージにより多くのメタデータを追加することができます。フィルターは追加パラメーター内の次のような名前が付くエントリの存在があるかないかでゲートウェイノード内で稼働しているかどうかを判断することができ

ゲートウェイ生成のメッセージパラメーター

org.jboss.soa.esb.gateway.file
メッセージ提供元のファイル。このゲートウェイがファイルベースである場合にのみ表される。
org.jboss.soa.esb.gateway.config
ゲートウェイインスタンスの初期化に使用された ConfigTree

注記

Red Hat は、ファイルベースの Java Message Service および SQL ゲートウェイを使用する場合のみ、 GatewayFilter をサポートします。

4.3. サービスとは

JBoss Enterprise Service Bus では、サービスは連続する形でメッセージを処理するアクションクラスの一覧であると定義されています。この定義内では、Enterprise Service Bus は、サービスの構成要素には制限を貸さないとされています。本ガイドの前半で説明したように、理想的な SOA インフラストラクチャーとは、メッセージが非常に重要となり実装固有の詳細が抽象インターフェースの背後に隠れるようなクライアントとサービス間に積極的な疎結合の対話式を採用しているインフラストラクチャーです。これにより、実装はクライアントやユーザー側での変更を必要としない変更が可能になります。メッセージの定義に対する変更で必然的に伴うのはクライアントへの更新のみになります。
こうした理由から、Enterprise Service Bus はサービスの定義と構成にメッセージ駆動型パターンを使用します。クライアントは Message をサービスに送り、基本的なサービスインターフェースは本質的に受け取った Message で動作する単一プロセスのメソッドになります。内部的にサービスは 1 つまたは複数の Action から構成され、着信 Message を処理するためチェーン化することができます。Action が行うことは実装依存になります。つまり、データベーステーブルのエントリを更新したり EJB を呼び出すなどです。
  1. カスタマイズのサービスを開発する場合、最初にコンシューマー側に公開する概念的なインターフェース (や規定) を決定する必要があります。この規定は Message の観点から定義されなければなりません (つまり、ペイロードをどのようにするか、どのタイプの応答 Message が生成されるかなどです)。
  2. 定義が完了したら、規定情報を registry 内で公開しなければなりません (現在、JBossESB には自動的にこれを行う手段はありません)。
  3. これでクライアントは公開された規定に従ってサービスを使用することができるようになります。サービスが Message をどのように処理し必要な作業を行うかについては実装での選択になります。単一の Action 内でも複数の Action 内でも可能です。管理性と再利用性のどちらをとるかなど、多少の代償はつきものです。

注記

今後のリリースでは、サービスの開発を容易にするツールサポートを向上させる予定です。

4.3.1. ServiceInvoker

JBoss Enterprise Service Bus 4.2 では、開発にかける作業の簡略化を支援するため ServiceInvoker が採用されました。ServiceInvoker は多くの低レベル詳細を表示させずステートレスサービスのフェールオーバーメカニズムと不透明に動作します。このように、Red Hat ではは ESB サービスのクライアント側インターフェースとして、ServiceInvoker の使用を推奨します。
public class ServiceInvoker
    {
        public ServiceInvoker(Service service) throws MessageDeliverException;
        public ServiceInvoker(String serviceCategory, String serviceName) throws MessageDeliverException;
			 public ServiceInvoker(Service service, List<PortReference.Extension> extensions);
        public Message deliverSync(Message message, long timeoutMillis) throws MessageDeliverException, RegistryException, FaultMessageException;
        public void deliverAsync(Message message) throws MessageDeliverException;
			public Service getService();
			public String getServiceCategory();
    }
ServiceInvoker のインスタンスはクライアントが対話を必要とするそれぞれのサービスに対して作成することができます。作成すると、そのインスタンスはプライマリの EPR またフェールオーバーの際には代替となる EPR を確定するため必要に応じて registry にコンタクトします。
作成すると、クライアントはサービスに対して同期的 (deliverSync) にまたは非同期的 (deliverAsync) にメッセージを送信する方法を確定できるようになります。同期的な方法の場合、タイムアウトを指定する必要があり、これはクライアントが応答を待機する時間になります。この期間内に応答が受信されないと ResponseTimeoutException が送出されます。
registry へコンタクトがとれない、またはサービスのルックアップに成功した場合、RegistryException が、deliverSync から送出されます。タイムアウトの値は以下の 3 つのいずれかをさします。
  1. サービスの問題
  2. 単にオーバーロードして時間内に応答できない
  3. 許容のタイムアウト時間よりもリクエストした作業に時間がかかっている

注記

問題が一時的な場合、次の試行で消える可能性があります。

注記

サービスと通信中の問題については、FaultMessageException が送出されます。
本ガイドの前半で説明したように、Message を送信する際に ToReplyToFaultToなどの値をMessage ヘッダー内に指定することが可能です。ServiceInvoker を使用する場合、構成される際に registry に既にコンタクトを行っているため To フィールドは不要になります。実際、ServiceInvoker を通じて Message を送信する場合、To フィールドは同期的配信モードでも非同期的配信モードでも無視されます。

注記

JBoss Enterprise Service Bus の今後のリリースでは、別の配信先として提供された To フィールドを使用することができ、registry により返されたエンドポイント参照により、アクティブなサービスへの解決が失敗します。

注記

JBoss Enterprise Service Bus のフェールオーバーのプロパティについては、本書の「高度なトピック」の章で説明しています。複数のコピーが registry にある場合ServiceInvoker が個別サービスインスタンスの問題を不透明にするのですが、高度なトピックでは、その方法についても説明しています。しかし、問題発生直後にアプリケーションに通知するための自動フェールオーバーを避けたい場合もあります。この方法は、 property にて org.jboss.soa.esb.exceptionOnDeliverFailure プロパティを true に設定することでグローバルレベルの設定を行います。あるいは、メッセージ別にこれを設定します。固有のメッセージで同プロパティを true に設定することも可能です (いずれの場合もデフォルト値は false です)。

4.3.2. トランザクション

InVM や Java Message Service など、一部の媒体で、トランザクション配信セマンティクスに対応しています。このような媒体に対する配信セマンティクスは JMS トランザクションセッションをベースにしています。つまり、トランザクションの範囲内にあるキューにメッセージが置かれるという意味です。しかし、内包されるトランザクションがコミットされるまで実際は配信されません。その後、別のトランザクションの範囲内で受け取り側がプルします。
JBossESB 4.5 以降はこのようなブロックされる状況を検出するよう試み、IncompatibleTransactionScopeException をスローします。JBoss ESB は、随時これをキャッチして状況に応じて機能します。

4.3.3. サービスと ServiceInvoker

クライアントとサービスの環境では、クライアントとサービスという用語を使って役割を表し、単一のエンティティが同時にクライアントでありサービスであり得ます。このように、ServiceInvoker とは純粋にクライアントの領域になりませんのでご注意ください。サービス内、 特に Action 内での使用が可能です。たとえば、ビルトインの content-based router を使用せずに、特定のビジネスロジックの評価に基づき異なるサービスに着信メッセージを再ルーティングさせるため Action を使用したい場合、あるいは Action によって後日の管理目的で Dead Letter Queue に障害メッセージの特定タイプをルーティングするよう決定させることもできます。
このようにして ServiceInvoker を使用すると、(「高度なトピック」の章で説明されているように) サービスにとって不透明なフェールオーバーのメカニズムという利点が得られます。つまり、複雑な開発作業をすることなく、より堅固な方法で他のサービスや障害などへの一方向要求のルーティングが可能になるということになります。

4.3.4. InVM トランスポート

InVM トランスポートは同じ JVM で実行されているサービス間の通信を提供します (InVM とは In Virtual Machine のことです) 。つまり、ServiceInvoker のインスタンスは、ネットワークやメッセージシリアライズ化のオーバーヘッドなしに同じ JVM 内からサービスを起動できます。

注記

サービス間通信を容易化するために使用する内部のデータ構造を最適化することで、InVM 機能がパフォーマンスの利点を受け取ることができます。メッセージの保存にしようするキューは永続的ではありません。つまり、メッセージは問題があれば失われる可能性があります。さらに、キューが空になる前にサービスが停止した場合、これらのメッセージは配信されません。他の制限は本章全体で記載しています。
JBoss Enterprise Service Bus では、複数のトランスポートにて同時にサービスが呼び出されるため、高性能および信頼性を実現できる方法でサービスを設計します。これには、各メッセージタイプに大して適切なトランスポートを選択してください。
<service category="ServiceCat" name="ServiceName" description="Test Service">
    <actions mep="RequestResponse">
        <action name="action" class="org.jboss.soa.esb.listeners.SetPayloadAction">
            <property name="payload" value="Tom Fennelly" />
        </action>
    </actions>			
</service>
初期の Enterprise Service Bus は、このトランスポートをサポートしておらず、各サービスにメッセージ対応リスナー 1 つ以上持たせるように設定する必要がありました。これは必要なくなり、サービスは <listeners> 設定なしに設定でき、仮想マシン内から呼び出しも可能です。
<service category="ServiceCat" name="ServiceName" description="Test Service">
    <actions mep="RequestResponse">
        <action name="action" class="org.jboss.soa.esb.listeners.SetPayloadAction">
            <property name="payload" value="Tom Fennelly" />
        </action>
    </actions>			
</service>
こうすることで、サービスの設定も比較的簡単になります。

4.3.5. InVM のスコープ

InVM サービス呼び出しのスコープは <service> 要素のinvmScope 属性を使用して制御します。Red Hat では現在、以下の 2 つのスコープに対応しています。
  1. NONE: Service は InVM トランスポートで起動できません。デフォルト値。
  2. GLOBAL: Service は同じ Classloader スコープ内から InVM トランスポートで起動可能です。

注記

今後のリリースには LOCAL スコープが追加され、デプロイされた同じ .esb アーカイブ内での起動が制限されます。
適切な名前のついた invmScope 属性を使用することで、各サービスの個別 InVM スコープを指定します (サービス設定の <service> 要素)。
<service category="ServiceCat" name="ServiceName" invmScope="GLOBAL"
  description="Test Service">
  <actions mep="RequestResponse">
    <action name="action" 
      class="org.jboss.soa.esb.listeners.SetPayloadAction">
      <property name="payload" value="Tom Fennelly" />
    </action>
  </actions>			
</service>
Enterprise Service Bus デプロイメント用のデフォルトの InVM Scope は jbossesb-properties.xml ファイルで core:jboss.esb.invm.scope.default プロパティを使用して指定されます。指定されている設定値は NONE ですが、このプロパティが未定義の場合、デフォルトのスコープは実際には GLOBAL になります。

4.3.6. 処理された InVM

InVM listener は、トランザクションスコープまたは非トランザクションスコープの中で実行可能です。トランザクション対応の他のトランスポートとして同じように実行します。明示的または暗黙的に設定を変更することでこの動作を制御します。
サービス要素の invmTransacted 属性を使い、トランザクションスコープの明示的設定を操作します。この設定は常に、暗黙的設定よりも優先されます。

注記

同じサービス上に設定されたトランザクショントランスポートが他にもある場合、InVM listener は暗黙的にトランザクションされます。現在、これらの追加トランスポートは JMS、Scheduled または SQL タイプとなります。

4.3.7. トランザクションセマンティック

警告

Enterprise Service Bus の InVM トランスポート はトランザクション形式であり、message queue は揮発性メモリにのみ保持されます。つまり、システム障害時またはシャットダウン時にこのトランスポートのメッセージキューは失われます。

重要

InVM トランスポートでは、ACID (Atomicity、Consistency、Isolation、Durability) セマンティクスすべてを実現できない場合があります。特に、データベースなど他のトランザクションリソースとあわせて使用している場合などです。これは、InVM キューの変動性が原因となっています。しかし、多くの場合、この欠点よりも、InVM のパフォーマンスの利点のほうがかなり大きくなります。全 ACID セマンティクスが必要な場合、Red Hat は、Java Message Service などの別のトランザクショントランスポートを使用するよう推奨しています。
InVM がトランザクション内で使用される場合、トランザクションが実際にコミットされるまで、メッセージは受取側のキューにはでてきません。しかし、送信側が後にキューに入れるようにメッセージが受信された旨の確認を直後に受け取ります。受取側は、キューからトランザクションのスコープ内にあるメッセージをプルしようとすると、トランザクションが結果的にロールバックされる場合メッセージは自動的にキューに置かれます。メッセージの送信側や受信側がトランザクションの結果を知りたい場合、直接モニタリングするか、トランザクションの同期登録をする必要があります。
トランザクションマネージャーがメッセージをキューに戻す場合、同じ場所に戻らない場合があります。これは、パフォーマンスを最適化する目的でこのように設計されています。アプリケーションで特定の順番にメッセージを並べる必要がある場合、別のトランスポートか、単一の wrapper メッセージ内にグループ関連のメッセージを使用するようにしてください。

4.3.8. スレッド化

InVM トランスポートに関連するリスナースレッドの数を変更するには、以下のコードを使用します。
<service category="HelloWorld" name="Service2" 
    description="Service 2" invmScope="GLOBAL"> 
       		 <property name="maxThreads" value="100" /> 
         		<listeners>... 
         		<actions>...

4.3.9. ロックステップ配信

IInVM transport は低いオーバーヘッドでメモリ内メッセージキューにメッセージを配信します。これは非常に高速であり、メッセージを消費するサービスに対して配信が行われるのが速すぎるとメッセージキューが溢れてしまうことがあります。これらの状況を緩和するために InVM トランスポートはロックステップ配信メカニズムを提供します。
子のメカニズムでは、サービスがメッセージを取得する前にメッセージがサービスに配信されないようにします。これは、受信側サービスがメッセージを取得するか、タイムアウト時間に到達するまでメッセージ配信をブロックすることによって行われます。

注記

これは同期配信方法ではありません。応答を待ったり、サービスがメッセージを処理するのを待ったりせず、メッセージがサービスによってキューから削除されるまでブロックします。
ロックステップ配信はデフォルトで無効になっていますが、<service> の <property> 設定を使用してサービスに対して設定できます。
  • inVMLockStep: LockStep 配信を有効にするかどうかを制御するブール値
  • inVMLockStepTimeout: メッセージ取得の待機時にメッセージ配信をブロックする最大時間 (ミリ秒単位)
<service category="ServiceCat" name="Service2" 
  description="Test Service">
  <property name="inVMLockStep" value="true" />
  <property name="inVMLockStepTimeout" value="4000" />

  <actions mep="RequestResponse">
    <action name="action" class="org.jboss.soa.esb.mock.MockAction" />
  </actions>
</service>

注記

トランザクションのスコープ内で InVM transport を使用する場合、ロックステップ配信は無効になります。内包のトランザクションをコミットする際に、メッセージが偶発的にキューに挿入されるためです。このコミットメントは、ロックステップの待機時間の前後であれば発生する可能性があります。

4.3.10. 負荷分散

ServiceInvoker を使用する場合は、InVM トランスポート (利用可能な場合) よりもサービスを起動することが常に優先されます。他の負荷分散のストラテジは、ターゲットサービスに対して InVM エンドポイントが存在しない場合のみ適用されます。
ServiceInvoker を使用する場合は、InVM トランスポート (利用可能な場合) よりもサービスを起動することが常に優先されます。他の負荷分散ストラテジーは、ターゲットサービスに対して InVM エンドポイントが存在しない場合のみ適用されます。

4.3.11. 「値で渡す」と「参照で渡す」

デフォルトでは、InVM transport参照としてメッセージを渡します。場合によっては、データの整合性に問題が出てくる場合があります。また、クラスキャストの問題、つまり、ClassLoader 境界を越えてメッセージが交換されてしまう場合もあります。
これらの問題を回避するには、値別にメッセージが渡されるように設定します。このサービスの inVMPassByValue プロパティを true に設定することで、メッセージが値別に渡されるように設定します。
<service category="ServiceCat" name="Service2" description="Test Service">
    <property name="inVMPassByValue" value="true" />

    <actions mep="RequestResponse">
        <action name="action" class="org.jboss.soa.esb.mock.MockAction" />
    </actions>
</service>

4.4. サービス規定定義

契約定義は、受信要求、送信応答、および対応するサービスによってサポートされる障害詳細メッセージを表す XML スキーマ定義を含めることによってサービスに対して指定できます。要求および応答メッセージを表すスキーマはメッセージのメインボディセクションのコンテンツの形式を定義するために使用され、そのコンテンツの検証を強制的に実行できます。
スキーマはサービスの <actions> エレメントに以下の属性を指定することによって宣言されます。

表4.1 サービス規定属性

名前 説明 タイプ
inXsd 要求メッセージのスキーマを含むリソース (単一エレメントを表す) xsd:string
outXsd 応答メッセージのスキーマを含むリソース (単一エレメントを表す) xsd:string
faultXsd スキーマのコンマで区切られた一覧 (それぞれが 1 つまたは複数のエラーエレメントを表す) xsd:string
requestLocation ボディ内の要求コンテンツの場所 (デフォルトの場所でない場合) xsd:string

4.5. メッセージ検証

要求および応答メッセージの内容は自動的に検証され、関連づけられたスキーマが <actions> エレメントに対して宣言されていることを確認します。この検証は、<actions> エレメントの validate 属性を true の値で指定することによって有効にできます。

注記

検証はデフォルトで無効にされます。

4.6. ESB サービスを Web サービスエンドポイント経由で公開

コントラクトスキーマを宣言すると、Web サービスエンドポイントを介して ESB サービスが自動的に公開されます (Contract Web アプリケーションを介して探すことができます)。この機能は webservice 属性を指定することによって変更できます。この値は以下のとおりです。

表4.2 Web サービス属性

名前 説明
false Web サービスエンドポイントは公開されない
true Web サービスエンドポイントは公開される (デフォルト)
デフォルトでは、Web サービスのエンドポイントは WS-Addressing をサポートしません。この機能を有効にするには、addressing 属性を設定します。

表4.3 WS-Addressing の値

説明
false WS-Addressing はサポートされていません (デフォルト)
true WS-Addressing サポートが必要です。
アドレッシングのサポートを有効にすると、WS-Addressing Message IdRelates To URIsRelationship タイプがプロパティとして受信メッセージに追加されます。

表4.4 WS-Addressing プロパティ

プロパティ 説明
org.jboss.soa.esb.gateway.ebws.messageID WS-Addressing のメッセージ識別子
org.jboss.soa.esb.gateway.ebws.relatesTo WS-Addressing Relates To URIs を含む文字列配列
org.jboss.soa.esb.gateway.ebws.relationshipType Relates To URIs に該当する WS-Addressing Relationship タイプを含む文字列配列
次の例では、(Web サービスのエンドポイントを使って公開することなしに) メッセージのリクエスト/レスポンスを検証したいサービスの宣言方法について例示しています。
<service category="ServiceCat" name="ServiceName" description="Test Service">
    <actions mep="RequestResponse" inXsd="/request.xsd" outXsd="/response.xsd"
            webservice="false" validate="true">
        <!-- .... >
    </actions>			
</service>
以下の例は要求および応答メッセージを検証し、Web サービスエンドポイントを介してサービスを公開するサービスの宣言を示しています。またサービスは要求が指定されたボディの場所の REQUEST に提供され、応答が指定されたボディの場所の RESPONSE に返されます。
<service category="ServiceCat" name="ServiceName" description="Test Service">
    <actions mep="RequestResponse" inXsd="/request.xsd" outXsd="/response.xsd"
            validate="true" requestLocation="REQUEST" responseLocation="RESPONSE">
        <!-- .... -->
    </actions>			
</service>

このページには機械翻訳が使用されている場合があります (詳細はこちら)。