第3章 サービスとメッセージ
- サービスはそれぞれ、ビジネス論理や統合ポイントをレガシーシステムでカプセル化します。
- メッセージを使い、クライアントとサービスは互いに通信します。
3.1. サービス
Listeners は、action pipeline へメッセージを送るため、サービスのインバウンドルーターとして機能します。
<?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" invmScope="GLOBAL">
<services>
<service category="Retail" name="ShoeStore" description="Acme Shoe Store Service">
<actions>
<action name="println" class="org.jboss.soa.esb.actions.SystemPrintln" />
</actions>
</service>
</services>
</jbossesb>
ServiceInvoker クラスを使用してサービスを呼び出すことができます。
ServiceInvoker invoker = new ServiceInvoker(“Retail”, “ShoeStore”); Message message = MessageFactory.getInstance().getMessage(); message.getBody().add(“Hi there!”); invoker.deliverAsync(message);
ServiceInvoker は Services Registry を使用して Retail:ShoeStore サービスが使用できるエンドポイントのアドレスをルックアップします。また、クライアントから使用できるサービスエンドポイントの 1 つにメッセージを送る処理をすべて行います。メッセージのトランスポート処理はクライアントに対して完全に透過的です。
ServiceInvoker に渡されるタイミングは、サービスに設定されているリスナーの種類により左右されます。例えば、JMS、FTP、HTTP などの種類です (上記の例では、リスナーは定義されていませんが、invmScope="GLOBAL" を使うことで、サービスの InVM listener が有効になっています)。
重要
- ゲートウェイリスナーゲートウェイリスナーの設定は、ゲートウェイエンドポイントを提供します。エンドポイントタイプは、ESB デプロイメント外部からメッセージのエントリポイントを提供します。また、サービスの
action pipelineへ送る前にメッセージペイロードを ESB Message へラップし、メッセージペイロードを「正規化」します。 - ESB 対応リスナーESB 対応のリスナーは、ESB 対応のエンドポイントを提供します。これは、ESB 対応コンポーネント間で ESB メッセージを交換する際に使用するエンドポイントのタイプです(たとえば、ESB 対応リスナーを使い、Bus 上でメッセージの交換ができます)。
<?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">
<providers>
<jms-provider name="JBossMQ" connection-factory="ConnectionFactory">
<jms-bus busid="shoeStoreJMSGateway">
<jms-message-filter dest-type="QUEUE" dest-name="queue/shoeStoreJMSGateway"/>
</jms-bus>
</jms-provider>
</providers>
<services>
<service category="Retail" name="ShoeStore" description="Acme Shoe Store Service"
invmScope="GLOBAL">
<listeners>
<jms-listener name="shoeStoreJMSGateway" busidref="shoeStoreJMSGateway"
is-gateway="true"/>
</listeners>
<actions>
<action name="println" class="org.jboss.soa.esb.actions.SystemPrintln" />
</actions>
</service>
</services>
</jbossesb>
ServiceInvoker は、常にサービスのローカル InVM エンドポイントがあればそれを優先的に利用します)。
3.2. メッセージ
- 要求応答アーキテクチャーでなく一方向メッセージを使用します。
- 交換されたメッセージ内で規定の定義を維持します。後で実装の変更が大変難しくなるため、バックエンド実装の選択を公開するサービスインターフェースを定義しないようにしてください。
- メッセージペイロードに拡張可能なメッセージ構造を使用します。これにより、変更をバージョン化して後方互換性を維持することができます。
- 極端に粒度が細かいサービスは開発しないようにしてください。これは、簡単に環境の変化に対応できないような非常に複雑なアプリケーションが必要になることが多いためです (SOA のパラダイムは分散オブジェクトではなく、1 つのサービスである点を忘れないでください)。
<xs:complexType name="Envelope"> <xs:attribute ref="Header" use="required"/> <xs:attribute ref="Context" use="required"/> <xs:attribute ref="Body" use="required"/> <xs:attribute ref="Attachment" use="optional"/> <xs:attribute ref="Properties" use="optional"/> <xs:attribute ref="Fault" use="optional"/> </xs:complexType>

