MSDN マガジン > Home > 発行物 > 2008 > June >  SAAS: ホストされた BizTalk サービスを使用してエンタープライズ アプリケーション...
SAAS
ホストされた BizTalk サービスを使用してエンタープライズ アプリケーションを接続する
Jon Flanders および Aaron Skonnard

この記事は、ASP.NET 3.5 および Microsoft AJAX Library のプレリリース版に基づいて書かれています。ここに記載されているすべての情報は、変更される場合があります。
この記事では、次の内容について説明します。
  • ESB サービスとしての BizTalk サービス
  • BizTalk サービスに基づく WCF アプリケーション
  • 中継される接続のオプション
  • Identity サービスとトークン プロバイダ
この記事では、次のテクノロジを使用しています。
BizTalk サービス、.NET Framework 3.0
今日の企業には、新しいアプリケーションの開発、導入、および既存環境への統合を迅速に行う能力がこれまで以上に必要です。数多くの企業がそのアプリケーションの基盤をサービス指向アーキテクチャ (SOA) に移しましたが (または移しつつありますが)、その主な理由の 1 つは、動的な疎結合アプリケーションに対するニーズの高まりにあります。
企業が SOA に向かうにつれて、会社全体のさまざまなアプリケーションからシステムを構成することが重要視されるようになりました。この新たな世界では、他のチームや組織によりネットワーク上で提供される各種アプリケーション サービスのビジネス プロセスを統制する役目は、開発者が担います。チームまたは組織ごとに異なる実装テクノロジや基幹業務アプリケーションが使用されている場合があり、システム全体の複雑さは増大します。SOA によって各ポイントツーポイント接続は簡素化されますが、アプリケーションに必要なサービス接続の合計数が徐々に増加するにつれて、複合アプリケーションの管理が難しくなったり、不具合が発生しやすくなったりするおそれがあります (図 1 を参照)。
図 1 複合アプリケーションのポイントツーポイント接続の管理 (クリックすると拡大画像が表示されます)
こうした現実に即して、多くの企業がより緩やかに結合された持続性のあるサービス パターンを採用するようになってきています。このサービス パターンは、一般に Enterprise Service Bus (ESB) と呼ばれています。基となるメッセージング システム上に抽象層を提供するセントラル バスを通じて複数のサービス接続を管理できるようになるため、ESB モデルの普及は進んでいます。たとえば、ESB では、サービス間でブローカーの名前付け規則、ID 管理、メッセージ形式、および通信プロトコルが異なっていてもかまいません。サービスがバス上にホストされると、そのバス上のあらゆるものが (通常はサービスと直接通信できないものであっても) サービスに接続できるようになります (図 2 を参照)。
図 2 ESB を利用した複合アプリケーションの構築 (クリックすると拡大画像が表示されます)
このモデルでは、バス上の各種サービス間、および複合アプリケーションとそれらが使用するサービス間に、ある程度の間接性が設けられます。ESB は、システム全体での緩やかな結合を実現するパブリッシュ/サブスクライブ機能など、さまざまなメッセージング機能も提供します。パブリッシュ/サブスクライブ機能があれば、コンシューマがサービスと直接接続されている必要がなくなります (あらゆるノードがバスと接続できさえすればよいため)。また、ノードの追加や削除を自在に行うことができるようになります。通常、ESB は、ビジネス プロセス (この層は、一般にオーケストレーションまたはワークフローと呼ばれる) を構成するメッセージングを統制するためのプロセス フロー エンジンも提供します。
マイクロソフト プラットフォーム上で ESB パターンを採用したシステムを構築する方法の 1 つに、BizTalk® Server を使用する方法があります。BizTalk Server には、これまでに説明したすべての ESB 機能が標準で用意されています。

Software as a Service
ESB が企業に浸透しつつある間に、Web に別のビジネス トレンドも見えてきました。これは、今後数年のうちにエンタープライズ システムに必ず影響を及ぼすに違いありません。SaaS (Software as a Service: サービスとしてのソフトウェア) と呼ばれるこのトレンドの中心となっているのは、コンシューマが料金を支払って使用できる完全なアプリケーションやサービスを Web 上 (インターネット クラウドとも呼ばれる) で公開している企業です。SaaS を利用することにより、同様のソフトウェアの開発や管理に伴う面倒な作業を行わなくても済むうえ、そのコスト (設計、開発、運用、および保守のコスト) を節約することができます。こうしたソフトウェアの開発や管理には、本来ばく大な初期投資が必要です。
SaaS モデルでは、基本的に、特定の分野 (CRM、会計、給与支払、データ ストレージ、電子メールなど) の専門技術を持つ企業がホストしているソフトウェアに、コンシューマがリモートでアクセスできます (図 3 を参照)。SaaS のサービス プロバイダは、通常、特定のソフトウェア ニーズを満たす完全なソリューションを提供します。コンシューマは、システムのその部分を外部調達できることになります。サービス プロバイダはソフトウェアを継続的に管理し、コンシューマに使用料金を請求します。つまり、コンシューマはそれらのソフトウェア サービスをローカルで管理する必要がありません。
図 3 SaaS を利用して必要なソフトウェアを外部調達する (クリックすると拡大画像が表示されます)
使い勝手を良くし、対象コンシューマの幅を広げるため、SaaS プロバイダが提供するアプリケーションやサービスには、通常、標準的な Web プロトコルとデータ形式が採用されています。現在は、広く普及している HTTP や一般的な Web データ形式 (XML、RSS、JSON など) の採用が主流になっています。SaaS では必ずしもこれらを使用する必要はありませんが、プロバイダにおいては、対象顧客の幅を広げるために採用せざるを得ない状況にあります。
SaaS システム アーキテクチャに固有の外部依存関係を利用することに、どれほどのメリットがあるのか、との疑問を抱くアーキテクトの方もいらっしゃることでしょう。それは、接続性やサービス レベル契約 (SLA) への懸念から生じるものと言えますが、どこにいてもインターネットに接続できるようになった今日、Web 上でのソフトウェアの公開はほぼ市民権を得たように思われます。また、新しい可能性が開けるという点を考えると、メリットも非常に大きいように思います。

