目次


クラウドをポケットに入れて持ち歩く

第 1 回 サーバー・リストを管理する

SoftLayer サーバーに関する情報を表示するモバイル・アプリケーションを作成する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: クラウドをポケットに入れて持ち歩く

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

このコンテンツはシリーズの一部分です:クラウドをポケットに入れて持ち歩く

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

この全 2 回からなる連載では、HTML5、CSS、および JavaScript/jQuery によるユーザー・インターフェースを介して SoftLayer サーバーを管理するためのアプリケーションの作成方法を学びます。第 1 回では、モバイル端末に仮想サーバーに関する情報を表示して管理する方法を説明します。第 2 回では、モバイル端末上でサーバーをオーダーして構成する方法を説明します。

最近取り組んだプロジェクトがきっかけで、私は SoftLayer API を使用した統合について詳しく調べてみました。curl と json_reformat を使用して REST API をいろいろと試した結果、SoftLayer の IaaS (Infrastructure-as-a-Service) を管理する上で便利なモバイル・アプリケーションを作成するのは、それほど難しくないはずであるという結論に至りました。そこでこれから、そのようなモバイル・アプリケーションを作成するために私が使用したパターンを説明し、どのようにすればニーズに合わせて簡単にアプリケーションを拡張できるかを明らかにします。

アプリケーションを構築するために必要となるもの

  • モバイル・アプリケーションを作成するための開発環境 (IBM Worklight FoundationApache Cordovaなど)。
  • CloudInAPocket という名前のプロジェクト。このプロジェクトのコード・サンプルは、開発環境の中に作成されたサンプル index.html があるディレクトリーに解凍します。
  • HTML5/CSS/JavaScript および jQuery/jQuery Mobile に関する十分な知識
  • SoftLayer アカウント

ヒント

ターンアラウンド・タイムを短縮するには、アプリケーションを任意の Web サーバーの文書ディレクトリーに配置して、Web ページとして Chrome で実行してください。Chrome には Web セキュリティー (サード・パーティー・ポリシー) を無効にするスイッチがあります。Chrome のすべてのインスタンスを停止した後、–disable-web-security スイッチを指定して Chrome を再起動するだけで、Chrome で開くすべてのページに対し、Web セキュリティーが無効になります。

Ripple をモバイル端末エミュレーターとして追加することもお勧めします。

一般的なパターンの概要を見る

アプリケーションの作成方法の詳細に入る前に、私がこのアプリケーションを開発するときに適用したいくつかのパターンの概要を見てみましょう。

JavaScript でのオブジェクト指向の手法

アプリケーション全体を通して、私は Java のオブジェクト指向の概念を JavaScript にマッピングしました (リスト 1 を参照)。

リスト 1. JavaScript: オブジェクト指向の概念のマッピング
var MyClass = function(args) {       // myClass is a class to be defined
   var thiz=this;                    // save instance var to private var
   this.publicvar = "hello world"    // equivalent of "public:" member in Java
   this.publicfun = {}               // equivalent of "public:" method in Java
   var privatevar = "hello world"    // equivalent of "private:" member in Java
   var privatefun = {                // equivalent of "private:" method in Java
     // access to public var in a method:
     thiz.publicvar = "new value";
     // access to private var
     privatevar = "new value";
     // same for public/private function
     thiz.publicfun(args);
     privatefun(args);
   }
}

Java とは異なり、JavaScript にはインスタンス変数がありません。JavaScript には this という変数がありますが、この変数はクラス・メソッドの内部で任意の値を持つことができます。このパターンを使用すると、アプリケーション内でクラス・インスタンスのインスタンス変数に簡単にアクセスすることができます。このインスタンス変数には、this と密接な関係があることを忘れないように、thiz という名前が付けられています。

関数の引数としての匿名オブジェクト

クラス・メソッドに含める引数の数が多くならないように、呼び出しの引数として匿名オブジェクトを使用するというパターンを適用しました。こうすることで拡張が容易になり、関数の引数を位置で渡す (その位置によって引数の型と値が決まります) のではなく、名前で渡せるようになります。

非同期の動作

