共有サービス

共有サービスとは、クラウド内の複数のクライアント・アプリケーション・デプロイメント (仮想アプリケーションや仮想システムなど) によってデプロイおよび共有される事前定義されたパターンのことです。 共有サービスは、複数のアプリケーションに特定のランタイム・サービスを提供したり、複数のアプリケーションの代わりにユーザーにサービスを提供したりします。

通常、共有サービスへの参照は、クラウドを定義するハードウェアの物理グループである クラウド・グループごとに 1 つのみです。 その共有サービスは、 クラウド・グループ内のすべてのアプリケーション・デプロイメントで使用できます。これは、共有サービスがマルチテナント・アクセスを提供する必要があることを意味します。

共有サービス・インフラストラクチャー

このインフラストラクチャーは、共通の管理フレームワークおよびレジストリー・サービスを提供します。 各 クラウド・グループでは、共有サービスへの単一の参照が許可されます。 共有サービスのデプロイメントおよび管理は、UI パネルを使用して行うことができます。 2 つのタイプの共有サービスを作成できます。1 つは クラウド・グループ で作成された仮想マシンを使用し、もう 1 つは クラウド・グループ外部のサービスへの外部参照です。

レジストリーには、各 クラウド・グループにデプロイされた共有サービスに関する情報が含まれています。 共有サービスのクライアントは、対話したい共有サービスに関する情報を、このレジストリーに照会できます。 クライアントに必要な情報だけでなく、サポート可能なクライアント API のバージョンも、共有サービス実装によって決まります。

共有サービス実装環境の作成