Internet Service Bus
マイクロソフトでは、ESB および SaaS という話題の概念を取り入れ、その最も魅力的な特性を Internet Service Bus (ISB) という新しい概念と統合しました。ISB モデルは、機能の面では ESB とほぼ同じです。ただし、ISB はより広範なインターネット スコープで利用できるので、標準、対象顧客、およびスケーラビリティの面では SaaS モデルに似ています。Microsoft® ISB は、簡単に言うと、企業による ESB インフラストラクチャの導入を容易にするものです。
ESB の機能はさまざまな企業にとって魅力的なものですが、今のところそのメリットを十分に享受しているのは規模の大きな企業だけのようです。ほとんどの場合、その理由は、ESB のような重要なインフラストラクチャの導入に伴う先行投資と財務上のリスクにあります。そのため、多くの企業が、最終的には独自の (よりコストがかかることが多い) カスタム システムの統合インフラストラクチャを構築しています。現在、これが BizTalk Server の採用を妨げる最も大きな障害の 1 つとなっています。
さらに、ESB を導入する力のある企業でも、自社の ESB とパートナーの ESB との通信を実現するのには苦労しています。同じ ESB インスタンスはありません。このことが、緩やかに結合された ESB パターンを採用する場合でさえも、企業間の統合を困難にしているのです。
マイクロソフトの ISB プラットフォームでは、主要なサービス バス コンポーネントをインターネット クラウドに配置して公開することで、そのコンポーネントを任意のプラットフォームで使用できるようにしています。マイクロソフトは、基本的に SaaS モデルを通じてサービス バスを提供しているため、どのような規模の企業でもバスを利用できます。ISB は、パブリッシュ/サブスクライブのアーキテクチャと、企業ファイアウォールやネットワーク アドレス変換 (NAT) を通過するために必要なメッセージング インフラストラクチャを提供します。さらに、図 4 に示すように、フェデレーション ID 管理機能と、Web 上にカスタム ビジネス プロセスをホストするためのワークフロー サービス層も、ISB で提供されます。
図 4 新しい Internet Service Bus での構築 (クリックすると拡大画像が表示されます)
マイクロソフトは ISB を実現するために積極的に取り組んでいます。その取り組みについては、BizTalk サービスの Web サイトでご覧いただけます (labs.biztalk.net を参照)。現時点の Community Technology Preview (CTP) には、すぐにお試しいただけるいくつかの基本的なサービスが用意されています。マイクロソフトでは、このイニシアチブを今後数年の間に発展させて、最新のさまざまな接続型アプリケーションの優れたビルディング ブロックを提供できる、リッチな通信機構を作り上げる予定です。
ただし、次の点にご注意ください。CTP 版として現時点で使用できるサービスは、評価とフィードバックの収集のためのものです。実稼働環境での使用は想定されていません。現時点では、マイクロソフトは品質を保証していません。また、実稼働環境での使用が可能になった場合の ISB の使用料金については、未発表です。