図3.1 メッセージの基本構造
org.jboss.soa.esb.message.Message インターフェースの実装です。このパッケージには、メッセージ内の各種フィールドのインターフェースが同梱されます。
public interface Message
{
public Header getHeader ();
public Context getContext ();
public Body getBody ();
public Fault getFault ();
public Attachment getAttachment ();
public URI getType ();
public Properties getProperties ();
public Message copy () throws Exception;
}
警告
org.jboss.soa.esb.addressing.Call クラスに関して学習するには、次章を参照してください)。
public interface Header
{
public Call getCall ();
public void setCall (Call call);
}
注記
警告
public interface Body
{
public static final String DEFAULT_LOCATION =
"org.jboss.soa.esb.message.defaultEntry";
public void add (String name, Object value);
public Object get (String name);
public byte[] getContents();
public void add (Object value);
public Object get ();
public Object remove (String name);
public void replace (Body b);
public void merge (Body b);
public String[] getNames ();
}
重要
add を使用してください。クライアントとサービスに対して同じバイト配列の場所が必要な場合、JBoss ESB が使用する ByteBody.BYTES_LOCATION を使用できます。
警告
DEFAULT_LOCATION) は注意して使用してください。
public interface Fault
{
public URI getCode ();
public void setCode (URI code);
public String getReason ();
public void setReason (String reason);
public Throwable getCause ();
public void setCause (Throwable ex);
}
警告
public interface Properties
{
public Object getProperty(String name);
public Object getProperty(String name, Object defaultVal);
public Object setProperty(String name, Object value);
public Object remove(String name);
public int size();
public String[] getNames();
}
注記
java.util.Properties を使用する properties はまだ、JBoss Enterprise Service Bus には実装されていません。これは、利用可能なクライアントやサービスのタイプを制限するためです。同じ理由から、Web Services スタックもこれらのプロパティを実装しません。この制約に対応するには、現在の抽出に java.util.Properties を埋め込んでください。
Attachment インターフェースは、名前の付いた添付と名前のない添付の両方をサポートします。JBossESB の現在のリリースでは、Java でシリアライズされたオブジェクトのみが添付として扱われます。今後のリリースではこの制限が解除される予定です
public interface Attachment
{
Object get(String name);
Object put(String name, Object value);
Object remove(String name);
String[] getNames();
Object itemAt (int index) throws IndexOutOfBoundsException;
Object removeItemAt (int index) throws IndexOutOfBoundsException
Object replaceItemAt(int index, Object value)
throws IndexOutOfBoundsException;
void addItem (Object value);
void addItemAt (int index, Object value)
throws IndexOutOfBoundsException;
public int getUnnamedCount();
public int getNamedCount();
}
注記
注記
- 開発者は、クライアントがサービスとの対話を行うために使用するコントラクトを定義します。このコントラクトの一部で、サービスの機能、非機能部分を指定します。例えば、航空予約サービス (機能) やトランザクション関連のサービス (非機能) です。また、開発者はサービスが理解できるオペレーション (メッセージ) も定義します。形式 (Java Serialized Message や XML) もメッセージ定義の一部として定義されます (この例ではトランザクションコンテキスト、座席番号、顧客名などです)。コンテンツを定義すると、サービスがペイロードがメッセージのどの部分にあるか分かるよう指定します (アタッチメントや、具体的な名前付きオブジェクト、またはデフォルトの名前付きオブジェクトなどの形式で行うことができます)。これはサービス開発者が決定します。唯一の制限事項は、オブジェクトとアタッチメントはグローバル一意名でなければならない点です (そうでなければ、同じメッセージボディが複数の「Hop」で転送される場合、サービスやアクションは別のものに向けられた部分的なペイロードを誤って拾ってしまう場合があります) 。
- サービスのコントラクト定義 (UDDI レジストリか、帯域外通信で) 取得でき、これでメッセージのどの部分にペイロードを置くかを定義します。それ以外の場所に置かれた情報は、ほぼ無視されるため、サービスが正しく実行されなくなります。
3.3. データの取得、設定
actions、listeners、gateways、routers、notifiers) はデフォルトでメッセージのデフォルトのペイロードの場所を使用して、メッセージ上にあるデータを "get"、"set" するよう設定されています。
MessagePayloadProxy を使用してメッセージの get やset を管理します。このクラスは上記のようにデフォルトのケースに対応しますが、すべてのコンポーネントで一様に無効にすることもできます。以下のコンポーネントプロパティを使用して、メッセージペイロードの get や set の場所を一様に無効にすることができます。
- get-payload-location: メッセージペイロードを取得する場所。
- set-payload-location: メッセージペイロードを設定する場所。
注記
jbossesb.sarに移動します。jbossesb-properties.xmlファイルを開きます。- core セクションで、use.legacy.message.payload.exchange.patterns プロパティを
trueに設定します。
3.4. ボディの拡張
拡張タイプ
org.jboss.soa.esb.message.body.content.TextBody- ボディの内容が任意のストリングの場合これを使用します。
getTextメソッドやsetTextメソッドを使用して操作することができます。 org.jboss.soa.esb.message.body.content.ObjectBody- ボディの内容がシリアライズされたオブジェクトの場合はこれを使います。
getObjectメソッドやsetObjectメソッドを使用して操作することができます。 org.jboss.soa.esb.message.body.content.MapBody- ボディの内容がマップ (ストリング、シリアライズされている) の場合これを使用します。
setMapメソッドやその他のメソッドを使用して操作することができます。 org.jboss.soa.esb.message.body.content.BytesBody- ボディの内容が任意の Java データタイプを含むバイトストリームの場合これを使用します。データタイプのメソッドを使用して操作することができます。
BytesMessageが作成されると、操作の必要に応じて読み取り専用モードまたは書き込み専用モード内に置かれます。readMode()メソッドやwriteMode()メソッドを使用してモードを変更することができますが、モードが変更される度にバッファーポイントがリセットされます。flush()メソッドを呼び出して、すべての更新がボディに適応されたことを確認する必要があります。
XMLMessageFactory クラスや SerializedMessageFactory クラスを使用すると、これらのインターフェースを基にしたボディの実装を持つメッセージを作成することができます。メッセージに対して作業を行う場合、MessageFactory クラスや MessageFactory に関連したクラスを使用するより、XMLMessageFactory クラスや SerializedMessageFactory クラスを使用した方が便利です。
createTextBody など、ボディの各タイプに関連する create メソッドが存在します。このメソッドによって、特定タイプのメッセージを作成し初期化することができます。メッセージの作成後、ローボディまたはインターフェースメソッドを使用して直接メッセージを操作することができます。ボディの構造は送信後も維持されるため、メッセージを作成したインターフェースのメソッドを使用すればメッセージの受信側が操作することもできます。
注記
3.5. メッセージヘッダー
org.jboss.soa.esb.addressing.Call クラスのインスタンスに格納されます。
public class Call
{
public Call ();
public Call (EPR epr);
public Call (Call copy);
public void setTo (EPR epr);
public EPR getTo () throws URISyntaxException;
public void setFrom (EPR from);
public EPR getFrom () throws URISyntaxException;
public void setReplyTo (EPR replyTo);
public EPR getReplyTo () throws URISyntaxException;
public void setFaultTo (EPR uri);
public EPR getFaultTo () throws URISyntaxException;
public void setRelatesTo (URI uri);
public URI getRelatesTo () throws URISyntaxException;
public void copy();
public void setAction (URI uri);
public URI getAction () throws URISyntaxException;
public final boolean empty();
public void setMessageID (URI uri);
public URI getMessageID () throws URISyntaxException;
public String toString();
public String stringForum();
public boolean valid();
public void copy (Call from);
}
org.jboss.soa.esb.addressing.Call は一方向パターンと要求返答対話パターンの両方をサポートします。
表3.1 org.jboss.soa.esb.addressing.Call プロパティ
| プロパティ | タイプ | 必須 | 説明 |
|---|---|---|---|
| To | EPR | Yes | メッセージ受信側のアドレス |
| From | EPR | No | メッセージ発信元のエンドポイント |
| ReplyTo | EPR | No | このメッセージに返信する受信側を特定するエンドポイント参照 |
| FaultTo | EPR | No | 不良の警告の受信側を識別するエンドポイント参照 |
| Action | URI | Yes | これは、メッセージが暗示するセマンティクスを一意かつ不透明に識別します。 |
| MessageID | URI | 場合による | 時空間でこのメッセージを一意に識別する URI。別のアプリケーションに使う予定のメッセージは [MessageID] を共有することはできません。メッセージは、通信エラーなどが原因で再送信され、同じ [MessageID] プロパティを使用する可能性があります。このプロパティの値は、不透明な URI で、等価を超えた解釈については定義されません。返信が来るものについては、このプロパティを必ず設置する必要があります。 |

