第8章 API を使った簡単な公開方法

jUDDI Registry を使用してサービスを公開する方法については、本章を参照してください。

8.1. UDDI データモデル

本章では、UDDI データモデルと、そのモデルに対する jUDDI 拡張について学習します。
アーチファクトの公開をする前に、データが UDDI モデルに適合する方法を把握する必要があります。本章では、プロセスの概要を把握しますが、詳細については UDDI 仕様を参照するようにしてください。
以下の図は、本モデルについてです (UDDI v3 仕様から抜粋)。
UDDI core data structures

図8.1 UDDI コアデター構造

図にあるように、データは階層別に整理されています。ビジネスエンティティがピラミッドの一番上に来ており、その中にビジネスサービスが含まれており、そのサービスの中にはバインディングテンプレートが含まれています。
TModels (またはテクニカルモデル) は、主なエンティティの 1 つに分類し、バインディングの技術詳細を説明 (プロトコルやトランスポート) し、 キーパーティションを登録するなど、包括的な構造となっています。
この階層と一貫性のある形式でデータをモデル化するには、サービスを公開する前にビジネスエンティティを構築し、バインディングテンプレートを公開する前にビジネスサービスを作成する必要があります (後ほど本章で例を使用して、このアプローチについて説明します)。
ビジネスエンティティは、サービスを提供する組織単位です。一般的に、ビジネスエンティティには説明と連絡先情報が含まれています。ビジネスエンティティの使用方法は、各自の状況により異なります。小規模な企業であれば、エンティティ 1 つしか必要ないでしょう。より規模の大きい企業で複数の部署を持つ場合、部署ごとにエンティティを 1 つ持たせるかもしれません。
また、別のオプションとしては、包括的なエンティティを1つと、その配下に複数の部署を示す子エンティティを持たせることもできます。方法は、Publisher アサーションを使用してエンティティ間の関係を作成します。
ビジネスサービスは、SOA 環境で中心的な存在であり、クライアントを消費する機能単位を表します。UDDI では、サービスには、名前、説明、カテゴリなど説明的な情報が主に含まれています。実際は、サービスに関する技術詳細は、バインディングテンプレートに含まれています。
バインディングテンプレートは、サービスの技術仕様が保存されるところです。仕様は、サービスのアクセスポイントやサービス WSDL の場所を提供するだけのシンプルなものから、WSDL の技術詳細の内訳などといった複雑なシナリオまで様々です (tModels と連携で使用)。

8.2. モデルへの jUDDI の追加

jUDDI Registry の実装は、仕様に記載されていない構造をデータモデルに提供します。パブリッシャー が主要なアイテムです。
UDDI 仕様は、レジストリ内で公開されたエンティティのオーナーシップについて記述していますが、このオーナーシップを実装すべきであることについては記述がありません。個別の実装により変わってきます。
パブリッシャーは、jUDDI Registry にこの機能を提供するアイデンティティ管理システムです。
Registry は認証トークンを取得できるようにしてパブリッシャーの認証を行なってからでないと、jUDDI にアセットの追加はできません。このトークンは後続の publish 呼び出しにアタッチされ、公開エンティティにオーナーシップを割り当てます。
カスタム API を用いて、jUDDI Registry にパブリッシャーを保存することができます。
パブリッシャーは、購入直後からアイデンティティ管理システムの実装をすぐにお使いいただけます。jUDDI により、独自のアイデンティティ管理管理システムに統合でき、パブリッシャーを完全に回避することも可能です。本書では、カスタマイズなしにすぐ利用できる、シンプルなパブリッシャーソリューションを利用します。

注記

オーナーシップは、本来 authorizedName フィールドから任意の登録エンティティに割り当てます。 operationalInfo の構造を説明している仕様の章にて、このフィールドに関する説明があります。詳細は http://www.uddi.org/pubs/uddi_v3.htm#_Toc85908030 を参照してください。

8.3. UDDI および jUDDI API

