目次


仮想アプリケーション・パターンのプラグインを作成する

第 2 回 既存のパターン・タイプを拡張してカスタマイズする

既存の仮想アプリケーション・パターンに新しい機能を追加する手法

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: 仮想アプリケーション・パターンのプラグインを作成する

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:仮想アプリケーション・パターンのプラグインを作成する

このシリーズの続きに乞うご期待。

はじめに

仮想アプリケーション・パターンとは、クラウドのワークロードを、そのベースにあるトポロジーや仮想マシンからは切り離された大まかな抽象アプリケーション・モデルとして定義する IBM PureApplication System のデプロイメント・モデルです。仮想アプリケーション・パターンは、特定の機能セットを提供するプラグインから作成します。これらのプラグインはパターン・タイプとしてパッケージ化されていますが、プラグインが提供している機能を拡張しなければならないような状況を考えてみてください。この記事では、そのような機能拡張を実際に行う方法を説明します。仮想アプリケーション・パターンについての詳しい説明は、「参考文献」セクションのリンクを参照してください。

独自のプラグインで既存のパターン・タイプを拡張する

以降のセクションでは、既存のプラグインが提供している機能を拡張するプラグインの開発方法を詳しく説明します。開発するプラグインは、新しい仮想マシンを追加せずに、追加の機能を注入します。この手法で利用するのは、既存のプラグインが提供しているコンポーネントと拡張プラグインが提供するコンポーネントの間の依存関係です。さらに、仮想マシンを追加で作成しなくても済むようにするために、拡張プラグインでは service という名前の特殊なコンポーネント変換構成体を使用します (新しい vm-template は作成しません)。拡張プラグインを作成するために必要なステップは、以下のとおりです。

  1. スタンドアロン形式ではデプロイできない新しいパターン・タイプを作成します。
  2. 既存のパターン・タイプに含める新しいプラグインを作成します。
  3. 既存のプラグインに定義されている別のコンポーネントにリンクできるコンポーネントを作成します。
  4. 既存のプラグインに追加機能を注入できる、ライフサイクル管理スクリプトを作成します。
  5. 最後に、追加の仮想マシンを生成せずにコンポーネントとリンクの変換処理を作成します。

この記事で取り上げる例

この記事では、Web Application Pattern Type 2.0 パターン・タイプが提供している機能を拡張します。Web Application Pattern パターン・タイプには、「Enterprise Application (エンタープライズ・アプリケーション)」コンポーネントと「Web Application (Web アプリケーション)」コンポーネントを提供する was という名前のプラグインが含まれています。これらのコンポーネントは、IBM WebSphere Application Server をインストールして構成する機能を提供するとともに、そのアプリケーション・サーバー上にエンタープライズ・アプリケーションまたは Web アプリケーションを提供します。作成する拡張プラグインでは、was プラグインが提供する Enterprise Application コンポーネントと Web Application コンポーネントを拡張して、WebSphere Application Server における追加の構成アイテムを定義します。具体的には、Java EE プロパティー・ファイルの管理に使用できる、新しい URL リソース参照を追加します。そのために、拡張プラグインのコンポーネントは、プロパティー・ファイルを値として取る「プロパティー・ファイル」属性を提供します。拡張プラグインをテストするために使用するサンプル・エンタープライズ・アプリケーションでは、この外部プロパティー・ファイルを使用して、新しい URL リソース参照が正常に構成されることを実証します。

独自の拡張プラグインを作成する

このセクションでは、拡張プラグインを作成する方法、そして Web Application Pattern パターン・タイプに対する拡張プラグインの依存関係を定義する方法を説明します。

パターン・タイプ

この連載の第 1 回で説明したように、パターン・タイプには、仮想アプリケーションとそれぞれに対応するライフサイクル・スクリプトをデプロイするために必要なコンポーネント、リンク、ポリシーを定義するプラグインが収容されます。従って、既存のパターン・タイプを拡張するには、まず始めに、拡張プラグインを含めるための新しいパターン・タイプを定義する必要があります。それには、IBM Workload Deployer Plug-in Development Kit を開き、WASCustomPatternType という名前の「IBM Workload Pattern Type Project」を新規に作成します (図 1 を参照)。新規パターン・タイプを作成する詳しい手順については、第 1 回を参照してください。

図 1. 新規パターン・タイプの作成
新規パターン・タイプを作成する画面のスクリーン・キャプチャー
新規パターン・タイプを作成する画面のスクリーン・キャプチャー

仮想アプリケーション・ビルダーで新しい仮想アプリケーション・パターンを作成するときには、このパターン・タイプを使用しません。これは、拡張する対象の既存のパターン・タイプであり、新しい仮想アプリケーションを作成するために使用するパターン・タイプです。従って、新しいパターン・タイプが仮想アプリケーション・ビルダーに表示されないように、patterntype.json ファイルに「”builder”: false」と追加します (図 2 を参照)

図 2. builder を false に設定する
builder を false に設定する JSON コードのスクリーン・キャプチャー
builder を false に設定する JSON コードのスクリーン・キャプチャー