SoftLayer の REST API を多用するこのアプリケーションは、非同期 Ajax 呼び出しを実行します。この呼び出しでは、成功用の引数と、失敗用の引数を指定します。Ajax (あるいは抽象メソッドのいずれか 1 つ) を使用する関数でも、ネットワーク呼び出しの結果を評価するために、成功用の引数と、失敗用の引数を指定します (リスト 2 を参照)。

リスト 2. JavaScript: 成功用の引数と、失敗用の引数
var MyClass = function(args) {		// myClass is a class to be defined
    this.getCenters() {
    var args={success: thiz.getCentersSuccess, error: thiz.getCenterError};
        SoftLayer.Location.centers(args);
    }
    this.getCentersSuccess(args) {
        ...
    }
    this.getCentersError(args) {
        ...
    }
}

最初のアプリケーションを作成する

最初のアプリケーションは、SoftLayer の中で皆さんのアカウントに関連付けられたサーバーを参照してリストとして表示するアプリケーションです (拡張性は設計に組み込まれているので、以降のステップで、サーバーの詳細ビューを追加し、最終的に IaaS サーバーの管理機能を追加します)。サーバーのリストを表示できるようにするには、SoftLayer ポータルから 1 つ以上のサーバーをプロビジョニングする必要があります。

実際のアプリケーションでは、個別ユーザーの API 資格情報を構成する機能を提供することになるはずですが、この例では SoftLayer の REST API の使用法に重点を置くために、ユーザー名と API トークンをハードコーディングします。Credentials.js ファイル編集して、自分のユーザー名と API アクセス・キーをハードコーディングしてください。

最下位層の作業: REST API のカプセル化

このチュートリアルでは SoftLayer API に重点を置くので、API のラッピングに関する設計がアプリケーションの重要な基礎となります。私は 2 段階の抽象化を使用しています。1 段階目では、4 つの REST メソッド (GET、PUT、POST、DELETE) の jQuery-Ajax 呼び出しをラップし、それぞれのメソッドと同じ名前のメソッドとして公開します。リスト 3 にその一例として、GET メソッドを記載します。

リスト 3. JavaScript: SLAPI-GET メソッドの例
//
// The four methods get/put/post/delete are used to do some common preparation,
// i.e. ensure the return data type is json
//
SoftLayer.get = function(args) {
 try {
   // One device seemed to cache the AJAX-calls,
   // therefore an extra parameter with a changing value is appended to the URL
   var mask=(args.mask||false)?"&objectMask="+args.mask:"";
   var url=SoftLayer.apiURL+args.uri+".json?_="+(new Date().getTime())+mask;
   $.ajax({ 
    url: url,
    success: function (data, txtsts) {
      if (args.userdata.success) callargs.userdata.success(data, args.userdata);
    },
    error: function (xhdr, txtsts, errtxt) { 
      if (args.userdata.error) args.userdata.error(xhdr, txtsts, errtxt, args.userdata);
    },
    dataType: 'json'
   });
 } catch (e) {
   console.error("error SoftLayer.get"+e);
 }
}

上記のメソッドは、Ajax 呼び出し用の引数を作成して、ユーザーが提供する成功用ハンドラーと失敗用ハンドラーを呼び出します。

2 段階目では、ノースバウンドに SoftLayer API の上位レイヤーの関数 (つまり、getVirtualGuests()) を提供し、サウスバウンドでは 4 つの基本 REST メソッドのうちのいずれか 1 つを使用します (リスト 4 を参照)。

リスト 4. JavaScript: SoftLayer サービスを抽象化する
SoftLayer.Account = function() {
    var thiz = this;
    try {
        //
        // get list of virtual guests
        //
        this.getVirtualGuests = function(usrargs) {
            try {
                var callargs = {
                    userdata : usrargs,
                    uri : 'SoftLayer_Account/getVirtualGuests'
                };
                SoftLayer.get(callargs);
            } catch (e) {
                console.error("error SoftLayer.Account.getVirtualGuests:"+e);
            }
        };
    } catch (e) {
        console.error("error SoftLayer.Account:"+e);
    }
};

