例: SOA モデルの例

問題記述 ページの先頭へ

この例では、PoS (Point-of-Sale) 端末で使用されている一部の機能をサービスとして再実装することにした、小売業者の問題を検討します。 現在、取引アプリケーション は、きわめて緊密に結合されたコンポーネントを持つモノリシック・アプリケーションとして開発されていますが、一部のコンポーネントは店舗内サーバー (ISS) 上に存在し、また一部の要求が ISS から全社的に中央管理しているサーバーに転送されることもあります。問題は、 コンポーネントが緊密に結合されていて、そのコンポーネントの開発とコンポーネント間の接続に独自のプロトコルとテクノロジーが使用されているため、店舗インフラストラクチャー全般、具体的には取引アプリケーションの保守が難しくなっていることです。

前の世代の店舗システムでは、PoS 端末に独自の低機能マシンが使用され、店舗外だけでなく店舗内でも帯域幅の制限がありました。こうした制限の多くはもう解消されています。 このことと、エンタープライズ・バックエンド・システム内は既にサービス指向アーキテクチャーに移行していることを考慮して、 ISS と中央サーバーが提供する機能の一部をサービスとして取引アプリケーションに公開することが決定されました。

プロジェクトの範囲と目標 ページの先頭へ

初めに考慮すべき機能が選択されました。現在、複数のデータ・ストアに情報を照会するロジックが取引アプリケーションに 必要とされており、その点で 1 つの共通パターンが共有されているからです。 したがって提案されたサービスでは、共通のインターフェースを提供するだけでなく、取引アプリケーションが明示的なデータ・ロケーション を知っていたり、複数のプロトコルを扱ったりしなくてもすむようになっています。 これらのサービスへのアクセスには、取引アプリケーションから ISS サービスへは RMI を介して、ISS から中央サービスへは SOAP over JMS を使用して行われます。

サービスの識別 ページの先頭へ

以下は、小売業者の IT 組織のメンバーと、サービス指向のソリューションの開発の専門家として呼ばれた外部コンサルタントから成るアーキテクチャー・チームが取り組んだ手順の概要を述べています。以下の手順は推奨される一連の RUP アクティビティーを示すものではなく、実際のプロジェクトのアクティビティーをまとめたものです。

このプロジェクトは、現在存在する機能の技術的な実装を改善するためのもので、 ビジネス・モデリングまたは分析のいずれかに費やす多くの時間は含まれていません。これは、 元の取引アプリケーションのために作成されたモデルを再利用できるからです。 現在のモデルのセット (下の図の左側にある) は以下に示す構造に従います。RUP ユースケース・モデル、取引アプリケーションの共通コンポーネントの分析モデル、詳細設計モデル、そして最後に Java 開発チームの実装モデルのセットです。

本文で説明されている図。

サービス・モデルは、独自の実装モデルを使用して、分析モデルをサービスのセットとして洗練したものとして導入されます (上図の右側)。 これで取引アプリケーションの設計を、これらの共通サービスの使用を示すように変更できます。 また、取引アプリケーションとサービス Java モデルの間の関係も示されます。

サービス・モデルの作成

店舗サポートのサービス・モデルは、下図のように、ソフトウェア・サービス用の UML プロファイルと (Rational Software Architect に含まれる) テンプレート・モデルに従って作成されました。 モデルは、上記のように、分析モデルを洗練したものとして識別されました。 見て分かるとおり、構造は、テンプレートによって推奨されたビューの間の依存関係を表す総括ダイアグラムで表されます。

本文で説明されている図。

ビュー・パッケージの隣にあるダイアグラム・リンクから、簡単にモデルへとナビゲートできます。それぞれ、リンク先以降のセクションの説明に従って作成できます。

詳しくは、ツール・メンター『RSA 内のサービス・モデルの作成』を参照してください。

サービス・パーティションの識別 (局所性)

上記の問題の説明から明らかなことですが、システムのパーティショニングには数多くの方法があります。例えば、在庫管理、修理/保証管理、PoS 操作 (価格検索、顧客など) を表すパーティションを導入することができます。 ただし、これはアーキテクトにとって主な関心事ではありません。モデルに追加されたパーティションは、店舗またはエンタープライズ・レベルで提供されたサービスの論理的な局所性を表しています。

本文で説明されている図。

「論理パーティション」というときは、店舗サービス・パーティションが、 店舗レベルでインスタンス化されたサービスのセットを含んでいることを指しており、 これらのサービスの物理的配置 (単一サーバー、クラスターなど) については触れていません。 . これらの論理パーティションは、アーキテクトがソリューションの重大な側面を表せるように提供されています。