BizTalk サービス
BizTalk サービスは、Web 上の ISB コンポーネントの最初の実装です。現在、BizTalk サービスはいくつかのコア サービス (BizTalk Connectivity サービスや BizTalk Identity サービスなど) で構成されています。もう 1 つの主要サービスである BizTalk Workflow サービスは、近日中にリリースされます。マイクロソフトでは、その他のサービスを順次追加する予定であり、サードパーティからも追加のサービスが ISB にホストされる見込みです。
現時点で提供されているコア サービスの詳細について見ていきましょう。疎結合複合アプリケーションの作成の際に最も頭を悩ませる課題の 1 つが、ネットワーク レベルでのサービスの接続方法を管理することです。たとえば、ネットワーク境界に位置するサービスと、ファイアウォール内部に位置するサービスがあり、それらが相互に通信できなければならないようなケースもあります。また、サービスをビジネス パートナーに公開する必要がある場合に、パートナー側のサービスがパートナー独自のファイアウォールやその他のネットワーク デバイス (プロキシや NAT など) によるファイアウォールで保護されているケースも考えられます。
BizTalk Connectivity サービスは、ネットワークのトポロジや構成に関係なく 2 つのノード間で直接的または間接的に通信を行うためのメカニズムや、サービスの汎用名前付け規則を提供することで、こうした通信にかかわる課題の多くを単純化します。そのために、ネットワーク デバイスを通じて接続を安全に中継するための制御されたメカニズムを提供します。ただし、ノード間で直接接続を確立できる場合には、BizTalk Connectivity サービスは道を譲り、トラフィックの中継なしで接続できるようにします。
もちろん、この種類のコードを開発者が記述することもできますが、難しく煩雑な作業になる可能性があります。この機能を BizTalk サービスを通じて入手することの主なメリットは、こうしたコード (エンドポイントごとにカスタマイズされることも多い) を記述または管理する必要がなくなることです。開発者は、インフラストラクチャの問題にかかわるコーディングから解放され、ビジネス上の問題を解決するためのコードの記述に専念できるようになります。BizTalk Connectivity サービスは、その他にも URI (Uniform Resource Identifier) に基づくグローバル名前付け規則、シンプルなパブリッシュ/サブスクライブ メカニズム、マルチキャスト機能などの主要な機能も提供します。
BizTalk サービスのもう 1 つのコア パーツが BizTalk Identity サービスです。これは、WS-Trust 標準に準拠した、パブリックにアクセス可能なセキュリティ トークン サービス (STS) です。WS-Trust 標準は、当事者間の信頼関係に基づいてセキュリティをネゴシエートするための相互運用性を備えています。たとえば、一方の当事者はクライアントを認証し、クライアントに関する要求セットを含むトークンを発行できます。そのトークンは、トークンを発行した元の当事者を信頼するもう一方の当事者に安全に送信されます。このアプローチにより、組織の境界を越えた重要な ID 情報のフェデレーションが可能になります。
BizTalk Identity サービスは、他の機能 (BizTalk Connectivity サービスなど) を一切利用していない場合でも、サードパーティの ID および認証管理サービスとして利用可能です。ただし、他の BizTalk サービスを使用している場合は、ユーザーの認証と承認に BizTalk Identity サービスが必ず使用されます。
BizTalk Connectivity サービスを使用している場合、クライアントとサービスは両方とも、ユーザー名/パスワード、クライアント証明書、マネージ カードのいずれかを使用して BizTalk Identity サービスで認証されます。認証後、一連の承認規則が処理されて、BizTalk Connectivity サービスに提供される新しいトークンが発行されます。BizTalk サービスの Web サイトでは、承認規則の管理用のユーザー インターフェイスと、いくつかのプログラミング API (RESTful インターフェイスなど) が提供されています。
BizTalk Workflow サービスは、まだ一般向けにはリリースされていません。ただし、BizTalk サービスの今後のリリースで、Windows® Workflow Foundation (WF) に基づいたワークフロー サービスを ISB でホストする機能が提供される予定です。ワークフローは、特定の URI の ISB で受信されたメッセージに基づいてアクティブ化されます。現時点では、これらの情報しか公開されていません。

BizTalk サービス SDK
BizTalk サービス SDK は、biztalk.net から無料でダウンロードできます。このサイトでは、ISB に関するプログラミングを開始するために必要な情報が提供されています。プログラミングを始めるにあたって、BizTalk サービス SDK をインストールし、BizTalk サービスのサイトでユーザー アカウントを作成する必要があります。BizTalk サービスは Windows Communication Foundation (WCF) を基に構築されています。この SDK は、Microsoft .NET Framework 3.0 に基づくアセンブリ セットです。Microsoft .NET Framework 3.0 により、WCF プログラミング モデルを通じて ISB を利用できるようになります。
BizTalk サービス SDK の大部分は System.ServiceBus アセンブリに含まれます。System.ServiceBus では、RelayBinding という名前の新しいバインドを定義するために標準の WCF 拡張ポイントを使用します。WCF をご存じない方のために一応説明しておくと、バインドとは、サービス エンドポイントによって公開または使用される通信の種類を定めるものです。バインドは、メッセージを送受信するための通信層 (チャネル スタックと呼ばれる) を作成するために、WCF ランタイムによって使用されます。チャネル スタックのオブジェクトは、ネットワーク通信を実行し、特定のエンドポイントに対するセキュリティやその他のプロトコルの実装方法を指定します。
リスナの側では、RelayBinding を使用してエンドポイントを公開できます。このエンドポイントには、BizTalk Connectivity サービスでサポートされているグローバル URI を使用してアクセス可能です。RelayBinding を使用してエンドポイントが開かれると、その URI は BizTalk Connectivity サービスに登録されます。それ以降、承認されたクライアントは、同様に構成されたクライアントを使用してそのグローバル URI にメッセージを送信できるようになります。そして BizTalk Connectivity サービスは、それら 2 つのエンドポイント間での通信に使用されるコンジットとなります。

一般的な WCF アプリケーション
それでは、簡単な例を挙げて詳しく見ていきましょう。ある会社で、リッチ クライアント アプリケーションから呼び出される WCF サービスを内部ネットワーク上で公開しているとします。クライアント アプリケーションは、注文を処理するために営業担当者によって使用されます。アプリケーションがサービスを呼び出すと、サービスは注文の処理に必要なバックエンド プロセスを開始します。
サービスには、TCP/IP を介した高速接続を可能にする NetTcpBinding を使用して、単一のエンドポイントが構成されています。ファイアウォール内部で処理されるサービスの場合、通常は NetTcpBinding が最適です。
標準の ServiceHost を使用してエンドポイントを構成し、サービスを開始するコードを次に示します。
ServiceHost sh = new ServiceHost(typeof(SalesService));
sh.AddServiceEndpoint(typeof(ISalesService), 
  new NetTcpBinding(),
  "net.tcp://salesservicehost/SalesService");