拡張プラグイン

次は、「WASCustomPlugin」という名前の「IBM Workload Plug-in Project」を作成して、拡張プラグインを含めます (図 3 を参照)。新しく作成した WASCustomPatternType パターン・タイプを、1 次パターン・タイプとして設定します (図 4 を参照)。

図 3. 新規プラグインの作成
新規プラグインを作成する画面のスクリーン・キャプチャー
新規プラグインを作成する画面のスクリーン・キャプチャー
図 4. 1 次パターン・タイプの選択
1 次パターン・タイプを選択する画面のスクリーン・キャプチャー
1 次パターン・タイプを選択する画面のスクリーン・キャプチャー

拡張コンポーネントを既存のパターン・タイプ内で使用できるようにするには、2 次パターン・タイプを拡張対象のパターン・タイプに設定する必要があります。

  1. 2 次パターン・タイプの名前とバージョン番号を調べるために、ブラウザーを開いて、PureApplication System にログオンします。「Workload Console (ワークロード・コンソール)」を選択して、「Patterns (パターン)」 > 「Virtual Applications Patterns (仮想アプリケーション・パターン)」の順に進みます。
  2. 続いて、ドロップダウン・ボックスから既存のパターン・タイプを選択します。この例で拡張しているのは「Web Application Pattern Type 2.0」パターン・タイプなので、ドロップダウンの値として「Web Application Type 2.0」を選択します。
  3. 次に、リスト内のいずれかのアプリケーションを選択して、そのアプリケーション ID (図 5 を参照) をメモに書き留めます。
    図 5. アプリケーション ID を書き留める
    アプリケーション ID を書き留めるための画面のスクリーン・キャプチャー
    アプリケーション ID を書き留めるための画面のスクリーン・キャプチャー
  4. ワークロード・コンソールで、「System (システム)」 > 「Storehouse Browser (Storehouse ブラウザー)」の順に進みます。Storehouse ブラウザーでは、「user/」 > 「applications/」の順に展開し、該当するアプリケーション ID を選択します。
  5. そして「Get Contents (New Window) (コンテンツの取得 (新規ウィンドウ))」をクリックすると、新しいブラウザー・ウィンドウに appmodel.json ファイルが開きます (図 6 を参照)。
    図 6. アプリケーション・モデルの JSON 文書を新しいウィンドウに開く
    アプリケーション・モデルの JSON 文書を新しいウィンドウに開いた画面のスクリーン・キャプチャー
    アプリケーション・モデルの JSON 文書を新しいウィンドウに開いた画面のスクリーン・キャプチャー

    この JSON ファイルの model セクションにある patterntype 属性と version 属性は、パターン・タイプの名前とバージョンを表しています。この 2 つの属性から、この例では 2 次パターン・タイプとして名前が「webapp」で、バージョンが「2.0」のパターン・タイプを追加する必要があることがわかります (図 7 を参照)。

    図 7. 2 次パターン・タイプを追加する
    2 次パターン・タイプを追加する画面のスクリーン・キャプチャー
    2 次パターン・タイプを追加する画面のスクリーン・キャプチャー
  6. これで、プラグインのスケルトンを作成できたので、次はプラグイン実装を提供して、既存のパターンの機能を拡張する準備ができました。

「IBM Workload Plug-in Project」ウィザードはデフォルトで、4 つのライフサイクル管理スクリプト (install.pyconfigure.pystart.pystop.py) を含めた 1 つのロールを作成します。それぞれのライフサイクル管理スクリプトの目的についての詳細は、第 1 回を参照してください。ロールの名前は、プラグイン名として設定した値から派生します。この例では、プラグインの名前が plugin.custom.wasextend に設定されていることから、ロールの名前は WASEXTEND となります。

この記事で取り上げる例」セクションで説明したように、拡張プラグインのテストに使用するサンプル・アプリケーションは、URL リソース参照を利用して外部プロパティー・ファイルを参照します。この外部プロパティー・ファイルが、拡張プラグイン WASCustomPlugin が提供するコンポーネントの属性値としてアップロードされて、仮想アプリケーションの artifacts ディレクトリーに保管されます (図 8 を参照)。

図 8. プロパティー・ファイルの場所
プロパティー・ファイルの場所を示す画面のスクリーン・キャプチャー
プロパティー・ファイルの場所を示す画面のスクリーン・キャプチャー

仮想アプリケーションをデプロイする際には、このプロパティー・ファイルを WebSphere Application Server をホストする仮想マシンのカスタム・ディレクリーにコピーする必要があります。これは 1 回限りのアクティビティーであるため、WASEXTEND ロールのインストール中に実行されます。リスト 1 に、install.py ライフサイクル管理スクリプトを実装するコードを示します。

リスト 1. 入力プロパティー・ファイルをダウンロードするコード
import logging
import maestro
import os

logger = logging.getLogger('WASEXTEND/install.py')
logger.debug("CUSTOM - In WASEXTEND/install.py...")