共有サービスは、仮想アプリケーションのプラグイン開発と同じように開発されます。 ただし、シナリオによっては、追加のメタデータや機能があります。 以下に、サービスを開発する際に従う手順をリストして概説します。
  1. 事前定義されたアプリケーション・モデルおよびプロパティー・メタデータを作成します。
    appmodel.json ファイルは、通常の仮想アプリケーションの Pattern Builder ユーザー・インターフェースで定義されるモデルのシリアライゼーションを表します。 コンポーネント (ノード) とリンクが、ユーザー指定のプロパティー値とともに示されています。 共有サービスの場合、プロパティーが事前定義されている必要があります。 アプリケーション・モデルのノード、リンク、およびその他の属性に加え、共有サービスには以下の属性が必要です。
    app_type
    "service" に設定します。
    serviceversion
    共有サービス・アプリケーション・モデル固有のバージョン。VRMF 形式で指定します。 例えば、1.0.0.0 となります。
    servicesupportedclients
    この共有サービスを使用可能な、サポートされるクライアント・バージョンのリスト。
    以下に、パターンの例を示します。
    • *: すべてのバージョンに一致します
    • [a,b]: ab を含め、a から b までのすべてのバージョンに一致します
    • (a,b): ab を除き、a から b までのすべてのバージョンに一致します
    • [*,b]: b を含め、b までのすべてのバージョンに一致します
    • [a,*]: a 以上のすべてのバージョンに一致します
    servicedisplayname
    グループ化された同様のサービスの表示名。
    servicename
    サービスの名前。 サービス・レジストリー文書の名前として使用されます。
    id
    "sharedservice" に設定します。 この属性は、ノード上での属性です。
    type
    transformer および appmodel メタデータをこのノードにリンクする固有の ID。
    servicetype
    サービスを外部共有サービスとして識別するには、 appmodel.jsonExternal に設定します。
    以下の例に、これらの属性の使用方法を示します。
    {
       "model":{
    		"name":"Shared Service",
    		"app_type":"service",
    		"patterntype":"foundation",
    		"version":"1.0",
    		"serviceversion":"1.0.0.0",
    		"servicesupportedclients":"[0.0,1.0]",
    		"servicedisplayname":"servicegroup",
    		"servicename":"service",
    		"description":"comments",
    		"nodes":[{
    			 "attributes":{...},
    			"id":"sharedservice",
    			"type":"uniqueComponentOSGIID"
    		}],
    		"links":[]
    	}
    }

    appmodel/metadata.json ファイルでは、プラグインによって実装されるコンポーネント、リンク、およびポリシーを記述します。 共有サービスは、同じ属性設計を使用します。 デフォルト属性を設定するには、事前定義 appmodel 内で特定の属性を設定するか、 metadata.json内で sampleValue フィールドを使用します。

  2. レジストリー・プロバイダー・クラスを定義します。

    共有サービス・レジストリーには、サービスにより共有されているサービス自体に関する情報をクライアントが見つけるための情報が格納されています。 インフラストラクチャーはこの機能を提供するために、共有サービスに固有の com.ibm.maestro.iaas.RegistryProvider クラスの実装を使用します。 以下のメソッドにより、共有サービスでは、そのモデルおよびデプロイメント構成に基づいて情報をクライアントに返すことができます。

    public JSONArtifact getRegistry(String ClientVersion, Map<String, JSONObject> deploymentInfo throws HttpException;

    deploymentInfo には、appmodel (appmodel.json)、デプロイメント (deployment.json)、トポロジー (topology.json)、およびレジストリー (registry.json) の各文書が格納されます。

  3. appmodel のトポロジー・テンプレートを作成します。
    トランスフォーマーは、アプリケーション・モデルを論理的な記述から、仮想アプリケーションのデプロイに使用されるトポロジー文書に変換するサービスです。 共有サービスでは (他のプラグインと同様に) トポロジー文書のテンプレートと、そのテンプレートをデプロイメント時に実際のトポロジー文書に変換するトランスフォーマーを定義できます。 共有サービス・レジストリー・プロバイダー・クラスを参照するには、共有サービスで以下の属性が提供されている必要があります。
     "service-registry": [{
            "type": "<RegistryProvider implementation>"
        
    }],

    外部共有サービス・トポロジー・テンプレート用の vm-templates 属性セクションは、共有サービスの外部リソース実装を指しているため、これは含めないでください。

  4. 共有サービス・ライフサイクル・スクリプトを作成します。

    ライフサイクル・スクリプトの開発について詳しくは、『プラグイン開発ガイド』の「ライフサイクル・スクリプトの開発」のセクションを参照してください。 共有サービスのライフサイクル・スクリプトを開発する際には、障害に対応し、リカバリーを可能にする機能などを検討して、サービスやスケーラビリティーなどの機能に対する管理操作を提供してください。

  5. オプション。 共有サービスのパブリック証明書をクライアントがアクセスできるようにします。

    インフラストラクチャーは、共有サービスがクライアントとして機能するデプロイメントに対して安全に使用可能にする必要がある証明書のための中央の場所を提供します。 共有サービスでは以下の com.ibm.maestro.iaas.RegistryService API を呼び出して、証明書を管理できます。

    public void putCertificate(RestClient restClient, String putObj, String cloudGroup, String sharedServiceName, String sharedServiceVersion) throws CredentialExpiredException, MaestroSecurityException, HttpException;

    public void deleteCertificate(RestClient restClient, String cloudGroup, String sharedServiceName, String sharedServiceVersion) throws CredentialExpiredException, MaestroSecurityException, HttpException;

  6. クライアントがサービスと対話するために使用する管理 HTTP 呼び出しを公開します。

    クライアントが簡単に共有サービスに登録して対話 (サービスのリソースを予約) できるように、それぞれの共有サービスが HTTP 管理インターフェースを公開する必要があります。 その後、サービスの使用法は、(予約されたリソースを非 HTTP 対話で使用することにより) 個々のサービスに応じてカスタマイズできます。 このステップでは、クライアントがサービスを使用する前に、管理 HTTP 対話のクライアント契約を判別するためにクライアント・バージョンが役立ちます。

    共有サービス・インフラストラクチャー・フレームワークでは、共有サービスでフレームワークをさらに活用する場合に HTTP 管理インターフェースを容易に作成するためのヘルパー機能が用意されています。 詳しくは、『汎用共有サービス REST API サポートおよびクライアント対話』のセクションを参照してください。

共有サービス・クライアントの開発

アプリケーション・デプロイメントでは、共有サービス・コンシューマー・モデルを以下の方法で使用可能にすることができます。
  • 仮想アプリケーション・モデラーによってリソースを直接公開する方法 (例: デプロイメントを ODR (オンデマンド・ルーター) ベース・ロード・バランサーの共有サービス・クライアントとして使用可能にするルーティング・ポリシー)。
  • 共有サービスの使用を暗黙指定する設定による間接的な方法。 スケーリング・ポリシーは、HTTP セッション・キャッシングを暗黙指定し、デプロイメントを キャッシング共有サービスのクライアントにすることを可能にします。
  • appmodel 変換プロセスによってクライアントを注入するという方法。 このプロセスを実行するために、プロセスによるトポロジー文書の作成中に、クライアント・プラグイン・パッケージ、パラメーター、サービス参照、およびその他の要素が追加されます。
このインフラストラクチャーは、共有サービス・クライアントに代わって行われるデプロイメント前のサービス参照チェックをサポートしており、デプロイメントがクラウド内にリソースを作成するのを停止することができます。
  • クライアントは、参照するサービスと、サービスの可用性によってデプロイメント続行の可否を決定するかどうかを指定できます。 クライアント・トポロジー文書内の以下のタグは、このクライアントが参照する共有サービスが、デプロイ先の クラウド・グループ で使用可能な 3.0 のクライアント・バージョンをサポートする必要があることを示しています。 サポートされていない場合、クライアント・デプロイメントは失敗します。
       "service-templates": [
    		{
    			"sharedservice": {
    				"client-version": "3.0", 
    				"name": "shared service name>", 
    				"required": true
    			}
    		}
        ]
  • クライアントは、必要なリソースをプロビジョンする ServiceProvisioner を定義できます。 共有サービスとの対話は、共有サービスのレジストリー情報を取得し、後で使用できるように入力をトポロジー文書に提供することによって可能になります。 この段階でも、クライアントによってデプロイメントが失敗する可能性があります。 クライアントは共有サービスに関する情報を取得するために、com.ibm.maestro.iaas.RegistryService インターフェースの getRegistry メソッドを次のように呼び出します。 public JSONArtifact getRegistry(RestClient restClient, String sharedServiceName, String clientCloudGroup, String clientVersion, String clientDeploymentId) throws HttpException;

    ServiceProvisionerについては、 Plug-in Development Kitの Javadoc 資料を参照してください。

デプロイメント後に、クライアント・プラグイン・パッケージがデプロイ済み仮想マシン上で解凍されると、クライアントは共有サービスのライフサイクル・スクリプトを使用して共有サービスと対話できるようになります。 このインフラストラクチャーには、ライフサイクル・スクリプトからのレジストリーおよび証明書関連のメソッド呼び出しのための maestro.registry Python ライブラリーが用意されています。
import maestro
parms=maestro.registry.getRegistry(shared_service_name, shared_service_client_version)
masterIP = parms['<registry parm name>']
クライアントを共有サービスに接続しておく必要がなくなった場合、またはクライアントを削除する場合には、removeRegistryRef 呼び出しを使用できます。
import maestro
maestro.registry.removeRegistryRef(shared_service_name, shared_service_client_version)
共有サービスが共有サービス・フレームワーク内でパブリック証明書を公開している場合、クライアントは、以下のコマンドを使用してその証明書を取得できます。
import maestro 
maestro.registry.getCertificate(shared_service_name, shared_service_client_version, temp_cert_file)
以下の例は、ライフサイクル・スクリプトで上記のコマンドを使用する方法を示しています。 このスクリプトは、デプロイされた キャッシング共有サービスの IP アドレスを表示し、パブリック証明書をダウンロードし、スクリプトの実行が終了したことを示すシグナルをサービスに提供します。
import maestro

service_name = "caching"
client_version = "2.0"

# get registry information
registry_info = maestro.registry.getRegistry(service_name, client_version)
ip_address = registry_info['cache-ip']

print "Caching service found at " + ip_address


# this is where the certificate will be stored
certificate_location = "/tmp/caching_certificate"

# download certificate
maestro.registry.getCertificate(service_name, client_version, certificate_location)

# signal the service that we have finished interacting with it
maestro.registry.removeRegistryRef(service_name, client_version)

共有サービス・プロバイダーは、サービスが提供する機能に基づくクライアント対話モデルを明確に文書化する必要があります。 この対話を文書化するには、クライアント・バージョンを使用してください。これが、そのバージョンに期待される内容を正確に定義するクライアント契約となります。 共有サービスのバージョンによって、レジストリーからクライアントに返される情報が異なる場合があります。 クライアント・サービス・プロビジョナーとライフサイクル・スクリプトは、レジストリー応答に応じた正しいサービスとの対話方法を理解する必要があります。 例えば、共有サービス・バージョン 1.0 は、getRegistry 呼び出しを通じてホスト、ユーザー名、およびパスワードの各属性をバージョン 1.0 のクライアントに返すとします。 この応答にポートも追加する必要がある場合、サービスはこの情報を、追加属性を処理するために作成されたバージョン 2.0 のクライアントを対象とすることを示すことができます。 次の改訂では、サービスでバージョン 1.0 と 2.0 の両方のクライアントをサポートし、それぞれに期待される応答を提供することができます。

また、クライアントのバージョンは、共有サービス・インフラストラクチャーが、クライアントが クラウド・グループで対話できる共有サービスのバージョンを判別するのにも役立ちます。 例えば、バージョン 1.0 の共有サービスでサポートしているのがバージョン 1.0 のクライアントのみである場合、バージョン 2.0 のクライアントがレジストリーを要求しても、インフラストラクチャーはそのクライアントにはレジストリー・オブジェクトを返しません。

共有サービス・クライアントの追跡および操作の呼び出し

特定の共有サービスでは、その共有サービスに接続するクライアントを追跡するための機能が必要になる場合があります。 この機能は、共有サービスがその開始または削除ライフサイクル・イベントをクライアントに伝達できるようにするために必要になることもあります。 例えば、クライアントが削除される時点で、そのクライアントによる共有サービスへの情報の要求を停止させるとします。 この機能を有効にするには、以下のメタデータを共有サービス VM テンプレートに組み込みます。
"service-registry": [{
        "type": "<RegistryProvider implementation>"
        "trackclientusage":true
        
}],

このメタデータが指定されると、インフラストラクチャーはサービスに対してレジストリー情報を要求するクライアントのリストを維持します。 また、このインフラストラクチャーでは、サービスが、そのサービスの使用状況が追跡されているクライアントに対して操作を呼び出すための機能も提供しています。 操作は、クライアントで次のように定義されます。public void callOperationOnSSClients(RestClient restClient, JSONObject serviceInfo, JSONObject operationParms) throws HttpException;

以下の例に、共有サービス ServiceProvisioner からこの操作を呼び出す方法を示します。
public StateAndDescription deleteService(String serviceReferenceName,
			JSONObject serviceDescription, RestClient restClient)
			throws Exception {
        final String METHOD_NAME = "deleteService";
        if (logger.isLoggable(Level.FINE)) {
            logger.logp(Level.FINE, CLASS_NAME, METHOD_NAME, "deleteService: " + serviceReferenceName + "/" + serviceDescription);
            logger.logp(Level.FINE, CLASS_NAME, METHOD_NAME, "Calling the disconnect operation on shared service clients");
        }
        
        JSONObject operationParms = new JSONObject();
        operationParms.put("role","<role_name>");
        operationParms.put("type", "<type_name>");
        operationParms.put("script", "<scriptname>");
        operationParms.put("method", "<method_name>");
        operationParms.put("parameters", new JSONObject());
        this.registrySvc.callOperationOnSSClients(restClient, serviceDescription, operationParms);

汎用共有サービス REST API サポートおよびクライアント対話

汎用共有サービス REST インフラストラクチャーは、クライアントが共有サービスで公開されているメソッドを開始するための、共通の HTTP ベースの対話モデルを提供するのに役立ちます。 共有サービスでは、メソッドを実装する操作メタデータと Python スクリプトを提供できます。 クライアントは、汎用共有サービス REST API を呼び出して操作を開始できます。 例えば、クライアントは REST URL https://<Master_Agent_VM>:9999/sharedservice/<servicename>/<resource>GET を呼び出すことができます。

サーバー・サイドのメタデータとセットアップを構成するには、以下の手順に従います。
  1. JSON ファイル内にサービス・メタデータを指定して、共有サービス nodepart データにパッケージ化する必要があります。 例: plugin/nodeparts/cachingrestapi/cachingrestapi/properties/cachingrestapi.json
    メタデータ内の JSON オブジェクトには、以下の属性を含める必要があります。
    servicename
    共有サービスの名前 ("caching")。
    operations
    サービスで公開される操作の JSON 配列。 この配列内の各オブジェクトが、以下の属性を定義します。
    type
    HTTP 操作のタイプ。GETPUTPOST、または DELETE です。
    parms
    各呼び出しタイプのパラメーターを表すオブジェクトの配列。 オブジェクトは、以下の属性を定義する必要があります。
    resource
    操作が実行されるリソース。 REST URL の servicename に続く URL セグメントにマップします。
    role
    この操作の実行対象となるロール。
    script
    < script_name> < メソッド名> 操作および開始されるメソッドを定義する Python スクリプト。
    clientdeploymentexposure
    オプション。 KernelServices プロセスからだけでなく、クライアントがデプロイされた仮想マシンからも、呼び出しを開始できるかどうかを決定します。 デフォルト値は false です。
    timeOut
    オプション。 操作のタイムアウト。 デフォルト値は 60000 です。 この属性が 0 の場合、操作はタイムアウトなしで同期的に実行されます。 この属性が 0 より大きい場合、操作は指定された期間 (ミリ秒単位)、この呼び出しの戻りを待機します。 タイムアウトが発生した場合、操作は HTTP 202 応答で応答します。
    pattern
    この属性を使用して URL の他のセグメントを突き合わせることで、操作にさらに多くの parms をフィードできます。 中括弧で囲まれたエントリーは、名前と値のペアとして着信 URL に対して突き合わせられ、parms として操作に渡されます。 例えば、REST URL の形式が https://<host>:<port>/sharedservices/caching/sessiongrid/gridA であり、パターンが {gridName} であるとします。 この場合、gridName=gridA という名前と値のペアが、追加の引数として操作にフィードされます。
    以下に、metadata json の例を示します。
    {
    	"servicename": "caching", 
    	"operations": [
    		{
    			"type": "PUT", 
    			"parms": [
    				{
    					"resource": "sessionGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py createSession",
    					"timeout": 1200000
    				},
    				{
    					"resource": "simpleGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py createSimple"
    				},
    				{
    					"resource": "dynamicGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py createDynamic"
    				}
    			]
    		}, 
    		{
    			"type":"DELETE",
    			"parms":[
    				{
    					"resource": "sessionGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py deleteSession",
    					"pattern": "{gridname}"
    				}, 
    				{
    					"resource": "simpleGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py deleteSimple",
    					"pattern": "{gridname}"
    				},
    				{
    					"resource": "dynamicGrid", 
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py deleteDynamic",
    					"pattern": "{gridname}"
    				}
    			]
    		},
    		{
    			"type":"GET",
    			"parms":[
    				{
    					"resource": "sessionGrid", 
    					"clientdeploymentexposure":true,
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py gridExists",
    					"pattern": "{gridname}"
    				},
    				{
    					"resource": "publicCert", 
    					"clientdeploymentexposure":true,
    					"role": "Caching-Master.Caching", 
    					"script": "restapi.py downloadCert",
    					"responseType": "zipFile"
    				}
    			]
    		}
    	]
    }
  2. 共有サービス・デプロイメントの仮想マシンの始動中に、仮想マシン上にメタデータをコピーする必要があります。 コピーする場所は、/0config/sharedservices/restmetadata/ です。 上記のメタデータをコピーするには、デプロイメント中に実行される nodepart インストール・スクリプトを指定します。 例えば、以下の内容が含まれる /plugin/nodeparts/cachingrestapi/common/install/7_cachingrestapi.py です。
    restapidir = '/0config/sharedservices/restmetadata'
    restapifile = '/cachingrestapi.json'
    restapi = '../../cachingrestapi/properties/cachingrestapi.json'
    
    os.popen('mkdir -p ' + restapidir)
    os.popen("mv " + restapi+ " "+ restapidir + restapifile)
  3. Python スクリプトにメソッドを実装します。 さまざまなソース、REST 呼び出しへの入力 JSON オブジェクト、または URL パターン・マッチングからの parms に基づいて実行される操作を定義します。 例: parts/caching.scripts/scripts/CachingMaster/restapi.py クライアントは、以下の便利メソッドを使用して API を呼び出すことができます。
    • KernelServices プロセス内から (サービス・プロビジョナーを介して) サービスに対する操作を呼び出す場合は、com.ibm.maestro.iaas.RegistryService に定義された以下のメソッドを使用します。
      public OperationResponse callOperationOnSharedService(String serviceName, String clientCloudGroup, String clientVersion, 
      String serviceIP, String resourceUrl, String operationType, JSONObject operationParms) throws HttpException;
      以下に例を示します。
      JSONObject clientJSON = new JSONObject();
          	clientJSON.put("user", user);
          	clientJSON.put("password", password);
          	clientJSON.put("gridname", grid);
          	clientJSON.put("gridcap", cachingCap);
      
            OperationResponse response = this.registrySvc.callOperationOnSharedService("caching", (String)serviceDescription.get("cloud_group"), "3.0", ip,
            "sessionGrid", "PUT", clientJSON);
            int status = response.getStatusCode();
            JSONObject result = response.getOperationResponse();
    • 仮想アプリケーション・デプロイメント用に、共有サービス・インフラストラクチャーでは共有サービスと対話するためのユーティリティーを提供しています。 このユーティリティーには、ライフサイクル・スクリプト内でアクセスできます。

      ユーティリティー・スクリプトは、 callSSrestapi: sharedservices.callSSrestapi(url, method, data=None, filepath_input=None, filepath_output=None)という 1 つのメソッドのみを提供します。 このメソッドは、指定されたメソッドを使用して、指定された URL への REST API 呼び出しを行います。 この関数が返すのは、呼び出しの HTTP 状況コードと、(提供されている場合) 戻り JSON 文書です。

      呼び出し元は、filepath_input パラメーターを設定することで、戻されたファイルを指定の場所 (そのディレクトリーが存在することが前提) に保管できます。 このパラメーターは、共有サービスがこの呼び出しによって圧縮ファイルを返す場合に必要となります。 filepath_input が設定されない場合、共有サービスからの応答は解析後に削除されることに注意してください。

      呼び出し元が共有サービスにファイルを送信しなければならない場合は、filepath_output パラメーターをそのファイルの場所に設定できます。ただし、ファイルを送信するには method 引数が PUT または POST でなければなりません。 PUT または POST メソッドが使用される場合には、data または filepath_output のいずれかの引数が必要となります。

      この関数にアクセスするには、以下のコードをライフサイクル・スクリプトに組み込む必要があります。
      import sys
      ss_path = '/0config/nodepkgs/helper/scripts'
      if not ss_path in sys.path:
          sys.path.append(ss_path)
      import sharedservices
      以下のスクリプトの例では、ユーティリティー関数を使用してキャッシュ共有サービスと対話します。 パブリック証明書を取得して、指定されたキャッシュ・グリッドが存在するかどうかを検査します。
      import sys
      
      ss_path = '/0config/nodepkgs/helper/scripts'
      if not ss_path in sys.path:
          sys.path.append(ss_path)
      import sharedservices
      
      service = "caching"
      version = "2.0"
      
      regInfo = maestro.registry.getRegistry(service, version)
      try:
          ipAddr = regInfo['cache-ip']
          print "caching service found at " + ipAddr
      except KeyError:
          print "caching service not found"
          sys.exit(1)
      
      
      cert_zip_location = "cert.zip"
      
      # download zip (that contains the certificate)
      cert_response = sharedservices.callSSrestapi("https://" + ipAddr + ":9999/sharedservice/caching/publicCert", 
      "GET", filepath_input=cert_zip_location)
      
      
      # check if a grid exists
      grid_name = "SomeGrid"
      
      http_code, grid_response = sharedservices.callSSrestapi("https://" + ipAddr + ":9999/sharedservice/caching/gridExists/", "GET")
      ret =  grid_response['OperationResults'][0]['return_value']
      
      if (ret.find(grid_name + ' does not exist') >= 0):
          print grid_name + " does not exist"
      else:
          print grid_name + " exists"
      
      # inform the caching service that we have finished interacting with it
      maestro.registry.removeRegistryRef(service, version)
    デプロイ済み仮想マシンで以下を実行することにより、API を手動でテストできます。
    cd /0config  
    export $(./get_userdata.sh)  
    export header=$(/opt/python-2.6.4/bin/python create_security_header.py)
    curl -H "X-IWD-Authorization : $header" -kv -H Content-Type:application/json -X PUT -d '{"input":"hi"}' 
    https://<shared service IP:9999/sharedservice/<servicename>/<resourcename>

仮想システム・クライアントと共有サービスの対話

共有サービス・インフラストラクチャーでは、仮想システム・デプロイメントを共有サービス・クライアントにするためのサポートも提供しています。 仮想システム上のスクリプト・パッケージを使用して以下のライブラリーおよび API を呼び出すことで、共有サービス・レジストリーを照会したり、共有サービスで公開されている REST API やその他の関数を開始したりできます。

仮想システム用の共有サービス・プラグインでは、maestro がデプロイ済み仮想システムにインストールされている必要があります。 デフォルトでは、そのようなデプロイメントで maestro は使用可能にされていません。 maestro を使用可能にするための手順は、以下のとおりです。
  1. 「カタログ」 > 「システム・プラグイン」をクリックします。 ダッシュボードから
  2. Foundation パターン・タイプを選択します。
  3. virtualsystem プラグインを選択します。
  4. 「構成」をクリックします。
  5. 「仮想システムのプラグイン (Plug-ins for virtual systems)」enabledに設定します。

上記の手順を実行すると、すべてのデプロイ済み仮想システム・パターンが maestro をインストールし、仮想システム用の共有サービス・プラグインを組み込みます。

共有サービス・クライアントは、関数で仮想アプリケーション・ライフサイクル・スクリプトを模倣しようと試みるノード・パッケージです。 ただし、操作とその呼び出し方法には、いくつかの重要な違いがあります。

共有サービスと対話するには、次のようにして共有サービス・クライアント・スクリプトをインポートする必要があります。
import sys
ss_path = '/0config/nodepkgs/helper/scripts'
if not ss_path in sys.path:
    sys.path.append(ss_path)
import sharedserviceclient
上記のスクリプトをインポートした後は、以下の関数にアクセスできます。
sharedserviceclient.getRegistry(service_name, client_version)
この関数は、クライアントのバージョンがサポートされている場合、指定された共有サービスのレジストリー情報を返します。 maestro.registry.getRegistry とは異なり、この関数は応答をテキスト・ストリングとして返します。
sharedserviceclient.removeRegistryRef(service_name, client_version)
この関数は、クライアントが指定された共有サービスとの対話を完了した時点で呼び出され、もう使用されないリソースをクリーンアップするようにサービスに信号を送ります。 この操作が正常に完了した場合の戻り値は 0 です。
sharedserviceclient.restapi(url, method, data=None)
この関数は、curl を使用して REST API メソッドを呼び出し、指定された URL にある共有サービスと対話します。 受け入れられるメソッドは、 GETDELETEPUT、および POSTです。 メソッドが PUT または POST の場合は、data パラメーターが必須です。

data 引数はテキスト・ストリングでなければなりません。 同様に、この関数はサービスからの応答をテキスト・ストリングとして返します。

以下の例に、キャッシュ共有サービスと対話して、指定されたデータ・グリッドが存在するかどうかを確認する方法を示します。
import sys
ss_path = '/0config/nodepkgs/helper/scripts'
if not ss_path in sys.path:
    sys.path.append(ss_path)
import sharedserviceclient


def find_cache_IP(reg_info):
    """
Finds the Caching Shared Service IP address in the registry information.
    """
    str_info = str(reg_info)
    
    start = 'cache-ip":"'
    end = '",'
    
    start_cip = str_info.find(start)
    end_cip = str_info.find(end, start_cip)
    
    return str_info[start_cip+len(start):end_cip]

def does_grid_exist(grid_name, caching_ip):
    """
Queries the Caching Shared Service to see if a grid exists.
Returns '1' if the grid exists, '0' otherwise.
    """
    str_reply = str(sharedserviceclient.restapi("https://" + cip + ":9999/sharedservice/caching/gridExists/" + grid_name, "GET", ""))
    
    if (str_reply.find(grid_name + ' does not exist') >= 0):
        return 0
    else:
        return 1


# figure out the caching service's IP address
reg = sharedserviceclient.getRegistry("caching", "2.0")
cip = find_cache_IP(reg)

# grid to read data from
grid_name = "WAS_GRID"

# ensure the grid exists
if (does_grid_exist(grid_name, cip)):
    print "Reading data from grid..."
    # read data from it
else:
    print "Grid '" + grid_name + "' doesn't exist"
    # ask somebody to create it

# done with caching server
sharedserviceclient.removeRegistryRef("caching", "2.0")