UDDI データモデルについて理解されたと思いますので、次に UDDI API の構成や、jUDDI Registry がこの API を実装する方法について見ていきます。
UDDI API を使用するには、どのような構成になっているか理解する必要があります。複数の sets に分割されており、各 set は特定の機能エリアについて表しています。
  • Inquiry は、エンティティの詳細に関する Registry へのクエリを処理します。details about entities.
  • Publication は、エンティティの登録を処理します。
  • Security は、認証処理を行う変更可能な仕様です。
  • Custody and Ownership Transfer は、エンティティのオーナーシップの移行処理を行います。
  • Subscription は、クライアントがサブスクリプションの形式を仕様してエンティティに関する情報をリトリーブできるようにします。
  • Subscription Listener は、サブスクリプションの結果を受け入れるクライアント API です。
  • Value Set (Validation and Caching) は、キー付きの参照値を検証します (このセットは、jUDDI ではまだ利用できません)
  • Replication は、レジストリノード間のデータを連携できるようにします (このセットは、jUDDI ではまだ利用できません)
最も頻繁に使用する sets は、InquiryPublicationSecurity です。Registry とやり取りを行う際に必要な標準機能を提供してくれます。
jUDDI サーバーは JAX-WS 準拠の Web サービスとして sets をそれぞれ実装します (セット内に定義されたメソッドは、該当の Web サービスにあるメソッドと同じです)。
jUDDI には、クライアントモジュールがあり、このモジュールはトランスポートクラスを使用してどのようにそれぞれを呼び出すのかを定義します (デフォルトのトランスポートは、JAX-WS を使用しますが、API への呼び出しには複数の方法があります)。
最後に、jUDDI は独自の API セットも定義します。この API セットには、パブリッシャーやその他のメンテナンス機能 (多くが jUDDI のサブスクリプションモデル関連) を処理するメソッドが含まれています。この API セットは、jUDDI に特有で、UDDI 仕様には準拠していません。

8.4. jUDDI Registry の初回利用

本章では、簡単な例をあげ、手順を説明していきます (この演習をはじめる前に jUDDI Registry を実行しておくようにしてください)。

8.4.1. 簡単なパブリッシャーの例

本章では、"simple-publish" の例についての手順を説明します。このサンプルでは、認証トークンをリトリーブした後に、Publisher、BusinessEntity、BusinessService が jUDDI に登録されます。
このサンプルには、SimplePublish クラス 1 つのみで構成されています。以下がコンストラクターです。
public SimplePublish() 
{
    try 
    {
        String clazz = UDDIClientContainer.getUDDIClerkManager(null).
            getClientConfig().getUDDINode("default").getProxyTransport();
        Class<?> transportClass = ClassUtil.forName(clazz, Transport.class);
        if (transportClass!=null) 
        {
            Transport transport = (Transport) transportClass.
                getConstructor(String.class).newInstance("default");

            security = transport.getUDDISecurityService();
            juddiApi = transport.getJUDDIApiService();
            publish = transport.getUDDIPublishService();
        }	
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }	
}
このコンストラクターは、jUDDI クライアント API を使用して、デフォルトノードからトランスポートをリトリーブします。このサンプルでは、JAX-WS Web サービスで UDDI を呼び出しするように設計されたデフォルトクライアントのトランスポートクラスを単にリトリーブするだけです。
トランスポートがインスタンス化されると、このサンプルに必要な API セットを 3 つ取得してください。API セット 3 つは以下のとおりです。
  • Security API セット (認証トークンを取得するため)
  • 専用の jUDDI API セット (パブリッシャーを保存するため)
  • Publication API セット (jUDDI にエンティティを登録するため)
以下に publish メソッドの最初の数行の例を示しています。
// Setting up the values to get an authentication token for the 'root' user 
// ('root' user has admin privileges and can save other publishers).
GetAuthToken getAuthTokenRoot = new GetAuthToken();
getAuthTokenRoot.setUserID("root");
getAuthTokenRoot.setCred("");

// Making API call that retrieves the authentication token for the 'root' user.
AuthToken rootAuthToken = security.getAuthToken(getAuthTokenRoot);
System.out.println ("root AUTHTOKEN = " + rootAuthToken.getAuthInfo());
このコードは、単に root ユーザー用の認証トークを取得するだけです。

注記