# Initialize variables
logger.debug("CUSTOM - parameters: %s" % maestro.parms)
CUSTOM_CONF_DIR = '/opt/CustomApp/config'
CONF_FILE_URL   = maestro.parms['CFG_FILE']

# Get base file name of uploaded configuration file
configBaseName = CONF_FILE_URL.rsplit('/')[-1]

# If not already there, create custom app directory that will contain
# the uploaded configuration file
if os.path.exists(CUSTOM_CONF_DIR) == False:
    os.makedirs(CUSTOM_CONF_DIR)
    logger.debug("CUSTOM - Created directory: %s" % CUSTOM_CONF_DIR)

configFile = os.path.join(CUSTOM_CONF_DIR, configBaseName)

# Finally, download the uploaded file from the storehouse
# and copy it to the custom directory
logger.debug("CUSTOM - Downloading %s" % configBaseName +
             " from the Storehouse and copying it to %s" % CUSTOM_CONF_DIR)

maestro.download(CONF_FILE_URL, configFile)
# Export the complete path to the config file as an variable to be picked
# up by the dependent WAS role
maestro.role['CFG_FILEPATH'] = configFile

logger.debug('CUSTOM - Leaving WASEXTEND/install.py')

「os」という名前の Python モジュールの makedirs メソッドは、プロパティー・ファイルのカスタム・ディレクトリーを作成します。「maestro」という名前の Python モジュールの download メソッドは、1 番目の引数で指定された成果物をダウンロードして、2 番目の引数で指定された場所に格納します。

従属ロール

プロパティー・ファイルを仮想マシンにコピーするだけでなく、実際の URL リソース参照も拡張プラグインによって定義する必要があります。それには、WebSphere Application Server が稼働状態でなければなりません。リソース参照を定義する前にアプリケーション・サーバーが稼働状態になっていることを確実にするには、WebSphere Application Server をインストール、構成、起動するロールと WASEXTEND ロールとの間の依存関係を作成する必要があります。

Web Application Pattern パターン・タイプに定義されている WebSphere Application Server ロールの名前を取得するには、以下の手順に従います。

  1. PureApplication System のワークロード・コンソールにログインして、拡張対象のパターン・タイプのインスタンスをデプロイします。デプロイメントのステータスは、「Instances (インスタンス)」 > 「Virtual Application Instances (仮想アプリケーション・インスタンス)」の順に選択することでモニターすることができます。
  2. 仮想アプリケーションが正常にデプロイされたら、そのインスタンスを選択し、「Middleware perspective (ミドルウェア・パースペクティブ)」を調べます (図 9 を参照)。

このパースペクティブには、該当する仮想アプリケーションに対して定義されているすべてのロールが一覧表示されます。このサンプル・デプロイメントでは、Sample Java EE Web Application のインスタンスをデプロイしました。これは、拡張対象の Web Application Pattern パターン・タイプに基づく仮想アプリケーションです。Sample Java EE Web Application は、2 つの仮想マシンをインスタンス化します。1 つはアプリケーション・サーバー用の仮想マシン、もう 1 つはデータベース・サーバー用の仮想マシンです。このパースペクティブで調べなければならないのは、アプリケーション・サーバーをホストする仮想マシンだけです。というのも、アプリケーション・サーバー上でリソース参照を作成しなければならないためです。ミドルウェア・パースペクティブを見ると、WebSphere Application Server をインストールして構成するロールは、WAS ロールとなっています。従って、WASEXTEND ロールは、このロールに依存することになります。

図 9. ターゲット・ロールを判別する
ターゲット・ロールを判別する画面のスクリーン・キャプチャー
ターゲット・ロールを判別する画面のスクリーン・キャプチャー
  1. 拡張プラグインに WASEXTEND ロールと WAS ロールの間の依存関係を定義するには、Plug-in Development Kit を開き、プラグイン・プロジェクトを選択します。
  2. プロジェクトを右クリックして、「New Plug-in Role (新規プラグイン・ロール)」を選択します。次に、新規ロールの名前を指定します (図 10 を参照)。ここでは依存関係を定義しているので、新規ロールの名前を <source_role>,<target_role> という形式で設定する必要があります。この例の場合、WASEXTEND ロールが WAS ロールに依存します。従って、ソース・ロールには WASEXTEND を設定し、ターゲット・ロールには WAS を設定するので、プラグイン・ロールの名前は WASEXTEND.WAS になります。
    図 10. ソース・ロールと WAS ロールの間の依存関係を定義する
    ソース・ロールと WAS ロールの間の依存関係を定義する画面のスクリーン・キャプチャー
    ソース・ロールと WAS ロールの間の依存関係を定義する画面のスクリーン・キャプチャー
  3. 「New Plug-in Role (新規プラグイン・ロール)」ダイアログで、新規ロールがソース・ロールと同じ scripts ディレクトリーに作成されていることを確認します。また、このダイアログで「Create directory structure as well as the following script stubs (ディレクトリー構造と以下のスクリプト・スタブを作成する)」オプションを選択し、changed.py ライフサイクル管理スクリプトだけを選択します (図 10 を参照)。changed.py スクリプトは、WAS ロールのライフサイクルで変更が発生するとトリガーされます。これがまさに、私たちが必要としているアクションです。依存関係についての詳細は、この連載の第 1 回の記事を参照してください。
  4. これでロール間の依存関係が定義され、changed.py スクリプトのスタブが生成されたので、URL リソース参照を作成するためのコードを作成する準備が整いました。