また、上図で、 アーキテクトは追加要素である取引アプリケーションそれ自体を導入することで、アプリケーションとサービス間の通信の記述を可能にしていることに注意してください。 取引アプリケーションは、ステレオタイプ「サービス・コンシューマー」を持つ UML 2.0 コンポーネントです。

詳しくは、概念『ソリューションのパーティショニング』を参照してください。

既存の機能の分析

次のステップでは、取引アプリケーションの現在の実装を分析して、上記の問題に関する説明で確認されたデータベース・アクセスの詳細を調べます。 そこで、以下の表が作成されました (ここには顧客と在庫の検索の詳細のみが含まれてます)。
 
名前 テクノロジー 入力 出力 コメント
sp_get_custlist_by_phone SQL サーバー・ストアード・プロシージャー phonenum (10 文字) リスト
custid (ID)
custname (40 文字)
このストアード・プロシージャーは、電話番号から顧客の詳細のリストを戻します。このリストは顧客に選択できるように表示される場合があります。 sp_get_cust_details 呼び出しを使用して、1 件の顧客レコードが戻されます。
sp_get_cust_details SQL サーバー・ストアード・プロシージャー custid (ID) 顧客レコード 顧客の詳細 (名前、住所、連絡先情報など) が戻されます。
CUST_QUERY IBM MQSeries phonenum (10 文字)
return-queue-name (120 文字)
correlation-id (120 文字)
N/A アプリケーションはこのキュー内に照会する顧客の詳細を置き、 メッセージはセンターへ配信され、そこでサーバーが応答メッセージを指定されたリターン・キューに入れます。
<return-queue-name> IBM MQSeries N/A correlation-id (120 文字)
顧客レコードのリスト
顧客レコードを戻す際、応答を元の要求と関連付けられるように、 リターン・メッセージに相関 ID も含まれます。 これにより、店舗内サーバーがすべての端末に対する単一のリターン・キューを持つことが可能になり、 端末はその相関 ID を使用して応答メッセージがあるかどうかキューを照会します。
sp_get_invstate_for_sku SQL サーバー・ストアード・プロシージャー sku (13 文字) 在庫レコード
INVENTORY_QUERY IBM MQSeries sku (13 文字)
return-queue-name (120 文字)
correlation-id (120 文字)
N/A
<return-queue-name> IBM MQSeries N/A 在庫レコード

ごのように、これらのエントリーは既存の実装を表します。これは新しい実装と置き換えられますが、その目的と機能は維持されます。

初期サービス仕様の開発

アクティビティー『サービスの識別』には、ソリューションをサポートするために必要なサービスと、 サービスに対する操作を識別するための多くの技法を導入されています。 この例では、レガシー更改という形式、既存機能のサービス・モデルへの変換、そして特にサービス実装のテクノロジーについて説明します。 これを行う際の最初の局面は、上記の機能を実装するサービスのための契約を提供するサービス仕様 のセットを開発することです。 下図は、この段階で作成され、概要で説明したサービスのそれぞれに対応する、現在は空の 3 つのサービス仕様を示します。

本文で説明されている図。

次に、サービスについて可能な使用パターンを分析します。例えば、実際には 2 つのサービス (1 つは店舗内、1 つはエンタープライズ) を持ち、データベース・アクセスとエンタープライズ・アクセスのロジックを、両方とも店舗内サービスにカプセル化することができます。 または、ロジックをカプセル化し、2 つの同一のサービス (1 つはローカル・データベース・アクセスをカプセル化し、もう 1つはエンタープライズでカプセル化する) を呼び出す、ファサード・サービスを店舗内に持つこともできます。 2 番目の選択肢は、2 つの店舗にアクセスするロジックを変更する場合には柔軟性がありますが、 比較的単純な機能ではオーバーヘッドと通信コストが発生します。 したがって、顧客検索と在庫検索の場合は、最初のオプションが選択されました。 サービスとサービス・プロバイダーの分散の詳細がまだ決定されていないので、サービスの識別は、サービス仕様にのみ焦点を当てればより一層効率的です。

これらのサービスのロールと責務を識別するために、サービス・コラボレーション と、顧客検索のためのサービスの構成を表す UML 2.0 コンポジット構造図を特に使用します。 下の構造図では、UML 2.0 のパーツがコラボレーション内の各要素を表しているのがわかります。 取引アプリケーションと店舗内サービスの間、および店舗内サービスとエンタープライズ・サービスの間のコネクターは、 サービス・チャネル としてステレオタイプ化され、 使用するバインディング (上記に示されている RMI または JMS) を示していることに注意してください。 店舗内サービスとローカル・データベース・コンポーネントとの間のコネクターのバインディング (後述) は、未定義です。