アプリケーションが SoftLayer API の新しい関数を必要とする場合には、getVirtualGuests() と同じようにして簡単に新規関数をメソッドとして追加することができます。

中間層の作業: アプリケーション・ロジック

認証済みアカウントに関連付けられたサーバーのリストは、REST API から取得することができますが、この API を特別なものにしているのは、オブジェクト・マスクです。オブジェクト・マスクを使用すれば、REST 呼び出しで返されたデータを、目的に応じて必要なサブセットに絞り込むことができます。サンプルのサーバー・リストでは、仮想サーバーの以下の属性を適用します。

  • 一意のサーバー ID (ID は表示されませんが、内部で使用されます。)
  • サーバーのステータスを示す色分け (赤色/停止済み、黄色/一時停止状態、緑色/実行中)
  • サーバーの完全修飾名
  • サーバーのデータ・センター
  • サーバーが作成された時刻
  • プライマリー IP アドレス
  • トランザクションがサーバーに対してアクティブであるかどうかを示すインディケーター

上記の属性は例として使用しています。他の設定を使用することもできます。

仮想サーバーのリストを取得するために呼び出されるのは、SoftLayer_Account サービスの getVirtualServers です。SoftLayer の REST API を調べると、この呼び出しが返すデータ型は SoftLayer_Virtual_Guest であることがわかります。つまり、表示したいデータとは異なるデータ・セットを受け取ることになります。

オブジェクト・マスク

オブジェクト・マスクが役立つ理由は、これを使用することで、必要に応じてレスポンスを微調整できるためです。オブジェクト・マスクは、要求されたオブジェクトに含めるデータ項目を制限することも、リレーショナル・プロパティーおよびカウント・プロパティーによってデータ項目を拡充することもできます。SoftLayer_Virtual_Guest の「Data Type (データ型)」ページには、「Local Properties (ローカル・プロパティー)」と「Relational & Count Properties (リレーショナル・プロパティーおよびカウント・プロパティー)」が見つかります。呼び出しに対して返されるデータを定義する際には、この両方のデータ型を使用することができます。

Local Properties (ローカル・プロパティー)」には、要求されるプロパティーである idcreateDate、および fullyQualifiedDomainName が含まれています。「Relational & Count Properties (リレーショナル・プロパティーおよびカウント・プロパティー)」には、datacenterprimaryIpAddressprimaryBackendIpAddress、および activeTransactionCount が見つかります。datacenter に関しては、データ・センターの名前だけが必要なので、オブジェクト・マスクを使用して datacenter.longName を指定することによって、返される値を制限することができます。完全なオブジェクト・マスクは以下のようになります。

id;createDate;datacenter.longName;powerState;fullyQualifiedDomainName;primaryIpAddress;
primaryBackendIpAddress;activeTransactionCount

注: オブジェクト・マスクは 1 行で記述する必要がありますが、読みやすくするため、上記は 2 行に分割されています。

最上位層の作業: ユーザー・インターフェース

アプリケーションを作成するには、まず、jQuery Mobile の入門ガイド (「Getting Started with jQuery Mobile」) と「Anatomy of a Page」を読んでください。このサンプル・アプリケーションの場合、初期ページに表示されるのはタスクの選択肢です (図 1 を参照)。

図 1. エントリー・ページ
Cloud-in-a-pocket アプリケーション: タスクの選択肢を表示するエントリー・ページ
Cloud-in-a-pocket アプリケーション: タスクの選択肢を表示するエントリー・ページ

このサンプル・アプリケーションでは、アカウント・データとサーバーを表示することや、新しいサーバーをオーダーすることができます。技術的には、このエントリー・ページは標準的な jQuery Mobile ページに、このアプリケーションで実行可能な選択項目のリストを表示したものであり、これらの項目は同じ HTML 文書内の他の jQuery Mobile ページを指しています。「View Servers (サーバーの表示)」を選択すると、サーバーのリストが表示されます。最初は、リスト 5 の待ち受けページが表示されます。