root ユーザーは自動的に、各 jUDDI インスタンスにインストールされ、jUDDI API 呼び出しの管理者として機能します。さらに、root ユーザーは jUDDI と合わせてインストールされた初期サービスすべてを所有するパブリッシャーとなります (初期サービスは、各 jUDDI ノードに Web サービスとして自動登録されるため、全 UDDI API セットから構成されています)。
root 認証を取得したので、パブリッシャーを追加していきます。
// Creating a new publisher that we will use to publish our entities to.
Publisher p = new Publisher();
p.setAuthorizedName("my-publisher");
p.setPublisherName("My Publisher");

// Adding the publisher to the "save" structure, using the 'root' user authentication 
// info and saving away. 
SavePublisher sp = new SavePublisher();
sp.getPublisher().add(p);
sp.setAuthInfo(rootAuthToken.getAuthInfo());
juddiApi.savePublisher(sp);
上記のコードは、jUDDI API を使用して認証済みの名前 my-publisher でパブリッシャーを保存します。root ユーザーの認証トークンを使用している点に注意してください。
次に、この新規パブリッシャーの認証トークンを取得する必要があります。
// Our publisher is now saved, so now we want to retrieve its authentication token
GetAuthToken getAuthTokenMyPub = new GetAuthToken();
getAuthTokenMyPub.setUserID("my-publisher");
getAuthTokenMyPub.setCred("");
AuthToken myPubAuthToken = security.getAuthToken(getAuthTokenMyPub);
System.out.println ("myPub AUTHTOKEN = " + myPubAuthToken.getAuthInfo());
どちらの認証呼び出しにも、認証情報が設定されていません。これは、デフォルトの認証子を使っているので認証情報を渡す必要がないためです。
root 認証を取得したので、公開の準備が整いました。
// Creating the parent business entity that will contain our service.
BusinessEntity myBusEntity = new BusinessEntity();
Name myBusName = new Name();
myBusName.setValue("My Business");
myBusEntity.getName().add(myBusName);

// Adding the business entity to the "save" structure, using our publisher's 
// authentication info and saving away.
SaveBusiness sb = new SaveBusiness();
sb.getBusinessEntity().add(myBusEntity);
sb.setAuthInfo(myPubAuthToken.getAuthInfo());
BusinessDetail bd = publish.saveBusiness(sb);
String myBusKey = bd.getBusinessEntity().get(0).getBusinessKey();
System.out.println("myBusiness key:  " + myBusKey);

// Creating a service to save.  Only adding the minimum data: the parent 
// business key retrieved from saving the business above and a single name.
BusinessService myService = new BusinessService();
myService.setBusinessKey(myBusKey);
Name myServName = new Name();
myServName.setValue("My Service");
myService.getName().add(myServName);
// Add binding templates, etc...

// Adding the service to the "save" structure, using our publisher's 
// authentication info and saving away.
SaveService ss = new SaveService();
ss.getBusinessService().add(myService);
ss.setAuthInfo(myPubAuthToken.getAuthInfo());
ServiceDetail sd = publish.saveService(ss);
String myServKey = sd.getBusinessService().get(0).getServiceKey();
System.out.println("myService key:  " + myServKey);
まとめると、この例では BusinessEntity を作成、保存してから、BusinessService を作成、保存しました。各エンティティに最小限のデータを追加しました (サービスには BindingTemplates は追加していません)。
実際には、特にサービス関連など、構造ごとにより多くの情報を追加するはずです。しかし、この例は便利なスタートポイントとなるでしょう。

注記

エンティティキーを使用する際に注意すべき重要なポイントがいくつかあります。仕様のバージョン 3 では、パブリッシャーは独自のキーを作成し、実装者にデフォルトのメソッドを持つように指示を出します。
Red Hat は、save 呼び出しで、各エンティティの key フィールドを空の状態にすることで、デフォルトの実装アプローチを選択しました。jUDDI のデフォルトキー生成は、ノードのパーティションを取り、GUID をそのパーティションに追加するだけです。
デフォルトのインストレーションでは、以下のようになります。
uddi:juddi.apache.org:<GUID>
(もちろん、上記をすべてカスタマイズすることも可能です)
2 つ目の重要なポイントは、BusinessService が保存されると、親ビジネスキー (ビジネスを保存する以前の呼び出しからリトリーブ) が明示的に設定される点です。このように独立した呼び出しにサービスが保存される場合、この手順は必要となります。この手順を行わないと、jUDDI が親エンティティを見つけられないため、エラーが発生してしまいます。