コンテンツ ベースのルーティングを実装するために、ルーティング サービスは、アドレス、エンドポイント名、特定の XPath ステートメントなど、メッセージの特定のセクションを検査する MessageFilter 実装を使用します。 .NET Framework 4.6.1 で提供されるメッセージ フィルターのいずれもニーズを満たさない場合は、基本 MessageFilter クラスの新しい実装を作成してカスタム フィルターを作成できます。
ルーティング サービスを構成する場合は、MessageFilter の種類と、メッセージ内で検索する特定の文字列値など、フィルターの作成に必要なサポート データを記述するフィルター要素 (FilterElement オブジェクト) を定義する必要があります。 フィルター要素を作成すると、個々のメッセージ フィルターのみが定義されることに注意してください。フィルターを使用してメッセージを評価およびルーティングするには、フィルター テーブル (FilterTableEntryCollection) も定義する必要があります。
フィルター テーブル内の各エントリは、フィルター要素を参照し、メッセージがフィルターと一致する場合にメッセージがルーティングされるクライアント エンドポイントを指定します。 フィルター テーブルのエントリを使用すると、バックアップ エンドポイント (BackupEndpointCollection) のコレクションを指定することもできます。これにより、プライマリ エンドポイントへの送信時に送信エラーが発生した場合にメッセージが送信されるエンドポイントの一覧が定義されます。 これらのエンドポイントは、成功するまで指定された順序で試行されます。
メッセージ フィルター
ルーティング サービスで使用されるメッセージ フィルターは、メッセージが送信されたエンドポイントの名前、SOAP アクション、メッセージが送信されたアドレスまたはアドレス プレフィックスの評価など、一般的なメッセージ選択機能を提供します。 フィルターは AND
条件と結合することもできます。そのため、メッセージがエンドポイントにルーティングされるのは、メッセージが両方のフィルターと一致する場合のみです。
MessageFilterの独自の実装を作成して、カスタム フィルターを作成することもできます。
次の表に、ルーティング サービスで使用される FilterType 、特定のメッセージ フィルターを実装するクラス、および必要な FilterData パラメーターを示します。
フィルターの種類 | 説明 | データの意味をフィルター処理する | フィルターの例 |
---|---|---|---|
アクション | ActionMessageFilter クラスを使用して、特定のアクションを含むメッセージを照合します。 | フィルター処理するアクション。 | <filter name="action1" filterType="Action" filterData="http://namespace/contract/operation" /> |
エンドポイントアドレス |
EndpointAddressMessageFilter クラスを使用し、IncludeHostNameInComparison == true を使用して、特定のアドレスを含むメッセージを照合します。 |
フィルター処理対象のアドレス (To ヘッダー内)。 | <filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" /> |
エンドポイントアドレスプレフィックス |
PrefixEndpointAddressMessageFilter クラスを使用し、IncludeHostNameInComparison == true を使用して、特定のアドレス プレフィックスを含むメッセージを照合します。 |
最長のプレフィックス一致を使用してフィルター処理するアドレス。 | <filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/" /> |
そして | 返す前に常に両方の条件を評価する StrictAndMessageFilter クラスを使用します。 | filterData は使用されません。代わりに、filter1 と filter2 には、対応するメッセージ フィルターの名前 (テーブル内にも) があり、一緒に ANDにする必要があります。 | <filter name="and1" filterType="And" filter1="address1" filter2="action1" /> |
習慣 | MessageFilter クラスを拡張し、文字列を受け取るコンストラクターを持つユーザー定義型。 | customType 属性は、作成するクラスの完全修飾型名です。filterData は、フィルターの作成時にコンストラクターに渡す文字列です。 | <filter name="custom1" filterType="Custom" customType="CustomAssembly.CustomMsgFilter, CustomAssembly" filterData="Custom Data" /> |
エンドポイント名 | EndpointNameMessageFilter クラスを使用して、到着したサービス エンドポイントの名前に基づいてメッセージを照合します。 | サービス エンドポイントの名前 (例: "serviceEndpoint1")。 これは、ルーティング サービスで公開されているエンドポイントの 1 つである必要があります。 | <filter name="stock1" filterType="Endpoint" filterData="SvcEndpoint" /> |
MatchAll | MatchAllMessageFilter クラスを使用します。 このフィルターは、到着するすべてのメッセージと一致します。 | filterData は使用されません。 このフィルターは常にすべてのメッセージと一致します。 | <filter name="matchAll1" filterType="MatchAll" /> |
XPath | XPathMessageFilter クラスを使用して、メッセージ内の特定の XPath クエリを照合します。 | メッセージを照合するときに使用する XPath クエリ。 | <filter name="XPath1" filterType="XPath" filterData="//ns:element" /> |
次の例では、XPath、EndpointName、PrefixEndpointAddress メッセージ フィルターを使用するフィルター エントリを定義します。 この例では、RoundRobinFilter1 エントリと RoundRobinFilter2 エントリにカスタム フィルターを使用する方法も示します。
<filters>
<filter name="XPathFilter" filterType="XPath"
filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
<filter name="EndpointNameFilter" filterType="EndpointName"
filterData="calculatorEndpoint"/>
<filter name="PrefixAddressFilter" filterType="PrefixEndpointAddress"
filterData="http://localhost/routingservice/router/rounding/"/>
<filter name="RoundRobinFilter1" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
<filter name="RoundRobinFilter2" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
</filters>
注
フィルターを定義するだけでは、メッセージがフィルターに対して評価されることはありません。 フィルターをフィルター テーブルに追加する必要があります。フィルター テーブルは、ルーティング サービスによって公開されるサービス エンドポイントに関連付けられます。
名前空間テーブル
XPath フィルターを使用する場合、名前空間の使用により、XPath クエリを含むフィルター データが非常に大きくなる可能性があります。 この問題を軽減するために、ルーティング サービスは、名前空間テーブルを使用して独自の名前空間プレフィックスを定義する機能を提供します。
名前空間テーブルは、XPath で使用できる一般的な名前空間の名前空間プレフィックスを定義する NamespaceElement オブジェクトのコレクションです。 名前空間テーブルに含まれる既定の名前空間と名前空間プレフィックスを次に示します。
接頭辞 | Namespace |
---|---|
s11 | http://schemas.xmlsoap.org/soap/envelope |
s12 | http://www.w3.org/2003/05/soap-envelope |
wsaAugust2004 | http://schemas.xmlsoap.org/ws/2004/08/addressing |
wsa10 | http://www.w3.org/2005/08/addressing |
sm | http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions |
tempuri | http://tempuri.org |
ser | http://schemas.microsoft.com/2003/10/Serialization |
XPath クエリで特定の名前空間を使用することがわかっている場合は、一意の名前空間プレフィックスと共に名前空間テーブルに追加し、完全な名前空間ではなく任意の XPath クエリでプレフィックスを使用できます。 次の例では、名前空間 "http://my.custom.namespace"
のプレフィックス "custom" を定義します。このプレフィックスは、filterData に含まれる XPath クエリで使用されます。
<namespaceTable>
<add prefix="custom" namespace="http://my.custom.namespace/"/>
</namespaceTable>
<filters>
<filter name="XPathFilter" filterType="XPath" filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
</filters>
テーブルのフィルター処理
各フィルター要素は、メッセージに適用できる論理比較を定義しますが、フィルター テーブルは、フィルター要素と宛先クライアント エンドポイントの間の関連付けを提供します。 フィルター テーブルは、フィルター、プライマリ宛先エンドポイント、および代替バックアップ エンドポイントの一覧間の関連付けを定義する FilterTableEntryElement オブジェクトの名前付きコレクションです。 フィルター テーブルのエントリを使用すると、フィルター条件ごとにオプションの優先度を指定することもできます。 次の例では、2 つのフィルターを定義し、各フィルターを宛先エンドポイントに関連付けるフィルター テーブルを定義します。
<routing>
<filters>
<filter name="AddAction" filterType="Action" filterData="Add" />
<filter name="SubtractAction" filterType="Action" filterData="Subtract" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="AddAction" endpointName="Addition" />
<add filterName="SubtractAction" endpointName="Subtraction" />
</filters>
</table>
</filterTables>
</routing>
フィルター評価の優先順位
既定では、フィルター テーブル内のすべてのエントリが同時に評価され、評価されるメッセージは、一致する各フィルター エントリに関連付けられているエンドポイントにルーティングされます。 複数のフィルターが true
に評価され、メッセージが一方向または双方向である場合、メッセージは一致するすべてのフィルターのエンドポイントにマルチキャストされます。 クライアントに返すことができる応答は 1 つだけであるため、要求/応答メッセージをマルチキャストすることはできません。
より複雑なルーティング ロジックは、各フィルターの優先度レベルを指定することで実装できます。ルーティング サービスは、最も優先度の高いレベルですべてのフィルターを最初に評価します。 メッセージがこのレベルのフィルターと一致する場合、優先順位の低いフィルターは処理されません。 たとえば、受信した一方向メッセージは、優先順位が 2 のすべてのフィルターに対して最初に評価されます。 メッセージはこの優先度レベルのどのフィルターとも一致しないため、次にメッセージは優先度が 1 のフィルターと比較されます。 2 つの優先度 1 フィルターがメッセージと一致し、一方向のメッセージであるため、両方の宛先エンドポイントにルーティングされます。 優先度 1 のフィルター間で一致が見つかったため、優先度 0 のフィルターは評価されません。
注
優先度が指定されていない場合は、既定の優先度 0 が使用されます。
次の例では、テーブルで参照されるフィルターの優先度 2、1、0 を指定するフィルター テーブルを定義します。
<filterTables>
<filterTable name="filterTable1">
<add filterName="XPathFilter" endpointName="roundingCalcEndpoint"
priority="2"/>
<add filterName="EndpointNameFilter" endpointName="regularCalcEndpoint"
priority="1"/>
<add filterName="PrefixAddressFilter" endpointName="roundingCalcEndpoint"
priority="1"/>
<add filterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint"
priority="0"/>
</filterTable>
</filterTables>
前の例では、メッセージが XPathFilter と一致する場合、メッセージは roundingCalcEndpoint にルーティングされ、他のすべてのフィルターの優先度が低いため、テーブル内のそれ以上のフィルターは評価されません。 ただし、メッセージが XPathFilter と一致しない場合は、次に優先度が低い EndpointNameFilter と PrefixAddressFilter のすべてのフィルターに対して評価されます。
注
可能な場合は、優先度の評価によってパフォーマンスが低下する可能性があるため、優先度を指定する代わりに排他フィルターを使用してください。
バックアップ リスト
フィルター テーブル内の各フィルターでは、必要に応じて、エンドポイントの名前付きコレクション (BackupEndpointCollection) であるバックアップ リストを指定できます。 このコレクションには、EndpointNameで指定されたプライマリ エンドポイントに送信するときにCommunicationExceptionが発生した場合にメッセージが送信されるエンドポイントの順序付きリストが含まれます。 次の例では、2 つのエンドポイントを含む "backupServiceEndpoints" という名前のバックアップ リストを定義します。
<filterTables>
<filterTable name="filterTable1">
<add filterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<backupLists>
<backupList name="backupEndpointList">
<add endpointName="backupServiceQueue" />
<add endpointName="alternateServiceQueue" />
</backupList>
</backupLists>
前の例では、プライマリ エンドポイント "Destination" への送信が失敗した場合、ルーティング サービスは、一覧に示されている順序で各エンドポイントへの送信を試み、最初に backupServiceQueue に送信し、backupServiceQueue への送信が失敗した場合は alternateServiceQueue に送信します。 すべてのバックアップ エンドポイントが失敗した場合は、エラーが返されます。