リスト 5. HTML: 実行可能な選択項目のページ
Index.html:
<div role="main" class="ui-content" data-theme='a'>
        <ul data-role="listview">
        <li><a href="#ciap-view-servers-waiting">View Servers</a></li>
        <li><a href="#ciap-notyet-page">Order Servers</a></li>
        <li><a href="#ciap-notyet-page">Your Account</a></li>
        </ul>
    </div>

ページ遷移には、以下のトリガーが割り当てられています。

$(document).on('pagebeforeshow', '#ciap-view-servers-waiting', thiz.onServersView);
$(document).on('pagebeforeshow', '#ciap-view-servers-page', thiz.onServersViewReady);

リストが正常に取得された場合は、thiz.onServersView メソッドが SoftLayer API を呼び出し、サーバー・リストを取得して次のページ (ciap-view-servers-page) に進みます。リスト 6 を参照してください。

リスト 6. JavaScript: 特定のユーザーに属する仮想マシンを取得する
SoftLayer.account.getVirtualGuests({
   success: function(_virtualGuests) {
      virtualGuests=_virtualGuests;
      $(':mobile-pagecontainer').pagecontainer('change',
         '#ciap-view-servers-page', { transition: 'turn'});

   },
   error: thiz.onErrorCatchall
});

サーバーのリストは、 listview として表示されます。HTML 文書内のマークアップには、ページのすべての要素と、id='ciap-view-servers-list' が指定された空の listview (アプリケーションによってリストの中身が満たされます) が含まれます (リスト 7 を参照)。

リスト 7. HTML: 特定のユーザーに属するサーバーのリストのスケルトン
<!-- list page -->
<div data-role="page" id="ciap-view-servers-page">
   <div data-role="header" >...</div>
   <div role="main" class="ui-content" >
      <ul id='ciap-view-servers-list' data-role="listview" style='display:none'></ul>
   </div>
   <div data-role="footer" data-position="fixed" style="text-align:center;">...</div>
</div>

onServersViewReady() メソッドは、最終的に結果をモバイル端末画面に表示します。この処理はループで行われます。ループでは guest.powerState を評価し、その評価に従ってテキストの色を設定し、必要な属性が指定されたリスト要素を作成します。リスト 8 を参照してください。

リスト 8. JavaScript: サーバーのステータスの色分け
if (guest.powerState||false) {
   if (guest.powerState.name == "Halted") color="red";
   if (guest.powerState.name == "Paused") color="orange";
   if (guest.powerState.name == "Running") color="green";
}

SoftLayer API は、要求されたパラメーターをすべて返すわけではありません。これは、新しくオーダーされたサーバーの場合には特に言えることです。ゲスト・オブジェクトの中で存在しないメンバーを要求することによる例外は、回避することができます。そのために選択されるパターンは以下のとおりです。

((guest.datacenter.longName||false)?guest.datacenter.longName:"<some-alternate-text>")

リスト 9 に、サーバー・リストに含まれる各エントリーがどのように作成されているかを示します。

