July 2012

Volume 27 Number 07

この記事は機械翻訳されたものです。

Forecast: Cloudy - Node.js を Windows Azure ソリューションに組み込む (機械翻訳)

Joseph Fultz | July 2012

 

Joseph FultzNode.js は、多くの後半に、プレスになっているし、高い I/O 応答を待っている間他の作業を行うにはメイン スレッドを解放、非同期 I/O モデルを喧伝されています。Node.js の包括的なルールは、I/O が高価で、非同期 I/O モデルを強制することによって経費を軽減しようです。私は、すでに既存のフレームワークに組み込む方法可能性について考えてきた。ゼロから開始している場合は、決定はかなりだけでクールな要因に基づく場合でも、技術の選択肢をレイアウトし、決定するは比較的簡単です。しかし、目標をソリューションの 1 つの部分に、テクノロジーの更新を実行する場合は、トリックは何かは、現在、将来は多くの追加の費用で来ていないあり、素敵な既存のソリューションの風景に収まるピッキングです。

まさにこのコラムで示すつもりです。表示するドキュメントのストレージことができますがそれらをダウンロードするには、共有アクセスの署名が必要な既存のソリューションを取る。その解決策を Node.js を使用して、単純な UI を追加します。その実装に役立つには、いくつかの一般的に使用されるフレームワークの利点を Node.js ってください。このソリューションは、したがってが含まれます。

  • Node.js—the コア エンジン
  • エクスプレス — モデル-ビュー-コント ローラー (MVC)-スタイルのフレームワーク
  • 翡翠 — レンダリングとテンプレート エンジン

一緒にこれら 3 つのツールは、ASP.NET MVC 3 とカミソリを使用するように UI を構築するから豊富なフレームワークを提供します。

手始めに

あなたは Node.js に新しいしている場合は、マイクロソフトから利用可能のウォークスルーを開始するのには、おそらく最高です windowsazure.com/develop/nodejs。また、Windows Azure の Node.js SDK をインストールする必要があります。エクスプレスの周りをつつく少しの時間を費やす必要があるまた、おそらくあります (expressjs.com) と翡翠 (翡翠 lang.com)。あなたはこれらのツールに新しいしている場合は、いくつかのなじみの概念となじみの構文の組み合わせを見つけます。

このシナリオでは、私の既存のサービス、Windows Azure の側の仕事、Node.js ベースの Windows Azure でホストされるサイトへのアクセスのためのドキュメントの一覧を表示するサービスを呼び出すでしょう。一般に、クライアントとバックエンド サービス間の間接層の役割を有用な勧めします。これから任意のインターフェイスの変更、サービス分離しますが、実際の値は頻繁余分な機能の柔軟性と方法を含めるし、バックエンド ・ サービス ・ プロバイダーを除外できます。

既存のソリューションで表示される図 1、目的は彼は、共有アクセスの署名 (SAS) を生成認証された場合にのみユーザーのアクセスを与えることでした。アイデアは、人の認証への読み取りアクセスを付与し、その後完全付与作成、読み取り、更新、削除 (CRUD) へのアクセスの役割とメンバーシップ ・ レベルに基づいて、特定のドキュメントをことだった。ここでの読み取りの権限だけを取り上げます。

要求シーケンス
図 1 要求シーケンス

サービスを作成します。

私は、ID を返すには、認証サービスを模擬しますその後のサービスの呼び出しは、ファイルの一覧を取得します。(「文書」) を使用して、Windows Azure ストレージ コンテナーは、パブリック アクセス許可の制限があります。ユーザーが認証されていません、しかし、ファイルを開くことができるように、認証されていないユーザーがしない場合でも、ドキュメントの一覧を提供したいと思います。私 2 つの呼び出しの署名作成した api です。

http://[host]/admin/GetAccess?user=[user] & pwd = [パスワード]
http://[host]/admin/files?accessId=[authId]

もちろん、querystring を使用しないし、SSL を使用して、現実的な認証サービスをします。 ここでのソリューションの部分をカバーされません。

まずは法が SAS 作成に必要な (を参照してください図 2)。まもなく私はドキュメントの一覧を作成するメソッドを作成するときはこのメソッド必要があります。

共有アクセスの署名を取得するために図 2 メソッド