sh.Open();
...
これが標準的な WCF コードです。サービス実装は SalesService 型であり、コントラクトは ISalesService です。AddServiceEndpoint が呼び出されたときに作成される ServiceEndpoint は、NetTcpBinding を使用し、そのアドレスは net.tcp://salesservicehost/SalesService になります。
この方法でエンドポイントをハードコーディングする代わりに、アプリケーションの構成ファイルでエンドポイントを構成することもできます (この方法が一般的です)。ただし、このサンプルではすべての要素がコードに含まれているので、こちらの方が理解しやすいと言えます。次に、注文を処理するために SalesService を呼び出すクライアント アプリケーションのサンプルを示します。
static void MakeSale(SaleData sd) {
  EndpointAddress ea = new EndpointAddress(
    "net.tcp://salesservicehost/SalesService");
  ChannelFactory<ISalesService> cf = 
    new ChannelFactory<ISalesService>(new NetTcpBinding(), ea);
  ISalesService service = cf.CreateChannel();
  service.EnterSale(sd);
}
やがて、営業部の移動性が高まってきたとしましょう。営業担当者からは、外出先で任意のネットワーク (その一部は仮想プライベート ネットワーク (VPN) 接続が不可) に接続しているときに、社内のサービスに接続して注文を処理することができないという報告が入るようになりました。
BizTalk サービスを利用すると、この問題を解決できます。BizTalk Connectivity サービスを介して SalesService を公開する方法を見てみましょう。
ServiceHost sh = new ServiceHost(typeof(SalesService));
sh.AddServiceEndpoint(typeof(ISalesService), 
  new RelayBinding(),
  "sb://connect.biztalk.net/services/contososervices/SalesService");