リスト 9. JavaScript: 仮想マシンの詳細表示を生成する
var fqdn=((guest.fullyQualifiedDomainName||false)? guest.fullyQualifiedDomainName:"";
var dcname=((guest.datacenter.longName||false)?guest.datacenter.longName:"")
var pwrState=((guest.powerState.name||false)?guest.powerState.name:"");
var ipaddr1=((guest.primaryIpAddress||false)?guest.primaryIpAddress:"");
var ipaddr2=((guest.primaryBackendIpAddress||false)?guest.primaryBackendIpAddress:"");
var html="<li><a href='#' 	onclick='ciap.onServersDetailView("+guest.id+")'+
      style='color:"+color+"'>"+tx+
      "<h3>Host:"+fqdn+" in " + dcname +"</h3>"+
      "<h6>Created: "+d.toGMTString()+"</h6>"+
      "<h6>Status: "+pwrState+"</h6>"+
      "<h6>IP: "+ipaddr1+"</h6>"+
      "<h6>IP: "+ipaddr2+"</strong></h6>"+
   "</a></li>";
item.append(html);

ここで、item は、以下のように空のリスト定義に初期化された jQuery オブジェクトです。

var item=$('#ciap-view-servers-list');

リストに対する変更を jQuery Mobile に通知するには、以下のように refresh の呼び出しを実行して変更内容をフレームワークに知らせます。

item.listview('refresh');

図 2 に、サーバー・リストを示します。このリストから、サーバーの概要を把握することができます。

図 2. サーバー・リストの表示
Cloud-in-a-pocket アプリケーション: サーバー・リスト
Cloud-in-a-pocket アプリケーション: サーバー・リスト

サーバーの詳細ビュー

サーバーの概要を表示するだけでなく、特定のサーバーの詳細を表示して、そのサーバーに対して操作を行いたい場合もあります。このアプリケーションにおける拡張性とは、特定のサーバーの詳細ビューを作成して、このビューに管理機能を追加できることを意味しています。

まずは、サーバー・リストのエントリーをタッチまたはクリックして、サーバーの詳細ビューを呼び出します。これにより、ゲスト ID が指定された onServersDetailView() が呼び出されます。するとこのメソッドによって SoftLayer API が呼び出されます。ここではリスト 10 に示すように、SoftLayer クラスに VirtualGuest クラスを追加して、特定の仮想ゲストに対するメソッドを実装します。

リスト 10. JavaScript: SLAPI から仮想ゲストの詳細を取得する
SoftLayer.VirtualGuest = function () {
    var thiz = this;
    try {
        //
        // get details of one particular virtual guests
        //
        this.get = function (usrargs) {
            try {
                var callargs = {
                    userdata : usrargs,
                    uri : 'SoftLayer_Virtual_Guest/' + usrargs.guestid,
                    mask : <see test description >
                };
                SoftLayer.get(callargs);
            } catch (e) {
                console.error("error SoftLayer.VirtualGuest.getVirtualGuests:" + e);
            }
        };
    } catch (e) {
        console.error("error SoftLayer.VirtualGuest:" + e);
    }
};

返されるデータは、テーブル・ウィジェットによって jQuery Mobile ページとして表示されます。このサンプル・アプリケーションで表示する情報は以下のとおりです。

  • サーバー名
  • CPU/RAM/ブロック・デバイス
  • オペレーティング・システム
  • root または管理者の資格情報
  • 電源のステータス
  • 使用時間数
  • アクティブなトランザクション

返されたサーバー情報は、アプリケーションのプライベート・インスタンス・メンバーとして保持されます。これを使用するのは、データを server-detail-page として表示するメソッドです (リスト 11 を参照)。

リスト 11. JavaScript: SoftLayer_Virtual_Guest サービスを呼び出す
SoftLayer.virtualGuest.get({
   guestid: guestid,
   success: function(guest) {
      currentServer=guest;
      $(':mobile-pagecontainer').pagecontainer('change', '#ciap-server-detail-page');
   },
   error: thiz.onErrorCatchall
});

仮想ゲストの詳細情報を取得するための呼び出しでは、SoftLayer API に対する 1 回の呼び出しで必要なすべてのデータが取得されるようにオブジェクト・マスクが作成されます。

リスト 12. JavaScript: 仮想マシンの詳細を取得するために使用するオブジェクト・マスク
mask=  'fullyQualifiedDomainName;primaryIpAddress;maxCpu;maxMemory;'+
   'operatingSystem.softwareLicense.softwareDescription.longDescription;billingItem.hoursUsed;'+
   'activeTransaction.transactionStatus.friendlyName;powerState.name;powerState.name;'+
   'blockDevices.diskImage;softwareComponents.passwords;id';

本来の目的を果たして呼び出しからリターンされた時点で、リスト 13 のコードに示されているように、返された値がテーブル内のセルに取り込まれます。

リスト 13. JavaScript: 返された値がテーブル内のセルに取り込まれる
$('#ciap-server-detail-maxCpu').text(guest.maxCpu);
$('#ciap-server-detail-maxMemory').text(guest.maxMemory);
var osname=guest.operatingSystem.softwareLicense.softwareDescription.longDescription||'<unknown>';
$('#ciap-server-detail-os').text(osname);
detailTable.table('refresh');

これで、サーバーの詳細ビューが表示されます (図 3 を参照)。

図 3. サーバーの詳細
Cloud-in-a-pocket アプリケーション: サーバーの詳細ビュー
Cloud-in-a-pocket アプリケーション: サーバーの詳細ビュー

さらに機能を追加する: サーバーの管理

次の機能セットでは、以下のサーバー管理機能を追加します。

  • 起動/停止/リブート
  • 一時停止/再開
  • 削除

サーバー管理機能は、jQuery Mobile ボタンとして実装されます。これらのボタンはどれもがアプリケーション内の同じメソッドをトリガーします。リスト 14 を参照してください。

リスト 14. HTML: 仮想サーバーの管理用コントロール
<fieldset data-role="controlgroup" data-type="horizontal" style='text-align:center;'>
   <input type="submit" id="iap-server-function-boot"   data-icon="check"
      onclick="ciap.onServermanagement(this, 'powerOn')" slapi-function="power on"/>
   <input type="submit" id="iap-server-function-reboot" data-icon="refresh"
      onclick="ciap.onServermanagement(this, 'rebootDefault')" slapi-function="reboot"/>
   <input type="submit" id="iap-server-function-shut"   data-icon="power"
      onclick="ciap.onServermanagement(this, 'powerOffSoft')" slapi-function="shut down">
   <input type="submit" id="iap-server-function-config" data-icon="bullets"
      onclick="ciap.onConfigure(this)" slapi-function="configure">
   <input type="submit" id="iap-server-function-delete" data-icon="delete"
      onclick="ciap.onServermanagement(this, 'deleteObject')" slapi-function="finally destroy">
   <input type="submit" id="iap-server-function-pause"  data-icon="minus"
      onclick="ciap.onServermanagement(this, 'pause')" slapi-function="pause">
   <input type="submit" id="iap-server-function-resume" data-icon="plus"
      onclick="ciap.onServermanagement(this, 'resume')" function="resume">
</fieldset >

slapi-function 属性に指定された値は、誤った操作を防ぐための質問に含めて表示されます。この質問では、要求されたアクションを実行する前にエンド・ユーザーに確認をします。作成した jQuery Mobile ボタンの 1 つがトリガーされると、警告ページがロードされます。この警告ページは、エンド・ユーザーによる確認の後、サーバー管理機能を呼び出します。選択されたメソッドは、後で SoftLayer API で使用するために currentServer.extra.method に保存されます。図 4 に、表示される確認画面を示します。

図 4. 確認画面
Cloud-in-a-pocket アプリケーション: 要求したアクションをユーザーに対して確認するための確認画面
Cloud-in-a-pocket アプリケーション: 要求したアクションをユーザーに対して確認するための確認画面

2 番目の引数 (onServermanagement()) は、実行する SoftLayer API メソッドです。SoftLayer.VirtualGuest クラスに対する以下の呼び出しを追加します。

リスト 15. JavaScript: 仮想サーバーを管理するための SLAPI REST インターフェース
this.server = function (usrargs) {
    try {
        var callargs = {
            uri : 'SoftLayer_Virtual_Guest/' + usrargs.guestid + "/" + usrargs.method,
            userdata : usrargs
        };
        SoftLayer.get(callargs)
    } catch (e) {
        console.error("error SoftLayer.VirtualGuest.server:" + e);
    }
};

アプリケーションでは上記のインターフェースを使用して、サーバーを管理することができます。リスト 16 を参照してください。

リスト 16. JavaScript: 仮想サーバーの管理機能を呼び出す
SoftLayer.virtualGuest.server({
   guestid : currentServer.id,
   method: currentServer.extra.method,
   success: function() {
      $.mobile.loading( 'hide');
      $( ":mobile-pagecontainer" ).pagecontainer( "change", '#ciap-view-servers-page');
   },
   error: thiz.onErrorCatchall
});

まとめ

SoftLayer クラウド・サーバーをモバイル端末に表示するためのアプリケーションの作成方法を理解できたところで、第 2 回では新規サーバーをオーダーして構成する方法を紹介します。


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


関連トピック


コメント

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development, Cloud computing
ArticleID=995126
ArticleTitle=クラウドをポケットに入れて持ち歩く: 第 1 回 サーバー・リストを管理する
publish-date=01222015