public string GetSharedAccessSignature()
{
  string sas = "";          
  sas = (string) System.Web.HttpContext.Current.Cache.Get("sas");
  // If no SAS then get one
  if (sas == null)
  {
    // TODO: hardcoded container, move to config
    CloudBlobContainer container = 
      blobClient.GetContainerReference("documents");
    // Ask the container for SAS passing in the a newly initialized policy
    sas = container.GetSharedAccessSignature(new SharedAccessPolicy()
    {
      SharedAccessStartTime = DateTime.Now,
      SharedAccessExpiryTime = DateTime.Now.AddMinutes(MaxMinutes),
      Permissions = 
        SharedAccessPermissions.Read | SharedAccessPermissions.List
    });
    // Add to cache for reuse because this isn't a per-user SAS
    System.Web.HttpContext.Current.Cache.Add("sas", sas, null,
      DateTime.Now.AddMinutes(MaxMinutes), new TimeSpan(0,0,5,0,0),
      CacheItemPriority.High, null);
  }
  return sas
}

ほとんどの部分については、これは GetSharedAccessSignature の呼び出しまでは典型的な Windows Azure ストレージ コードです。 起動またはアクセスと、アクセス許可の種類を許可を停止する場合についての情報を通過するので、共有のアクセス ポリシーをここでは、ないです。 すべて経由で SAS を提供したいのですが。 読み取りし、ファイルを一覧表示する機能です。 SAS 理論的には誰にも認証が使用されるため、また、私は、キャッシュの再利用のために衝突を避けるために、アクセス キーの生成に解約の量を減らすに追加します。

サービス インターフェイスは、WebMethod として構成されます。

[OperationContract]
[WebGet(UriTemplate = "Files?accessId={accessId}")]
List<BlobInfo> GetFiles(string accessId);

カスタム クラス BlobInfo の使用に注意してください — もう一度、私の間接参照を使用しています。私は帰りたい特定のフィールドと IListBlobItem が必ずしも彼らを表していません。私が私のタイプのリストに IListBlobItems から返される情報をマーシャよで示すように、 図 3

図 3 GetFiles の実装

public List<BlobInfo> GetFiles(string accessId)
{
  List<BlobInfo> blobs = new List<BlobInfo>();
  CloudBlobClient sasBlobClient = default(CloudBlobClient);
  CloudStorageAccount storageAccount =
    CloudStorageAccount.FromConfigurationSetting(
    "StorageAccountConnectionString");
  string sas = default(string);
  if(accessId.Length > 0)
  {
    // For the mock just make a simple check
    if(VerifyId(accessId))
    {
      sas = GetSharedAccessSignature();
      // Create the blob client directly, using the SAS
      sasBlobClient = new CloudBlobClient(storageAccount.BlobEndpoint,
        new StorageCredentialsSharedAccessSignature(sas));
    }
  }
  else
  {
    sasBlobClient = storageAccount.CreateCloudBlobClient();
  }
  CloudBlobContainer blobContainer =
    sasBlobClient.GetContainerReference("documents");
  foreach (IListBlobItem blob in blobContainer.ListBlobs())
  {
    BlobInfo info = new BlobInfo();
    info.Name = blob.Uri.LocalPath;
    info.Uri = blob.Uri.AbsoluteUri;
    info.Sas = sas;
    info.CombinedUri = blob.Uri.AbsoluteUri + sas;
    blobs.Add(info);
  }
  return blobs;
}

注意する重要なは図 3 アクセス ポリシー コンテナを尊重リストを返すために、ユーザーが認証されている場合、SA を使っていること。

表象 State Transfer (REST) サービスの場所を私は経由でブラウザー ウィンドウを簡単にテストを実行できます。サービス インターフェイスをこのように設定すること、私の私があるまでは、既知の値を使用して認証を模擬するために簡単になります、for ループのリストと適切に実行して SAS を生成します。完了すると、VerifyId(string) は単にかどうか、accessId にキーと等しいにキャッシュされた資格情報があるを確認します。図 4 認証なし返されたリストが表示されます。サービスによって返されたリストが認証ではなかったため、SAS 値を nil に設定されます。したがって、一覧、レンダリングするデータを使えますが、SAS がないため、ユーザーには、働くリンクをられない。

は、認証されていないリスト
図 4 は、認証されていないリスト

図 5 SA は、認証済みのリストを表示します。

、認証一覧、sas
図 5、認証一覧、sas

サービスは、認証された呼び出しからを返しますを並べ替えるには、Node.js クライアントの仕事をして最後の URI を sas のハイパーリンクをレンダリングします。クライアントは、1 つの要素だけにアクセスする必要がありますので、それを支援するには、I CombinedUri 要素提供しました。私は Node.js で働いているので、XML は素晴らしいですが、最後に、返す JSON オブジェクトとしてサービスの応答を直接使用できるようにするインターフェイス上の帰属を変更するにはかなってください。

[WebGet(UriTemplate = "Files?accessId={accessId}",
  ResponseFormat=WebMessageFormat.Json)]

ここのように見える何 JSON 出力です。