sh.Open();
...
ご覧のように、BizTalk サービスを通じてサービスを公開するには、1 行のコード (ServiceHost.AddServiceEndpoint の呼び出し) を変更するだけで済みます。NetTcpBinding の代わりに RelayBinding を使用してください。RelayBinding により、このエンドポイントは BizTalk Connectivity サービスを通じて指定の URI で外部に公開されます。そのアドレスに送信されるメッセージは、ローカルの SalesService インスタンスに中継されます。
URI の形式に注目してください。URI は "sb" スキームから始まり、その後に BizTalk サービスのホスト名と "services" が続いています。その後ろには BizTalk サービスの ID (設定済みのアカウント名) を追加します。この場合は contososervices です。さらに、URI を一意にするために任意の文字列を追加します。ここではシンプルに SalesService を追加しました。
ServiceHost.Open を呼び出すと、サービス ID を認証して特定の URI でのリッスンを承認するために、RelayBinding によって WCF と BizTalk Identity サービスの通信が開始されます。このときの既定の動作では、Windows CardSpace™ セレクタが表示され、ユーザーはサービスの ID を表すカードを選択するよう求められます。
ほとんどのサービスでは、このように認証時に UI が表示されるプロセスは許容されません。サービスは一般にヘッドレス環境で実行され、コンピュータにログインできないからです。ただし、この問題は数行のコードを記述することで回避できます。この点については後ほど説明することにして、先に進みましょう。ここではまず、SalesService がリッスンを開始できるようにするカードを選択します。BizTalk Identity サービスを使用し、特定の URI でのリッスンを許可する ID を管理できます。
次に、クライアントを更新して、クライアントが BizTalk サービス エンドポイントを使用できるようにする方法について見ていきましょう。
static void MakeSaleISB(SaleData sd) {
  string uri =   
    "sb://connect.biztalk.net/services/contososervices/SalesService";
  ChannelFactory<ISalesService> cf = new ChannelFactory<ISalesService>(
    new RelayBinding(), new EndpointAddress(uri));
  ISalesService service = cf.CreateChannel();
  service.EnterSale(sd);
}
RelayBinding を使用していることとサービス バス (sb://...) の URI を指定していることを除き、クライアントとサービスはまったく同じであることに注目してください。既定では、クライアントにも Windows CardSpace セレクタが表示されます。ここでクライアントは ID を選択でき、その ID は認証と承認のために BizTalk Identity サービスに送信されます。クライアントによる指定の URI へのメッセージの送信が承認されると、BizTalk Identity サービスはその事実を示すトークンを返します。そのトークンは、証拠として BizTalk Connectivity サービスに渡されます。
このシナリオでは対話型のクライアント アプリケーションを使用しているため、Windows CardSpace セレクタを表示しても問題ありません。ここでも、BizTalk Identity サービスを使用することで、特定の URI への送信を許可するクライアント ID を管理できます。
BizTalk Connectivity サービスは、承認された送信元から着信メッセージを受信すると、そのメッセージをローカルで実行されている SalesService のインスタンスに単純に中継します。そのしくみについては、今後変更される可能性の高い実装の細部なので特に注目する必要はありません。ただし、バックグラウンドでは、RelayBinding は WCF の TcpTransport を使用して BizTalk Connectivity サービスに接続しています。メッセージを中継するとき、BizTalk Connectivity サービスでは既存の TCP 接続をトンネルしてローカル サービス インスタンスに送信できます。
なぜこれほどシンプルなのでしょうか。それは、BizTalk Connectivity サービスでは標準の WCF 拡張ポイントを活用して、新しい RelayBinding 内部にクライアントとサービスの両方の接続および中継ロジックをカプセル化するためです。バインドを変更するだけで基本的な通信方法を変更できるという点は (完全に構成で行うことが可能)、WCF プログラミング モデルの採用により得られる真のメリットの 1 つです。

中継される接続のオプション
RelayBinding オブジェクトの重要なプロパティの 1 つが、ConnectionMode です。プロパティの型は RelayedConnectionMode という列挙型です。これを設定することで、BizTalk Connectivity サービスとの接続をどのように行うかを指定します。BizTalk Connectivity サービスでは、送信側と受信側の間で多数の通信モードを使用できます。そのため、個別の通信シナリオに大きな柔軟性がもたらされます (図 5 を参照)。
ConnectionMode の値 説明
RelayedOneWay 一方向の操作だけを受信または送信するように接続を設定します。この設定を使用するには、IsOneWay プロパティが true に設定されている OperationContractAttribute が、サービス コントラクトのすべてのメソッドに含まれている必要があります。
RelayedDuplex 要求/応答コントラクト (双方向コントラクトを含む) をサポートするように接続を設定します。
RelayedDuplexSession RelayedDuplex と同じですが、WS-ReliableMessaging を使用するように構成します。
DirectDuplexSession RelayedDuplexSession と同じですが、それを最適化したモードと言えます。送信側と受信側の最初の接続では BizTalk Connectivity サービスを使用しますが、その後、2 つのノード間の直接接続のブリッジを試みます (可能な場合)。直接接続を確立できる場合、送信側と受信側は BizTalk Connectivity サービスを間に挟まずに通信を行うようになります。直接接続を確立できない場合は、BizTalk Connectivity サービスが引き続き通信を中継します。
RelayedMulticast パブリッシュ/サブスクライブ機能を提供するように接続を設定します。このモードを使用する場合は、同じアドレスを使用して複数のリスナを登録できます。この設定を使用するには、IsOneWay プロパティが true に設定されている OperationContractAttribute が、サービス コントラクトのすべてのメソッドに含まれている必要があります。
RelayedHttp ローカル ネットワーク上のコンピュータで実行されているサービス (通常はインターネットを通じてアクセスできないサービスも含む) にメッセージを中継する HTTP エンドポイントを、BizTalk サービスを介して公開するように接続を設定します。
RelayedOneWay は一方向のメッセージング シナリオ向けのモードです。したがって、IsOneWay=true とマークされた操作でのみ使用できます。一方、RelayedDuplex は、双方向コントラクトの含まれる要求/応答シナリオ向けのモードです。RelayedDuplexSession は RelayedDuplex とよく似ていますが、チャネル スタック内の信頼性の高いメッセージングも有効になります。これは既定の接続モードなので、前の例で実際に使用しています。また、DirectDuplexSession モードは、可能であれば送信側と受信側の直接接続のブリッジを試みるという点で、RelayedDuplexSession を最適化したモードと言えます。直接接続を確立できない場合は、トラフィックを中継します。
ここからは、最後の 2 つの接続モードについて詳細に見ていきましょう。まず、RelayedMulticast を設定すると、WCF 上でのパブリッシュ/サブスクライブが有効になります。これは、どの組み込み WCF バインドでも実現されない通信パターンです。また、RelayedHttp を設定すると、企業のファイアウォール内部から、または NAT の背後から、HTTP ベースのエンドポイントを公開できるようになります。Web サービスの登場以来、開発者たちはこの状態を実現するために懸命に取り組んできました。
BizTalk Connectivity サービスでは、最初のリスナによって RelayedMulticast が指定されると、複数のリスナが自身を URI に登録できます。その同じ URI でリッスンしているエンドポイントを含む各 ServiceHost は、暗黙的にサブスクライバとなります。クライアントがその URI 宛てにメッセージを送信すると、そのメッセージは、現在サブスクライブしているすべてのサービス エンドポイントに配信されます。RelayedMulticast を使用する場合の唯一の制約は、RelayedOneWay と同様に、すべての操作が IsOneWay=true とマークされている必要があることです。
前の販売アプリケーションに戻りましょう。この会社では、さまざまな販売品目の価格を日中定期的に更新すると仮定します。全営業担当者がすぐに把握できるように、新しい価格をブロードキャストします。そのためには、各クライアント アプリケーションで、ServiceHost を開始し、RelayBinding を使用して (ConnectionMode は RelayMulticast に設定)、同じ URI をリッスンできる必要があります。
ServiceHost sh = new ServiceHost(typeof(PriceUpdateService));
sh.AddServiceEndpoint(typeof(IPriceUpdateService),
  new RelayBinding(RelayConnectionMode.RelayedMulticast),
  "sb://connect.biztalk.net/services/contososervices/priceupdate");
sh.Open();
...
アプリケーションが起動すると、各クライアントではこのコードが実行されます。そのため、すべてのクライアント アプリケーションが sb://connect.biztalk.net/services/contososervices/clientupdate に送信されるメッセージのサブスクライバとなります。これで、各クライアントはこのコントラクトと URI のためのサブスクライブ サービスとなりました。このシナリオでは、次に示すように、バックエンド システムが WCF クライアントの役割を果たし、すべてのサブスクライバにメッセージをブロードキャスト (パブリッシュ) します。
static void DoPriceUpdate(PriceUpdate pu) {
  EndpointAddress ea = new EndpointAddress(
    "sb://connect.biztalk.net/services/contososervices/priceupdate");
  ChannelFactory<IPriceUpdateService> cf = 
    new ChannelFactory<IPriceUpdateService>(
      new RelayBinding(RelayConnectionMode.RelayedMulticast), ea);
  IPriceUpdateService service = cf.CreateChannel();
  service.UpdatePrice(pu);
}
UpdatePrice が呼び出されると、PriceUpdate メッセージが BizTalk Connectivity サービスに送信されます。BizTalk Connectivity サービスは、同じ URI に現在サブスクライブしているすべてのサービスにそのメッセージを中継します。

RelayedHttp を使用してファイアウォールを通過する
RelayedHttp モードでは、ローカル ネットワーク上で実行されている HTTP サービスを選び、それを BizTalk Connectivity サービスを通じてパブリックな Web 上に HTTP 経由で公開できます。通常はネットワーク外部から直接アクセスできないサービスであっても公開可能です。この機能は、.NET Framework 3.5 で新たに導入された WCF Web プログラミング モデルと共に使用する場合に、特に役立ちます。
この新しい Web プログラミング モデルでは、WCF を使用して RESTful Web サービスをより簡単に実装できます。また、このプログラミング モデルには、WCF サービスと、今日の Web でよく使用されている既存の RSS/Atom および AJAX インフラストラクチャを簡単に統合する機能が用意されています。BizTalk サービスには .NET Framework 3.5 は必要ありませんが、こうした新しい WCF 機能が導入されている .NET Framework 3.5 をインストールすると、RelayedHttp モードをいっそう活用できるようになります。
販売アプリケーションに戻りましょう。販売担当者は、リッチ クライアント アプリケーションを実行していない場合でも、最新の価格情報を受け取る必要がある場合があります。頻繁に更新されるデータを公開するための興味深い手段の 1 つに、Web フィードがあります。これは、よく知られた XML 形式 (RSS や Atom など) のデータを、フィードの使用方法を把握しているアプリケーションに返す HTTP エンドポイントです。フィード リーダー (ユーザーが使用する UI に Web フィードを集めるプログラムの一般的な名称) を使用して、設定したスケジュールで Web フィードをポーリングし、新しいコンテンツを取得できます。これにより、エンド ユーザーは、サイトにアクセスしなくてもフィード リーダーを通じて更新情報を確認できるようになります。
WCF Web プログラミング モデルを利用すると、価格の更新データを公開する Web フィードを簡単に作成できます。まず必要なのは、HTTP の呼び出しを有効にするための新しい WCF 属性を使用するコントラクトです。これらの属性は、SOAP Action ヘッダーではなく URI に基づいて、サービスのメソッドに着信 HTTP 要求をルーティングする方法を、WCF メッセージング層に伝えます。次に例を示します。
[ServiceContract]
public interface IPriceUpdateFeed {
  [OperationContract()]
  [WebGet(UriTemplate = "*")]
  Atom10FeedFormatter GetPriceUpdate();
}
この場合、WebGetAttribute は、HTTP GET 要求がサービスに到着するたびにこのメソッドを呼び出すよう WCF に指示します (常に HTTP POST を使用する SOAP 要求とは対照的です)。
WebGetAttribute の UriTemplate プロパティにも注意してください。このプロパティは、着信要求の URI に基づいて別のメソッドに着信メッセージをルーティングする方法を WCF に正確に指示します。この例では、すべての GET 要求をこの特定のメソッドにルーティングするよう指示する、ワイルドカード テンプレート ("*") を使用しています。サービスには、それぞれ異なる UriTemplate を処理する複数のメソッドを簡単に構成できます。また、GET 以外の HTTP 動詞 (POST、PUT、DELETE、HEAD など) に応答するようにする場合は、WebInvokeAttribute を使用できます。
このコントラクトでもう 1 つ注意しなければならないのは、メソッドの戻り値の型です。WCF Web プログラミング モデルには、今日の標準的なフィード形式のデータを生成できる、特別に作成された新しい型が用意されています。現在サポートされている 2 つの主要な形式は、Atom と RSS です。この記事の例では、Atom 形式を使用します。
図 6 に、Atom シンジケーション フィードを生成する GetPriceUpdate 操作のシンプルな実装を示します。この実装では、論理フィードを生成するための新しい SyndicationFeed API を使用しています。これは、適切な XML 形式のデータを生成するために Atom10FeedFormatter オブジェクトでラップされて返されます。
public Atom10FeedFormatter GetPriceUpdate() {
  SyndicationFeed feed = new SyndicationFeed("Product Update Feed",
    "", null);
  List<SyndicationItem> items = new List<SyndicationItem>();
  feed.Items = items;
  IEnumerable<Product> products = GetUpdatedProducts();
  string iText = "Product update for {0}. Old price={1}. New Price={2}";
  foreach (var product in products) {
    items.Add(new SyndicationItem("Product update for " + product.Name,
      String.Format(iText, product.Name, product.OldUnitPrice,   
      product.UnitPrice),
      null, 
      product.Name, 
      product.UpdatedTime));
  }
  return new Atom10FeedFormatter(feed);
}
ここで、これらの要求をリッスンするようにエンドポイントを構成する必要があります。WCF 3.5 には、エンドポイントを非常に簡単に構成できる新しいバインド クラスが用意されています。WebHttpBinding クラスは、SOAP メッセージをサポートしない RESTful チャネル スタックの作成に関する詳細情報をカプセル化します。このクラスでは、単純に HTTP トランスポートと WCF のテキストベース メッセージ エンコーダ (エンコーダのメッセージ バージョンは None に設定) を使用します。次に、新しいエンドポイントをフックして実行するために必要なコードを示します。
ServiceEndpoint se = 
  sh.AddServiceEndpoint(typeof(IPriceUpdateFeed), 
  new WebHttpBinding(), "http://localhost:8099/ProductFeed");
se.Behaviors.Add(new WebHttpBehavior());
...
WebHttpBehavior のインスタンスを使用して WebHttpBinding エンドポイントが構成されていることに注目してください。このインスタンスは、必要な HTTP ベースのディスパッチ ロジックをランタイムに挿入します。この新しいエンドポイントを構成したうえで ServiceHost を実行すると、サービスが localhost:8099/ProductFeed でリッスンしている HTTP URI を参照して Atom フィードを確認できるようになります。
ここで、内部ネットワークに接続していない営業担当者にこのフィードを公開する必要があるとしましょう。このとき、このコンピュータをファイアウォール越しに公開する代わりに、単純に BizTalk Connectivity サービスを使用して、HTTP トラフィックをローカル サービスに中継することができます。そのためには、次に示すように RelayBinding を使用して ConnectionMode を RelayedHttp に指定し、別のエンドポイントを追加します。
ServiceEndpoint se = 
  sh.AddServiceEndpoint(typeof(IPriceUpdateFeed),
  new RelayBinding(RelayConnectionMode.RelayedHTTP),
  "http://connect.biztalk.net/services/contososervices/ProductFeed");
se.Behaviors.Add(new WebHttpBehavior());
...
これで、サービスはパブリックな Web に安全に公開されました。ただし、ロジックは内部サーバーにホストされています。図 7 は、インターネットでアクセスできるパブリック URI を通じてこのフィードが公開されていることを表します。もちろん、表示されるフィードはまったく同じです。外出中の営業担当者はこのフィードをサブスクライブし、VPN、ファイアウォール、およびネットワークの問題に煩わされることなく、更新情報を入手できます。
図 7 BizTalk Connectivity サービスを通じた HTTP サービスの公開 (クリックすると拡大画像が表示されます)

Identity サービスを構成する
RelayBinding で使用している接続モードに関係なく、リスナ (サービス) と送信側 (クライアント) はどちらも BizTalk Identity サービスで認証および承認される必要があります。認証とは、最初の要求セットが提供されたときにクライアントまたは要求側を認証するプロセスのことです。承認とは、その最初の要求セットにユーザー定義の承認規則のセットを適用するプロセスのことです。
承認規則によって、一連の要求変換を通じて単純に新しい要求セットが生成されます (各規則により入力要求セットが出力要求セットにマッピングされます)。入力要求の初期セットは、要求側によって BizTalk Identity サービスに送信される要求です。現時点の BizTalk Identity サービスは、ユーザー名/パスワード、クライアント証明書、およびマネージ カードの 3 種類の初期要求セットをサポートしています。ユーザー名/パスワードの場合は、ユーザー名が初期要求で、パスワードがその要求の証拠です。
BizTalk Identity サービスでは、出力要求を生成するために、まずユーザー名の要求を使用して承認規則の処理を開始します。生成された新しい要求は他の規則の入力要求の役割を果たすため、規則のチェーンを形成できます。出力要求の最後のセットは、BizTalk Identity サービスから返されるトークンに含まれるセットです。BizTalk Connectivity サービスへのアクセスを試みる際には、特定の出力要求を送信する必要があります。
証明書を使用して BizTalk Identity サービスを構成し、サービスによって生成されるトークンを保護することもできます。証明書を構成すると、要求側に提供されるトークンは証明書の公開キーで暗号化されます。したがって、トークンをより安全に送信できるうえ、転送中にクライアントの改ざんを受ける可能性を抑えることができます。
これらの承認規則は、いくつかの方法で構成できます。その 1 つが、BizTalk サービスの Web サイトに表示される UI を使用する方法です (図 8 を参照)。また、SDK に含まれている ID 管理 API を使用してプログラミングする方法もあります。最近、そのインターフェイスの RESTful バージョンもリリースされました。
図 8 BizTalk サービス Web サイトの要求マッピング用 UI (クリックすると拡大画像が表示されます)
承認規則を構成する際には、BizTalk Identity サービスの使用方法について考える必要があります。繰り返して言いますが、BizTalk Identity サービスは、一般的な STS としても、BizTalk Connectivity サービスのアクセス制御メカニズムとしても使用できます。
BizTalk Identity サービスを一般的な STS として使用する場合は、着信ユーザー名入力要求を任意の出力要求にマッピングできます。出力要求は、他の当事者に送信できる結果のトークンに含められます。サービスをこのように使用する場合は、入力要求がユーザー名である規則が少なくとも 1 つ必要です。新しい出力要求に基づいてカスケードする規則を追加できます。たとえば、ユーザー名の規則によって生成された出力要求を、別の出力要求に対する入力要求として利用することができます。そのため、任意の出力要求セットを構成可能です。詳細な例については、BizTalk サービスの SDK に含まれる AccessControl のサンプルを参照してください。
BizTalk Connectivity サービスを使用して認証を行うには、BizTalk Identity サービスにいくつかの特定の規則を構成していることを確認する必要があります。前に述べたとおり、入力要求がユーザー名である規則が少なくとも 1 つ必要です。また、カスケードする規則を追加することもできます。
ただし、BizTalk Connectivity サービスが一意である場合は、Resource#Operation 出力要求 (Resource はサービスのリッスン URI、Operation は Listen と Send のどちらか) が最後のトークンに含まれている必要があります。{URI}#Listen の場合、ユーザーは指定の URI でサービス エンドポイントのリッスンを開始できます。一方、{URI}#Send の場合は、ユーザーは指定の URI にメッセージを送信できます。

カスタム トークン プロバイダ
前の部分で説明したように、サーバーによるリッスンの開始時にサーバー アプリケーションで対話型のログイン画面 (Windows CardSpace セレクタなど) を表示するのは、通常は適切ではありません。こうした画面が表示されるのは、ITokenProvider インターフェイスを実装するオブジェクトを含む RelayBinding が各エンドポイントに使用されているためです。このインターフェイスの既定の実装は、CardspaceTokenProvider です。これを設定すると、BizTalk Connectivity サービスとの接続が確立された際に Windows CardSpace セレクタが表示されます。
SDK には、CardspaceTokenProvider のほかにも ITokenProvider のいくつかの実装が含まれています。UsernameTokenProvider を設定すると、登録されているユーザー名とパスワードを使用して BizTalk Identity サービスからトークンが取得されます。AutomaticRenewalTokenProvider を設定すると Windows CardSpace セレクタが表示されるようになりますが、現在のトークンの期限が切れる前に新しいトークンが自動的に取得されるため、エンドポイントの構成の手間が省けます。これらの両実装も、既定の CardspaceTokenProvider の代わりにクライアントまたはサービス エンドポイントに追加できるエンドポイント動作です。
この記事のサービスでは、次に示すように、ServiceHost.Open の呼び出しの前に UsernameTokenProvider をエンドポイントに構成することで、対話型のログイン画面が表示されないようにすることができます。
ServiceHost sh = new ServiceHost(typeof(SalesService));
ServiceEndpoint se = sh.AddServiceEndpoint(typeof(ISalesService),
  new RelayBinding(),
  "sb://connect.biztalk.net/services/contososervices/SalesService");
UsernameToken token = new UsernameTokenProvider("someusername", 
  "somepassword");
se.Behaviors.Add(token);
sh.Open();
...
これで、いつサービス処理が開始されても、BizTalk Identity サービスを使用して、人の介在なしに自動的に認証が行われるようになりました。ITokenProvider のその他の実装も、エンドポイント動作として追加するだけで RelayBinding エンドポイントに構成することができます (SDK に含まれる TokenProvider 基本クラスは、ITokenProvider と IEndpointBehavior の両方を実装します)。

使用を開始する前に
BizTalk サービスの使用を開始するには、まず labs.biztalk.net にアクセスしてアカウントを作成してください。.NET Framework 3.0 がインストールされていることを確認する必要があります。確認後、BizTalk サービス SDK をダウンロードしてインストールできます。アカウントを作成し、SDK をお使いのコンピュータにインストールしたら、この記事で紹介したサンプルを再作成できます。当然のことながら、URI 中のアカウント名を "contoso" からご自身のアカウント名に変更する必要があります。また、SDK には参考用にその他のサンプルもいくつか用意されており、ここで説明した概念を理解するうえで役立ちます。使い始めて何らかの疑問が生じた場合は、BizTalk サービス サイトの FAQ を確認してください。健闘をお祈りします。

Jon Flanders は、フリーのコンサルタント、講演者、Pluralsight のトレーナーという 3 つの肩書きを持っています。彼は、BizTalk Server、Windows Workflow Foundation、および Windows Communication Foundation のスペシャリストです。Jon のブログのアドレスは masteringbiztalk.com/blogs/jon です。

Aaron Skonnard は、Microsoft .NET の第一のトレーニング プロバイダである Pluralsight の共同設立者の 1 人です。Aaron は、Pluralsight が提供する Applied Windows Communication Foundation、Applied BizTalk Server 2006、および Applied Web Services の各コースのほか、多数の書籍、ホワイト ペーパー、および記事を執筆しています。彼のブログのアドレスは pluralsight.com/aaron です。

Page view tracker