本文で説明されている図。

ここで注意すべき主要な要素の 1 つは、LocalCustomerLookupProvider が生成されたサービスで、 データベース照会のシン・ラッパー・サービスであり、SQL 選択を表す操作が 1 つだけあるということです。 店舗内の顧客検索サービスがデータベースに直接アクセスするアプローチと比較した結果、このアプローチが選ばれました。これにより、 ローカル・サービスに追加のビジネス・ルールを組み込んだり、さらには今後ローカル・サービスをより完成したサービスにすることができます。

ただし、この図は単にコラボレーションの構造を示しているだけであり、 以下の相互作用図 (UML 2.0 シーケンス図) が実際のサービス間の通信を表します。 操作 getCustomerByPhone がサービス仕様に追加されたことに注意してください。 また、UML 2.0 ではシーケンス図にオプションの「フラグメント」が指定できるようになり、 この例では、ローカル検索が失敗した場合はエンタープライズ・サービスとのみ通信することを示していることにも注意してください。

本文で説明されている図。

静的構造とコミュニケーション図の組み合わせによって、 サービスのコンポジションとコラボレーションを文書化することが可能になります。この例では、サービス仕様に対して 1 つの 操作のみが必要であることが識別されています。

詳しくは、アクティビティー『サービスの識別』を参照してください。

サービス設計 ページの先頭へ

サービスの識別アクティビティーからモデルを取り込み、識別した候補となる一連のサービスを、構築するサービスの詳細設計に移行します。 最初のステップは、上記の仕様を実現するサービス仕様をマップすることです。当然、サービスがどのように上記のモデルからサービス仕様を実現するかを決定しなければなりません。 この例では、適度に単純であるものの、おそらく多くのプロジェクトに共通する構造を持っています。 ここでは、1 つの仕様を実現する 1 つのサービスを表す 1 つのサービス・プロバイダー があります。 プロバイダーごとに複数のサービスを持つことはもちろん可能です。 このモデル内のサービス間の使用関係のいくつかにも注意してください。 これらの依存関係は、時間と共にサービスがどのように展開していくかを理解するために重要です。

本文で説明されている図。

この構造によって、モデルがまだサービスの論理ビューであっても、空間的な分散へと進むことができます。 これは、サービス・プロバイダーがサービス・モデルの配置単位を表しているからです。 サービス自体 (UML 2.0 ポート) はコンポジションの記述に必要な構造を所有できないため、コンポジット・サービスの定義にはサービス・プロバイダーも必要です。

メッセージ設計

上記のサービス識別アクティビティーでは、サービス仕様で記述される操作の間で実際に交換されるメッセージについては何も説明しませんでした。 操作の点からサービスの責務を収集して、メッセージの詳細な設計は後で行うというのは、極めて一般的なアプローチと言えます。場合によっては、このアプローチは逆になります。その場合、メッセージ構造が先に分かっていて、後から一連の操作に集約されます。

この例では、コンポーネントの分析モデル (以前に開発されたアセット) の一部として開発されたドメイン・モデルを利用することができます。 したがって、メッセージ・モデルについては、何もないところから構築されるのではなく、再利用するドメイン・モデルのサブセットを識別します。 以下の例はこの関係を示しています。 ドメイン・クラスはテクノロジーとプラットフォームを一切認識せず、一方、メッセージはデータ転送オブジェクト、 サービス間で受け渡される構造であると想定されます。 したがって、ドメイン・モデルを変更するよりはむしろ、内部の要素から構成されるクラス構造の「外部」にメッセージを作成します。

本文で説明されている図。

詳しくは、概念『メッセージ設計』を参照してください。

サービスの実現 ページの先頭へ

ここでは、店舗内の顧客検索サービスの実現に焦点を当てます。このサービスはサービス・モデルから設計モデルへの変換という点では典型的なものです。 変換自体はガイドラインに文書化されていて、結果は以下のモデル構造になります。

本文で説明されている図。

これはまだ設計モデルですが、ツールを使用して、このモデルを後述する EJB 実装にさらに変換します。 基本的に、この実装は上記の CustomerByPhone クラスから変換され、 顧客の詳細を示すメッセージはデータベースの照会に使用されるエンティティー Bean に変換されます。

本文で説明されている図。

詳しくは、ガイドライン『サービスからサービス・コンポーネントへの移行』を参照してください。