このリソース参照は、WebSphere 管理コマンドが含まれる Jython スクリプトを使用して、サーバー・スコープ・レベルで JNDI 名前空間に追加されます。これらのスクリプトを実行するには、アプリケーション・サーバーが稼働状態でなければなりません。スクリプトが正常に完了した後は、変更を適用するために再起動が必要です。リスト 2 に、この実装方法を示します。スクリプトの完全なバージョンは、この記事に付属のソース・コードに含まれています。

リスト 2. URL リソース参照を追加するコード
# Check if the updated/added role is the WAS component and whether it is up and RUNNING
if '.WAS' in wasRole and statuses[wasRole] == 'RUNNING':    
 existsURL = maestro.trace_call(logger,
				     ['sh', '/opt/IBM/WebSphere/AppServer/bin/wsadmin.sh',
                                   '-lang', 'jython', '-f', maestro.node['scriptdir'] +
                                   '/WASEXTEND/WAS/existsURLResourceRef.py'])    
 logger.debug("CUSTOM - Result of call to existsURLResourceRef is: %s" % existsURL)
 
# If return code > 0, the resource reference does not exist and needs to be
# added to WAS.
if existsURL > 0:
  logger.debug("CUSTOM - Calling addURLResourceRef.py to add URL Resource
				Reference to WAS...")
  configFile = maestro.role['CFG_FILEPATH']        
  rc = maestro.trace_call(logger,
			['sh', '/opt/IBM/WebSphere/AppServer/bin/wsadmin.sh', '-lang',
                      'jython', '-f', maestro.node['scriptdir'] +
                      '/WASEXTEND/WAS/addURLResourceRef.py', configFile])
  maestro.check_status(rc, 'Failed to execute wsadmin jython script!!')            
  logger.debug("CUSTOM - Restarting server to get JNDI directory updated.")
  restart_server()              
  maestro.role_status = 'RUNNING'
logger.debug("CUSTOM - Leaving WASEXTEND/WAS/changed.py...")

コンポーネントとリンクを定義する

ここまででパターン・タイプと、拡張機能を実装するために必要なロールと依存関係が含まれる拡張プラグインを作成しました。このパターン・タイプを PureApplication System にインストールするとします。さらに、仮想アプリケーション・ビルダーを開いて、拡張対象のパターン・タイプをベースに新しい仮想アプリケーション・パターンを作成するとします。その場合、拡張プラグインに関連付けられていて、キャンバス上にドラッグ・アンド・ドロップできる成果物は 1 つも見つかりません。その理由は、独自のプラグインを使って仮想アプリケーション・パターンを作成するときにパターン・ビルダーで使用できるようにしたいアプリケーション・モデルの要素をまだ定義していないためです。

これらの要素を定義するには、コンポーネント要素のメタデータを指定して、パターン・ビルダーが外部プロパティー・ファイルをアップロードできるようにしなければなりません。WebSphere Application Server に対する依存関係を指定するには、このコンポーネントを Web Application Pattern パターン・タイプのエンタープライズ・アプリケーション・コンポーネントと Web アプリケーション・コンポーネントにリンクできるようにする必要があります。

  1. コンポーネント要素のメタデータを作成するために、Plug-in Development Kit を開いて、IBM Workload Plug-in Project 内の config.json ファイルをダブルクリックします。
  2. 続いて「Application Model (アプリケーション・モデル)」タブを選択し、「Add (追加)」をクリックします。これにより、「Create a New Metadata (新規メタデータの作成)」ウィンドウがポップアップ表示されます。
  3. タイプとして「component (コンポーネント)」を選択し、「OK」をクリックします。これで、アプリケーション・モデルのコンポーネントが作成されるので、このコンポーネントに適切な ID、ラベル、説明を指定する必要があります。さらに、コンポーネントを表すアイコンと、外部プロパティー・ファイルを表す属性も指定する必要があります。
  4. 仮想アプリケーション・ビルダーでこのコンポーネントを独立したカテゴリーとして表示するために、コンポーネント詳細の「Category (カテゴリー)」フィールドに、このコンポーネントを説明する独自の値を入力します。また、ローカライズをサポートするために、「Label (ラベル)」「Description (説明)」の各フィールドにはプレースホルダーを使用します。ラベルと説明の実際の値は、messages.json ファイルに記載します。このファイルは、プラグイン・プロジェクト内で「plugin」 > 「appmodel」 > 「locales」の順に展開すると、見つかります。図 11 に、カスタム・コンポーネントのメタデータを示します。
    図 11. カスタム・コンポーネントを定義する
    カスタム・コンポーネントを定義する画面のスクリーン・キャプチャー
    カスタム・コンポーネントを定義する画面のスクリーン・キャプチャー
  5. 次に、「Application Model (アプリケーション・モデル)」エディターをもう一度開き、「Add (追加)」をクリックしてリンクを作成します。「link (リンク)」に対してタイプの値を設定してから「OK」をクリックします。
  6. この場合も、ID、ラベル、説明には適切な値を選択します。
  7. 最後のステップとして、このリンクに参加するコンポーネントを定義します。この例の場合、リンクが必要となるのは、Web Application Pattern パターン・タイプのエンタープライズ・アプリケーションおよび Web アプリケーション・コンポーネントと、カスタム・コンポーネントとの間です。従って、まずは「Source (ソース)」フィールドの値として、カスタム・コンポーネントの ID を指定します。このコンポーネントはプラグイン・プロジェクト内で定義されているため、「Add (追加)」ボタンをクリックしてドロップダウン・リストからカスタム・コンポーネントの ID を選択することができます。

ターゲット・コンポーネントは、拡張対象のパターン・タイプで定義されています。そのため、このコンポーネントの ID は、ドロップダウン・リストから選択可能な値にはなっていません。つまり、手作業で ID を入力しなければならないため、その ID をどこで調べられるかを知っておく必要があります。それには、アプリケーション・モデルの JSON 文書を開きます。アプリケーション・モデルの JSON 文書を表示する方法についての詳細は、「拡張プラグイン」のセクションを参照してください。

  1. アプリケーション・モデルの JSON 文書を開いたら、この文書の models > nodes セクションの下にある「id: “application”」という部分を検索し、この type フィールドの値をコピーしてください (この例の場合、値は “EAR” です)。図 12 に、該当するセクションを示します。Web アプリケーション・コンポーネントの値も、同じようにして取得することができます。
    図 12. アプリケーション・モデルの JSON 文書から取得するコンポーネント ID
    アプリケーション・モデルの JSON 文書から取得するコンポーネント ID のスクリーン・キャプチャー
    アプリケーション・モデルの JSON 文書から取得するコンポーネント ID のスクリーン・キャプチャー
  2. 「Application Model (アプリケーション・モデル)」エディターで、ターゲットの「Add (追加)」ボタンをクリックします。エンタープライズ・アプリケーション・コンポーネントへのリンクを定義するには、ターゲット値として「EAR」と入力し、Enter キーを押します。Web アプリケーション・コンポーネントへのリンクを定義するには、ターゲット値として「WAR」と入力します。図 13 に、以上のステップで定義したリンクに対するメタデータ定義を示します。
    図 13. リンクを定義する
    リンクを定義する画面のスクリーン・キャプチャー
    リンクを定義する画面のスクリーン・キャプチャー

OSGI サービス・コンポーネントを定義する

ここまでで、Web Application Pattern パターン・タイプを拡張する新しい仮想アプリケーション・パターンを作成するためのパターン・タイプ、プラグイン、必要なコンポーネントとリンクの作成が完了しました。ただし、この時点でデプロイしても成功しません。それは、アプリケーション・モデルをトポロジー文書に変換するために必要な OSGI サービス・コンポーネントがまだ欠けているためです。この連載の最初の記事では、この変換がどのように行われるのかを説明し、その手段として以下の 2 つの選択肢を挙げました。

  • Velocity テンプレート・ベースのトポロジー・プロバイダー
  • Java ベースのトポロジー・プロバイダー

この例では既存のパターン・タイプのすぐに使用可能な機能を拡張しているので、パターンの一部として仮想マシンを追加する必要はありません。コンポーネント変換では、追加の仮想マシンを使用しなくても済むように、カスタム・コンポーネントを通常の vm-template としてではなく、service コンポーネントとして変換する必要があります。

maestro フレームワークで拡張プラグインのライフサイクル・スクリプトを実行可能にするには、WASEXTEND ロールのすべてのスクリプトが含まれるパッケージが、WebSphere Application Serverをホストする仮想マシンにコピーされていなければなりません。それには、WASEXTEND ロールを WAS vm-template に追加する必要があります (図 14 を参照)。これにより、maestro フレームワークが WAS ロールを管理する仮想マシン上で、実行時に拡張機能を実行できるようになります。トポロジー文書に WAS ロールと WASEXTEND ロールの間のリンクを依存関係として含めて、WAS ロールで提供するスクリプトの実行後に、WASEXTEND ロールで提供する拡張スクリプトが実行されるようにします。

図 14. WAS VM テンプレートに追加した、サービス・コンポーネントとしての WASEXTEND
WAS VM テンプレートに追加した、サービス・コンポーネントとしての WASEXTEND のスクリーン・キャプチャー
WAS VM テンプレートに追加した、サービス・コンポーネントとしての WASEXTEND のスクリーン・キャプチャー

この例では、サービス・コンポーネントを作成し、Javaベースのトポロジー・プロバイダーを使用してロール、依存関係、パッケージをトポロジー文書に追加することにしました。連載の第 1 回で説明したように、Javaベースのトポロジー・プロバイダーが生成する Java クラスには、transformComponent メソッドと transformLink メソッドの 2 つが含まれます。アプリケーション・モデルをトポロジー・モデルに変換するには、この 2 つのメソッドを実装する必要があります。

サービス・コンポーネントを作成する

カスタム・コンポーネントを対象とした、標準的な Velocity テンプレート・ベースのトポロジー・プロバイダーは、リスト 3 に記載するような vm-template になります。

リスト 3. vm-template の JSON フラグメントの例
{
    "vm-templates": [
        {
            "persistent": false,                 
            "name": "${prefix}",
            "roles": [
                {
                    "parms": {
		       "CFG_FILE": "artifacts\/config.txt"
                    },
                    "type": "WASEXTEND",
                    "name": "WASEXTEND"
                }
            ],
            "packages": [
                "WASEXTEND"
            ]
        }
    ]
}

ただし、上記のテンプレートはデプロイ中に追加の仮想マシンを生成します。これを防ぐには、前の段落で説明したように、カスタム・コンポーネントをサービス・コンポーネントに変換する必要があります (リスト 4 を参照)。

リスト 4. サービス・コンポーネントの JSON フラグメント
{
    "service":"Customize_WAS",
    "attributes":
        {
            "CFG_FILE": "artifacts\/config.txt",
            "type": "EXTERNALCONFIG",
            "id": "Customize WAS"
        }
 }

この JSON フラグメントを生成するコードは、transformComponent メソッド内で実装します。リスト 5 に、その実装の一例を記載します。

リスト 5. transformComponent の実装
public JSONObject transformComponent(String prefix,
                                     String applicationUrl,
		                      JSONObject component,
                                     Transformer transformer) throws Exception {

    logger.info("CUSTOM - In custom written transformComponent...");
     	
    // Defines template to store the custom service component	  		
    JSONObject custTemplate = new JSONObject();  
    
    // Defines the attributes for the custom service template.
    JSONObject custTemplateAttrs = new JSONObject();      
                                                      
    // Obtain the custom component's attributes.
    JSONObject customCompAttributes = (JSONObject) component.get("attributes");  
    
    logger.fine("CUSTOM - component attributes" + customCompAttributes.toString());
    
    // Construct the attributes section of the above JSON fragment
    custTemplateAttrs.put("id", (String) component.get("id"));
    custTemplateAttrs.put("type", (String) component.get("type"));
    custTemplateAttrs.put(CUSTOMCOMP_VAR1, customCompAttributes.get(CUSTOMCOMP_VAR1));
    	
    // Use the prefix as the value for the service component and
    // add the attributes section to the service template.
    custTemplate.put("service", prefix);
    custTemplate.put("attributes", custTemplateAttrs);
	
    logger.fine("CUSTOM - custTemplateAttrs: " + custTemplateAttrs.toString());

    logger.info("CUSTOM - custTemplate: " + custTemplate.toString());
    logger.info("CUSTOM - Leaving transformComponent");

    return custTemplate;
}

トポロジー文書をカスタムのロール、依存関係、パッケージで更新する

最後のステップは、WASEXTEND ロール、このロールの WAS ロールに対する依存関係、そして WASEXTEND パッケージのすべてがトポロジー文書に追加されることを確認します。トポロジー・プロバイダーの transformLink メソッドが、アプリケーション・モデルのリンク定義に従ってトポロジー文書を更新します。つまり、ターゲット WAS ロールに対応する vm-template の JSON フラグメントを更新して、WASEXTEND ロールを含める必要があります (リスト 6 を参照)。

リスト 6. WASEXTEND ロールが含まれるトポロジー文書の WAS フラグメント
"vm-templates": [
    {
        "parts": [ … ],
        "licenses": [ … ],
        "node-parts": [ … ],
        "scaling": { … },
        "persistent": false,
        "update": { … },
        "name": "Enterprise_Application-was",
        "image": { … },
        "roles": [
            { … },
            {
                "plugin": "plugin.custom.wasextend/1.0.0.0",
                "depends": [
                    {
                        "role": "Enterprise_Application-was.WAS",
                        "parms": {
                            "config_file": "artifacts/config.txt"
                        },
                        "type": "WAS"
                    }
                ],
                "parms": {
                    "CFG_FILE": "https://127.0.0.1:9444/storehouse
                                 /user/deployments
                                 /d-e37a6028-6bf4-492d-b810-3c7e0c724647
                                 /artifacts/config.txt"
                },
                "type": "WASEXTEND",
                "name": "WASEXTEND"
            },
            { … },
            { … },
            { … },
            { … },
            { … },
            { … },
            { … }
        ],
        "packages": [
            "WAS32",
            "WAS",
            "WASEXTEND",
            "MONITORING",
            "logbackup",
            "sharedservice",
            "SSH",
            "temclient",
            "MAINTENANCE",
            "AGENT",
            "RHUSCLIENTPACKAGE"
        ]
    }
],

このようにするには、最初にターゲット・コンポーネントのトポロジー文書から vm-template を取得し、その vm-template から該当ロールの JSON フラグメントを抽出する必要があります。この方法を、リスト 7 に記載するコード・スニペットに示します。

リスト 7. ターゲット・ロールの JSON フラグメントの取得
// Obtain the target role. In this case, the WAS component of the webapp 2.0 pattern
TopologyProvider.MatchedRole existingTarget = getMatchedRole(targetFragment, "WAS");

// The template fragment of the WAS target.
JSONObject wasTemplate = existingTarget.template;				

// Obtain the target roles. The source role is added here.
JSONArray wasRoles = (JSONArray) wasTemplate.get("roles");

リスト 7 で定義されている JSON 配列オブジェクト wasRoles には、ターゲット・ロールに対応する JSON フラグメントが含まれます。この配列オブジェクトを更新して、ソース・ロール WASEXTEND とこれに「依存する」セクションをともに組み込むことができます。これらのオブジェクトは、リスト 8 に記載するコードのように作成することができます。

リスト 8. ソースと依存関係の JSON フラグメントの作成
// Initialize the source role object.
JSONObject sourceRole = new JSONObject();

// Initialize the dependencies of our source role.
// In this case only the dependency with WAS is added here.
JSONArray depArray = new JSONArray(); 						

// Initialize the object that will contain the WAS dependency.
JSONObject depObject = new JSONObject();  

// Initialize the object that will contain the dependency parameters.
JSONObject depParms = new JSONObject();

// Initialize the object that will contain the source role parameters.
JSONObject sourceParms = new JSONObject();

sourceRole.put("name", "WASEXTEND");
sourceRole.put("type", "WASEXTEND");
sourceRole.put("plugin", getPluginScope());

// Defines the depends section in the "WASEXTEND" JSON fragment.
String depRole = wasTemplate.get("name") + "."  + "WAS";
depObject.put("role", depRole);
depObject.put("type", "WAS");

// Obtain attributes from the source fragment
JSONObject sourceAttr = (JSONObject) sourceFragment.get("attributes");

// The parameters defined in the parms section of the depends role will be available
// as xparms in the changed.py lifecycle script of the target role.
depParms.put("config_file",  sourceAttr.get(CUSTOMCOMP_VAR1));
sourceParms.put(CUSTOMCOMP_VAR1, applicationUrl + sourceAttr.get(CUSTOMCOMP_VAR1));

// Add the dependency parameters to the dependency JSON fragment
depObject.put("parms", depParms);
depArray.add(depObject);

// Add the dependency fragment to the source JSON fragment
sourceRole.put("depends", depArray);

// Add the parameters that need to be available in the source JSON fragment
sourceRole.put("parms", sourceParms);

最後に、ターゲット・コンポーネントのトポロジー文書の vm-template を、更新後の wasRoles JSON フラグメントおよび WASEXTEND パッケージで更新する必要があります。そのためのコードは、リスト 9 のとおりです。

リスト 9. 更新後のロール・フラグメントと WASEXTEND パッケージの追加
// Add our source role (WASEXTEND) to the roles section of our target template.
wasRoles.add(sourceRole);

// Obtain the packages JSON fragment from vm-template
JSONArray wasPackages = (JSONArray) wasTemplate.get("packages");

// Ensure the package of the custom written plug-in is added to the packages section
// of the WAS component. That way, all necessary scripts are copied to the WAS VM.
if ((wasPackages != null) && (!wasPackages.contains("WASEXTEND")))
    wasPackages.add("WASEXTEND");

transformLink メソッドの完全な実装については、付属のソース・コードを参照してください。これで実装が完了したので、アプリケーション・モデルを適切なトポロジー文書に変換し、パターン・タイプをビルドして PureApplication System にデプロイできるようになりました。

パターン・タイプをビルドしてインストールする

このセクションでは、前のセクションで作成したプラグインとパターン・タイプ・プロジェクトをビルドしてデプロイする方法を説明します。

  1. WASCustomPatternType プロジェクトを右クリックし、プラグインとパターン・タイプをビルドするために「IBM Pattern Toolkit」 > 「Build (ビルド)」の順に選択します。このアクションにより、WASCustomPatternType/export/ の下に patterntype.was.custom-1.0.0.0.tgz という名前のパターン・タイプ・アーカイブ・ファイルが作成されます。このビルド済みパターン・タイプ・アーカイブ・ファイルをインストールするには、Plug-in Development Toolkit と PureApplication System のどちらでも使用することができます。
  2. Plug-in Development Toolkit を使用してパターン・タイプをデプロイする場合は、最初に「Windows (ウィンドウ)」 > 「Preferences (設定)」 > 「IBM Pattern Toolkit」の順に選択して、デプロイヤーのホスト名、ユーザー ID、パスワードを定義する必要があります。これらを定義した後、WASCustomPatternType プロジェクトを右クリックし、「IBM Pattern Toolkit」 > 「Install/update to deployer (デプロイヤーにインストール/更新)」アクションを順に選択して、パターン・タイプをインストールします。
  3. PureApplication System を使用してパターン・タイプをデプロイする場合は、システムにログインし、ワークロード・コンソールで「Cloud (クラウド)」 > 「Pattern Types (パターン・タイプ)」 > 「New (新規)」(プラス記号) の順に選択します。このアクションにより、「Install a pattern type (パターン・タイプのインストール)」ダイアログが開きます。このダイアログで、patterntype.was.custom-1.0.0.0.tgz ファイルの場所を参照し、「OK」をクリックしてパターン・タイプをインストールします。

この記事で取り上げる例をテストする

このセクションでは、拡張プラグインのテスト方法を説明します。作成した拡張機能をテストするには、記事に付属の SampleWebAppEAR.ear ファイルを使用します。このサンプル・アプリケーションは、プロパティー・ファイルからプロパティーを読み取って表示します。プロパティー・ファイルは、作成した拡張プラグインによって WebSphere Application Server 構成に追加される URL リソース参照によって管理されます。

  1. テストを行うには、まず、前のセクションで説明した手順に従ってインストールした WAS のカスタム・パターン・タイプを有効にします。
  2. パターン・タイプが有効になったら、「Patterns (パターン)」 > 「Virtual Applications (仮想アプリケーション)」 > 「Web Application Pattern Type 2.0」の順にクリックして、仮想アプリケーション・ビルダーで新規パターンを作成します (図 15 を参照)。
  3. エンタープライズ・アプリケーション・コンポーネントの「EAR file (EAR ファイル)」フィールドの入力として SampleWebAppEAR.ear を使用し、Customize WAS コンポーネントの「Property file (プロパティー・ファイル)」フィールドの入力として、名前と値のペアが含まれるプロパティー・ファイルを使用します。この記事には、サンプル・プロパティー・ファイルが付属しています。
    図 15. Web Application Pattern パターン・タイプの拡張
    Web Application Pattern パターン・タイプを拡張する画面のスクリーン・キャプチャー
    Web Application Pattern パターン・タイプを拡張する画面のスクリーン・キャプチャー
  4. パターンを保存してデプロイすると、図 16 に示すように、1 つの仮想マシンを実行するパターン・インスタンスが表示されます。Customize WAS コンポーネントはトポロジー文書で「サービス」に変換したため、この追加コンポーネントにインスタンス化される新しい仮想マシンはありません。このインスタンスには、新しいロール WASEXTEND も表示されています。このロールは、WAS ロールが提供する WebSphere Application Server 基本構成を拡張するために拡張プラグインで指定したロールです。
    図 16. 拡張された Web Application Pattern インスタンス
    拡張された Web Application Pattern インスタンスのスクリーン・キャプチャー
    拡張された Web Application Pattern インスタンスのスクリーン・キャプチャー
  5. 拡張プラグインが提供する機能を確認するには、「Endpoint (エンドポイント)」のリンクを選択して、サンプル・エンタープライズ・アプリケーション SampleWebAppEAR を実行します。注意する点として、PureApplication System Elastic Load Balancer の DNS マッピングが構成されたホスト・ファイルが必要です。このマッピングをセットアップする方法についての詳細は、IBM PureApplication System のヘルプ・トピック「伸縮可能ロード・バランシング・プロキシー・サービス」を参照してください。図 17 に示されているように、「Endpoint (エンドポイント)」のリンクをクリックすると、入力プロパティー・ファイルに指定されたプロパティーの名前と値のペアを含んだ Web ページが表示されます。SampleWebAppEAR アプリケーションには、新しく構成された URL リソース参照を使用して値を取得するサーブレットが含まれます。アプリケーションは、このサーブレットをユーザーに表示します。
    図 17. 拡張 URL リソース参照を使用して取得されたプロパティー・ファイルを表示するサーブレット
    拡張 URL リソース参照を使用して取得されたプロパティー・ファイルを表示するサーブレットのスクリーン・キャプチャー
    拡張 URL リソース参照を使用して取得されたプロパティー・ファイルを表示するサーブレットのスクリーン・キャプチャー

まとめ

この記事では、新しい拡張パターン・タイプを提供することによって、既存のパターン・タイプをカスタマイズする方法を説明しました。この手法では、元のパターン・タイプのソース・コードを一切変更することなく、元のパターン・タイプを拡張することができます。しかも、この手法によって、追加の仮想マシンが作成されないようにすることもできます。

謝辞

この連載記事を寄稿する機会を与えてくれただけでなく、記事をレビューしてフィードバックを提供してくれた IBM の José De Jesús 氏に感謝いたします。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere, Cloud computing
ArticleID=973534
ArticleTitle=仮想アプリケーション・パターンのプラグインを作成する: 第 2 回 既存のパターン・タイプを拡張してカスタマイズする
publish-date=06122014