図3.2 UML で表記されたヘッダーとエンドポイント参照の関係
注記
警告
注記
WS-Addressing 規格にまとめられています。
3.6. LogicalEPR
LogicalEPR とは、ESB サービス/エンドポイントの名前とカテゴリを指定する EPR のことです。LogicalEPR には物理アドレス指定の情報は含まれません。
LogicalEPR は EPR ユーザー(通常 ESB ですが、そうとは限りません)を想定しないため、LogicalEPR の選択が奨励されます。LogicalEPRのクライアントは EPR で提供されるサービス名やカテゴリの詳細を使用して、呼び出し が行われる時に(適切なアドレス指定情報を取得する場合など)サービスやエンドポイントに対する物理エンドポイントの詳細をルックアップできます。クライアントは適切な物理エンドポイントタイプを選択することもできます。
3.7. デフォルトの FaultTo
注記
LogicalEPR の詳細を参照してください。
3.8. デフォルトの ReplyTo
ReplyTo のデフォルトを使用するには、システム管理者は JBoss Enterprise Service Bus をデフォルト使用するよう設定する必要があります)。
表3.2 トランスポートによるデフォルトの ReplyTo
| トランスポート | ReplyTo |
|---|---|
| JMS | 元のリクエストの配信に使用した名前と同じものを持つキュー。接尾辞は _reply です。 |
| JDBC | 元の要求の配信に使用した名前を持つ同じデータベース内にあるテーブル。接尾辞は _reply_table (応答テーブルには、要求テーブルと同じ列定義が必要となります)。 |
| ファイル | ローカルファイルとリモートファイル共に管理的な変更は必要ありません。元の送信側のみが応答を受け取るようにするため、応答は固有のサフィックスで要求と同じディレクトリに書き込まれます。 |
3.9. メッセージペイロード
警告