[{"CombinedUri":"https:\/\/footlocker.blob.core.windows.
net\/documents\/AzureKitchen-onesheet.docx?st=2012-03-05T05%3A22%3A22Z&se=2012-03-05T05%3A27%3A22Z&sr=c&sp=rl&sig=Fh41ZuV2y2z5ZPHi9OIyGMfFK%2F4zudLU0x5bg25iJas%3D","Name":"\/documents\/AzureKitchen-onesheet.docx","Sas":"?st=2012-03-05T05%3A22%3A22Z&se=2012-03-05T05%3A27%3A22Z&sr=c&sp=rl&sig=Fh41ZuV2y2z5ZPHi9OIyGMfFK%2F4zudLU0x5bg25iJas%3D","Uri":"https:\/\/footlocker.blob.core.windows.
net\/documents\/AzureKitchen-onesheet.docx"}]

エクスプレスと翡翠内直接消耗品としては述べたように、JSON 最終的にここでは、欲しいものです。

Node.js UI

私はすでに Node.js を設定して、エクスプレス、ヒスイの UI を作成する準備ができてる。私は Node.js の役割の展開を取得して、Visual Studio では、実行中のプロセスを行ってきたが、非常に詳細な完全に手動のプロセスです。ツールの統合のための Node.js 部分がないため、私崇高本文 2 私の編集を行うし、デバッグにクロムを使用します (Tomasz Janczuk のブログ上で説明されているよう bit.ly/uvufEM)。

いくつかの家事の項目を言及する必要があります。初心者のために、午前の採用フレームワークはいくつかの特定の機能、MVC、テンプレート レンダリング エンジンの使いやすいラッパーを提供します。

  • Restler (簡体字の WebClient) と思う簡単に残りの呼び出し
  • 一般的な MVC スタイル アプリケーション フレームワークの表現します。
  • テンプレート レンダリングと同様に ASP.NET MVC を使用するかみそりエンジンに翡翠

これら Node.js (のような .net Dll) 内のすべての考慮モジュールであり、一般的にノード パッケージ マネージャー (NPM) 経由でを GitHub からインストールされています。たとえば、Restler をインストールするには、「故宮インストール コマンド restler」からプロジェクト フォルダー内で使用します。これは、手動でモジュールをインストールして、それへの参照をプロジェクトに追加するが行われます。

1 つの最後のビットについては、なじみのないのは。その他の関数では入れ子に匿名の関数の多くがわかります。私の最高のアドバイスは、当然のことながら、それを再フォーマットすることなくが解析するまでそれを作業中に入れ子に十分なコードを再フォーマットすることです。読みやすさのための私のサンプルを巣に、素敵な色は、読みやすさを助ける崇高なものからのスクリーン ショットを使用するを試みるでしょう。

新しい AzureService 新しい AzureWeb のコマンドを使用­AzureNodeExpress という名前のアプリケーションを作成する役割。私はまたその他の変更のカップルを加えました。Server.js のインデックス ページを取得するルートを追加; アナログの ASP.NET MVC のプロジェクトで使用される MapRoutes メソッドです。

Server.js の変更

多くでは、c# の using ステートメントのような私は Node.js 使用するライブラリを教えてくださいする必要があります。Node.js では、値の戻り値の変数を割り当てることによってと私はそれらの参照を設定します、('[ライブラリ名]') 関数を必要とします。参照が設定されていると、いくつかのエンジン変数を設定する構成のビットを行う (たとえば、「エンジンの表示」に設定する「翡翠」)。特定の関心の「ビューのエンジン」はルーター bodyParser cookieParser、セッション。

いくつかより世俗的な要素をスキップしますが、私のルーティングを設定したい操作を行います。私のインデックス ページでの Get 動詞は単にビューを直接レンダリングされます。

app.get('/index',
  function(req, res){
    res.render('index.jade', {title: 'index'});
  }
);

ただしは Post 動詞のインデックス モデルを処理する必要。 "モデルの定義済みメソッドをバインドするには「あるを達成するには。

app.post('/index', index.GetAccessKey.bind(index));

場所のルーティングでは、ビューとモデルの両方を設定しなければなりません。

View—Index.jade

ある意味では先頭から末尾に、ビュー、コント ローラーから行くによってスキップだが、MVC スタイルで作業するとき動作に対して最初に簡単なビューを作成しましょう。翡翠構文は基本的に HTML のかっこの装飾なしです。私の全体の翡翠のテンプレートが表示されます図 6

図 6 玉テンプレート

html
head
  title Default
body
  h1 File List Home Page
  br
  label Welcome #{username}
  form(method='post', action='/index')
    label Username:
      input(name='username', type='text')
    br
    label Password:
      input(name='password', type='password')
    br
    button(type='submit') Login
  h2 Files   
  form
    table(border="1")
      tr
        td Name
        td Uri
        each doc in docList
          tr
            td #{doc.Name}
            td
              a(href=#{doc.CombinedUri}) #{doc.Name}

メモここでは省略 foreach の一種である変数とテーブル テンプレートには、ループで参照する # {[var]} の使用。 ドキュメント リストを反復処理する項目のリストを名づけるきた。 どこにこのビューをレンダリングするために玉を求める、index.js ページでは、docList 用の値を渡す必要がありますので、これは重要です。 ものはかなり基本的なここでは、私はちょうど、開発者の UI を作成するので — シンプルでプレーン。

Model—Index.js

Server.js でランタイム インフラストラクチャと、最終的な表示テンプレート index.jade の設定を持つ、index.js の発生、執行の肉を左です。 アプリケーションのバインディング設定を覚えています。インデックス ページにポストします。 バインドをロードし、プロトタイプを実行の index.js を作成しました。 これを行うには、私の関数インデックス プロトタイプに示すように追加します図 7。 本質的には、名前付きの関数 (たとえば、GetAccessKey) を作成し、その実行体としての匿名関数を定義です。 これらの各関数にはのようにする残りの呼び出しを簡略化するのに Restler モジュールを使用します。

図 7 Index.js 機能

バインドが起こるポストが単にユーザー名とパスワードは、フォーム ポストを通じて提出を受け取り、GetAccessKey には、後の最初の呼び出しは、それらはクエリ文字列の一部として URI を追加し、Restler を使用して、Get を実行します。 、非常にネストされた匿名関数の増殖を見る理由の 1 つですべての通信を非同期的に発生 Node.js を覚えています。 そのパターン rest.get への呼び出しで true にご滞在は、要求の完了後に実行される匿名関数を定義します。 行を簡素化する、エラー処理コードなし。

rest.get (uri).on('complete',
  function(result){
    accesskey = result;
this.ShowDocs (req, res);}
  )

うまくいけば、再フォーマットは何の意味を与えることになります。 私のサービスから、キーを入れた後、それにドキュメントのリストをフェッチするメソッドに URI を後置よ。 今、いつもと少し違うこと。 ドキュメントの一覧を取得する残りの呼び出しの戻り値を処理、匿名関数では、私のために結果を表示する玉を求める:

res.render ('index', {title: "Doc List",
    layout: false,
    docList: result,
    username: req.BODY.username});

作成したことでテンプレート変数名"docList"前述私は今私は、正しい名前を使用しているかどうかを確認する必要があります。Res.render への呼び出しは、「インデックス」リソースをレンダリングするには、エクスプレス フレームワークに指示し、コロンおよびコンマで区切られた名前と値のペアのリストを介してのパラメーターを渡します。

Runtime

それをダウンロードするファイルの 1 つを参照する場合、何を提示午前します。Web ページが見つかりません。Windows Azure ストレージからの不正なエラーを期待できますが、プライベートとマークされている何かにアクセスしよう場合は、何が返される、リソースが存在しないことです。これはデザインであり何か、「プライベート」概念においても、国民に存在してはならないので、それが望ましい。401 エラーが返された場合は、それが実際には、個人によって表されるセキュリティ ポリシーに違反するものを示します。

ストレージの場所を確保しましたので、直接アクセスは許可されません。ただし、サンプル コードを実行すると、話はちょっと違います。Windows PowerShell 発行-AzureService コマンドを使用してアプリケーションを発行するページを参照し、自分の資格情報を入力します; [ファイルへのリンクの一覧を提示午前 (を参照してください図 8)。

ファイルへのリンク
図 8 ファイルへのリンク

私のサービスの呼び出しを記憶する仲介ですので、にもかかわらず、私は直接それらをリストすることはできませんファイルを一覧表示ことができた。またにクリックしたときの各リンクと SAS、最後ですのでを開くか、対象のドキュメントを保存するように求めです。

まとめ

あなた Windows Azure アプリケーションが進化する手段として新しいまたはトレンドの技術に興味や Node.js ドメインで何が起こっているの真の信者をしている場合は、Windows Azure をカバーしている-だけでなく、ソリューションをホスティングが、次に示すようも Node.js クライアント ライブラリなどのオプションの開発側では、REST API 直接または間接を押します。開発は確かに適切なツールのサポート、Node.js、Node.js の人気が成長し続けると我々 最終的に Visual Studio との統合のいくつかの並べ替えがわかりますと確信する場合多くのより良いより簡単でしょう。

Joseph Fultz*、ヒューレット ・ パッカード株式会社グッドエイチピードットコム グローバル IT グループの一部としての作業でするソフトウェア アーキテクトです。 以前、彼は Microsoft、その一流企業と ISV のお客様の建築とデザインのソリューションを定義するためのソフトウェアアーキテクトだった。*

この記事のレビュー、次技術専門家のおかげで:: Bruno Terkaly