図3.3 メッセージペイロードの UML 表記
add メソッドを使用します。粒度の細かくデータにアクセスできるように、名前付きのオブジェクトペアを使用します。どのタイプのオブジェクトでもメッセージボディに追加できます (Java シリアライズ可能でないオブジェクトを追加するには、JBoss Enterprise Service Bus にメッセージのマーシャル化とアンマーシャル化機能を追加する必要があります。このプロセスの詳細については、"メッセージフォーマット"のセクションを参照してください)。
注記
注記
注記
注記
3.10. MessageFactory
org.jboss.soa.esb.message.Message インターフェースの実装はすべて org.jboss.soa.esb.message.format.MessageFactory クラスから取得されます。
public abstract class MessageFactory
{
public abstract Message getMessage ();
public abstract Message getMessage (URI type);
public abstract void reset();
public static MessageFactory getInstance ();
}
- MessageType.JBOSS_XML: これは、ワイヤー上にあるメッセージの XML 表現を使用します。メッセージのスキーマは、
message.xsdファイルで定義します (schemasディレクトリ内にあります)。URI は urn:jboss/esb/message/type/JBOSS_XML です。 - MessageType.JAVA_SERIALIZED: この実装では、メッセージの全コンポーネントをシリアライズできます。また、このメッセージタイプの受信側には、デシリアライズするための十分な情報 (Java クラス) が必要なのは明らかです。URI はurn:jboss/esb/message/type/JAVA_SERIALIZED です。
重要
org.jboss.soa.esb.message.format.MessagePlugin を使用します。
public interface MessagePlugin
{
public static final String MESSAGE_PLUGIN =
"org.jboss.soa.esb.message.format.plugin";
public Object createBodyType(Message msg, String type);
public Message getMessage ();
public URI getType ();
}
getType() メソッドを使用して、提供するメッセージ実装のタイプを一意に識別しなければなりません。プラグインの実装は、org.jboss.soa.esb.message.format.plugin 拡張の付いたプロパティ名を使って jbossesb-properties.xml ファイル内でシステムに対し識別されなければなりません。
注記
JBOSS_XML です。これを変更するには、org.jboss.soa.esb.message.default.uri プロパティを任意の URI 名に設定します。
3.11. メッセージのフォーマット
MessageType.JAVA_SERIALIZED
IllegalParameterException がスローされます。
MessageType.JBOSS_XML
ワイヤー上にあるメッセージの XML 表現を使用します。メッセージのスキーマは、message.xsd ファイルで定義されます (schemas ディレクトリにあります)。任意オブジェクトをメッセージに追加できます。つまり、シリアライズする必要はありません。そのため、メッセージのシリアライズが必要な場合、このようなオブジェクトを XML にマーシャリングまたは、アンマーシャリングできるようにする必要があります。org.jboss.soa.esb.message.format.xml.marshal.MarshalUnmarshalPlugin から設定できます。
public interface MarshalUnmarshalPlugin
{
public static final String MARSHAL_UNMARSHAL_PLUGIN =
"org.jboss.soa.esb.message.format.xml.plugin";
public boolean canPack(final Object value);
public boolean marshal (Element doc, Object param)
throws MarshalException;
public Object unmarshal (Element doc) throws UnmarshalException;
public URI type ();
}
注記
jbossesb-properties.xml 設定ファイルよりシステムに登録しなければなりません。プラグインは MARSHAL_UNMARSHAL_PLUGIN で始まる属性名を持たなければなりません。

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.