normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

日本全国のコミュニティイベントが主体の Community Open Day 2012 が開催!!

6月9日(土)に、全国各地で一斉にCommunity Open Day と銘打った勉強会が開催される。
本勉強会、内容も充実しているが、参加 or USTREAM で見るだけでも 豪華プレゼント がもらえるかもしれない豪華イベントだ。詳細については http://cod.ms/Pages/present.aspx を是非確認頂きたい。

以下の会場で実施されるため、近場の会場に足を運び、興味のあるセッションに参加してみてはいかがだろうか。もちろん USTREAM での視聴も歓迎だ。

  • 北海道会場
  • 福島会場
  • 東京会場
  • 名古屋会場
  • 北陸会場
  • 大阪会場
  • 広島会場
  • 四国会場
  • 九州会場
  • 沖縄会場

Trac Lightning on Windows Azure への道のり 〜その2〜

以前に紹介した Trac Lightning on Windows Azure への道のり 〜その1〜 id:waritohutsu:20120320 から、二か月弱経ってしまったが、続編を紹介したい。前回までの記事では、Windows Azure 上で Trac Lightning を実行することが可能なところまで検証したが、永続化部分に対する考慮が不足していた。
課題となっていた永続化部分についての対応を行い、GitHub にて WATracLightning というプロジェクト名で公開した。興味がおありの方は是非お試し頂きたい。

今回の記事では特にソースコードの紹介はしないため、必要な場合は GitHub 内のソースコードを参照して頂きたい。

システム構成図

作成した WATracLightning のシステム構成図は以下となる。予め VHD ファイルと Trac Lightning のバイナリをブロブ上に配置しておく必要がある点に注意して欲しい。

処理の流れ

Workerロールで行われる処理は以下になる。Trac Lightning のインストール後、一度OSの再起動が必要であるため、RoleEntryPoint.Run()処理内で実行するスクリプトに多少工夫が必要になる。

RoleEntryPoint.OnStart() 内では、diskpart.exe を利用して Azure Drive を固定ドライブレターにマウントする処理を実行している。ご存じない方も多いと思うが、Azure Drive がマウントするドライブレターは固定ではない*1ため、当該処理が必要になる。

今後の課題

現時点では、Jenkins が上手く動作していない。Jenkins を利用した自動ビルドや自動テストは、プロジェクトサイズが大きくなると時間のかかる処理であるため、当該処理だけでもインスタンス数を増やす対応が可能かどうかのフィージビリティ検証を行いたいところだ。

ご参考リンク(結局利用はしなかったが…)

*1:単一のVHDファイルをマウントする場合でもドライブレターが異なる場合がある

Windows Azure & ASP.NET MVC4 & itextsharp で日本語PDFファイルの動的生成

ふと思い立ち、Windows Azure 上で日本語 PDF ファイルを生成したい衝動に駆られたのでフィージビリティを取得した。結論から言うと「任意の日本語フォントを利用したPDFファイルは Windows Azure 上で生成可能」だ。
後述する ActiveReports の様に独自にフォントを管理する機能をもたなくとも、日本語フォントを Windows Azure 上にインストールして利用することが可能なことが分かった。しかし、ベンダーサポートやライセンスの問題については言及していないので、その点には留意頂きたい。

前提知識

Windows Azure のホスティッドサービスで提供される仮想マシンは英語版OSであり、日本語環境にローカライズされていない点を認識頂く必要がある。このため、日本語フォントはインストールされておらず、タイムゾーンUTC 時刻となっている。タイムゾーンは DateTime.UtcNow に対し、日本の時差である時間だけ差分をとれば対応可能だが、日本語フォントはこの様に単純な対応ではうまくいかない。
Windows Azure 上に日本語フォントが不足している環境で日本語PDFファイルを作成するには、以下のうちどちらかの対応を実施するしかない。

  • ActiveReports の様に、独自に日本語フォントを管理する機能を持つソフトウェアを利用する
  • Windows Azure 環境に日本語フォントをインストールする

Azure への日本語フォントのインストール方法に関しては、 @harutama 氏がブログで紹介しているため、今回はこちら あれとアレは混ぜるな危険 Azureのインスタンスにフォントを入れたいんですが? を利用する。

今回利用するPDF生成ライブラリ

今回は itextpdf を日本語PDFファイルの生成ライブラリとして利用する。日本語での紹介記事も存在するので、必要な場合は別途 codezine の記事を参照して頂きたい。

Read more

第 69 回 CLR/H 勉強会で話した「基礎から見直す ASP.NET MVC のテスト自動化方法 〜Azure関連もあるかも〜」

4/14(土)に開催された 「第 69 回 CLR/H 勉強会 Intelはいってるデイ」 で話した内容について共有させていただく。

今回は ASP.NET MVC単体テスト自動化をベースに資料を作成し、対象者は「単体テスト自動化をしてみたいが、どうやったらいいか分からない人」とした。この手のお作法は方々に情報が散っているものの、初学者向けに情報がまとまっている箇所が少なかったので情報をまとめてみた。
その他にも、「togetter - CLR/H 第 69 回 勉強会 Intel はいってるデイ レポート」に状況がまとめられているので、興味のある方はご一読いただきたい。

今後は QUnit-Tap や Trac Lightning とも連携し、テストの自動化をより一層進めたいところだ。

Node.js × Silverlight の Websocket 通信ではまったこと

著しく時期を損ねてしまった感はあるが、Silverlightを囲む会in東京#5 with JAZUG で話したネタを投下する。セッションで話した内容は、Node.js & socket.io と Silverlight & WebSocket を疎通させうとした際にはまった点だ。

socket.io そのものは非常に優秀なライブラリだが、Silverlight(や、たぶんFlex等も)の様に socket.io 向けのラッパーが用意されていない場合には注意が必要だ。

Trac Lightning on Windows Azure への道のり 〜その1〜

「その○」と銘打って続かないものが多々あって恐縮だが、無事 Windows AzureTrac Lightning を動かすことが出来たのでTIPSを共有させて頂く。永続化部分等で考慮するべき点は多いが、Windows Azure 上で動作させるにはどんな手順が必要かを記載する。

Trac Lightning とは

私のブログを見に来るような方には説明が不要だと思うが、 http://sourceforge.jp/projects/traclight/ で公開されており、 Trac, Subversion, Maven の簡易インストーラとサンプルプロジェクトを提供するナイスプロジェクトだ。Trac Lightning のインストーラはGUIが主体だが、オプションしだいではサイレントインストールも可能となっている。

Windows Azure で動作させるには

手順はさほど複雑ではなく、以下を実施すれば良い。

  • TracLightning のバイナリを入手し、BLOBストレージ上にパブリック権限で配置する
  • Windows Azure の Workerロールプロジェクトを作成し、スタートアップタスクでTracLightningをセットアップする

次に、実際の作業手順を記載する。

TracLightning のバイナリを入手し、BLOBストレージ上にパブリック権限で配置する

こちらの手順は非常に単純だ。 http://sourceforge.jp/projects/traclight/ サイトから TracLightning-X.X.X.exe をダウンロードし、Windows Azure 上のBLOBストレージに配置する(今回は https://myaccountname.blob.core.windows.net/trac/TracLightning.exe と名前を変更して配置)。

Windows Azure の Workerロールプロジェクトを作成する

Visual Studio 2010 から、Windows Azure のプロジェクトを作成する(プロジェクト名は WATracLightning とした)。Workerロールを一つ作成する。

TracLightning ダウンロード用のスクリプトを配置する

以前紹介した 2011年12月 Windows Azure の大幅更新 〜Java編〜 id:waritohutsu:20111231:1325300990 に含まれる download.vbs を利用することで、大容量ファイルをBLOBストレージから同期的に取得することが可能だ。今回はこちらを WorkerRole1\Assets\download.vbs に配置し、プロパティウィンドウから [出力ディレクトリにコピー]を[新しい場合はコピーする]に設定する。

80番のエンドポイントを設定する

外部からWorkerロールにアクセスするため、エンドポイントを指定する。Visual Studio のウィンドウから、以下を指定する。

名前 種類 プロトコル パブリックポート プライベートポート
Endpoint1 Input tcp 80 <指定無し>
スクリプトを作成し、Workerロールプロジェクトに配置する

以下のスクリプトを WorkerRole1\setuptrac.cmd として配置し、 [出力ディレクトリにコピー]を[新しい場合はコピーする]に設定する。

@echo off

if exist C:\TracLight\start.bat goto runtrac
"%~dp0Assets\download.vbs" https://myaccountname.blob.core.windows.net/trac/TracLightning.exe
"%~dp0TracLightning.exe" /VERYSILENT /LOG="mylog.txt"
goto end

:runtrac
start C:\TracLight\start.bat

:end
作成したスクリプトをStartup Taskで実行するように設定する

Windows Azure プロジェクト内の ServiceDefinition.csdef を以下のように修正する。

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WATracLightning" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="WorkerRole1" vmsize="Small">
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
    <Runtime executionContext="elevated" />
    <Startup>
      <Task commandLine="setuptrac.cmd" executionContext="elevated" taskType="simple" />
    </Startup>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="tcp" port="80" />
    </Endpoints>
    <ConfigurationSettings>
      <Setting name="StorageConnectionString" />
    </ConfigurationSettings>
  </WorkerRole>
</ServiceDefinition>

以上の作業を行うことで、Windows Azure 上で Trac Lightning を動作させることが可能になる。

残課題として

Trac Lightning を Windows Azure 上で動作させることができたが、永続化に関しては何も対策をしていない状態になっている。少なくとも、以下のファイルを永続化しないと Trac Lightning を Windows Azure上で運用できないだろう。

  • アカウント情報
    • c:\TracLight\projects\svnauthz
    • c:\TracLight\projects\trac.htdigest
  • SVNリポジトリ
    • c:\TracLight\projects\svn
  • Trac プロジェクト
    • c:\TracLight\projects\trac 以下のプロジェクト

上記のうちで「trac-admin <プロジェクト名> resync」で解決できるものもあるが、対応を完全なものにするには検討が必要なものが残っている。

Windows Azure SDK for Node.js でキューストレージを利用する その1

id:waritohutsu:20120211:1328948258 で紹介したテーブルストレージの利用方法に引き続き、キューストレージの利用方法についても紹介する。
キューストレージは.NET SDK同様に利用することができたが、格納した文字列が文字化けした。その点に注意すれば、現時点でもキューストレージは利用可能だ。

キューの作成、メッセージの作成と挿入

早速コード例を記載する。

var azure = require('azure');
var ServiceClient = azure.ServiceClient;
var queueService = azure.createQueueService(
  ServiceClient.DEVSTORE_STORAGE_ACCOUNT,
  ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY,
  ServiceClient.DEVSTORE_QUEUE_HOST
);

var uuid = require('node-uuid');


var queueName = "myqueue";
var metadata = { 'class': 'test' };

var messageText1 = "おっぱいおっぱい at " + new Date().toString();

// Create だが、IfNotExists もある
// queueService.createQueue(queueName, { metadata: metadata }, function (createError, queue, createResponse) {
queueService.createQueueIfNotExists(queueName, { metadata: metadata }, function (createError, queue, createResponse) {
   console.log(createError)
   console.log(queue);
   console.log(createResponse.isSuccessful);
});

//メッセージを作成し、返答結果を表示する
queueService.createMessage(queueName, messageText1, function (createMessageError, message, createMessageResponse) {
   console.log(createMessageError)
   console.log(message);
   console.log(createMessageResponse);
});

実行結果は以下の様になるので参考程度に眺めて頂ければ幸いだ。

>node.exe queue-main.js
null  
false 
true 
null 
{ queue: 'myqueue' }
{ isSuccessful: true,
  statusCode: 201,
  body: '',
  headers:
   { 'transfer-encoding': 'chunked',
     server: 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0',
     'x-ms-request-id': '528810c2-c2fc-48ed-a22e-7258a5e1e306',
     'x-ms-version': '2011-08-18',
     date: 'Sat, 11 Feb 2012 08:26:09 GMT' },
  md5: '1B2M2Y8AsgTpgAmY7PhCfg==' }

メッセージの取得と削除

次に、メッセージの取得と削除方法を紹介する。キューストレージに格納されたメッセージは、以下の様に明示的に削除しないと保存され続ける点に注意が必要だ。

var azure = require('azure');
var ServiceClient = azure.ServiceClient;
var queueService = azure.createQueueService(
  ServiceClient.DEVSTORE_STORAGE_ACCOUNT,
  ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY,
  ServiceClient.DEVSTORE_QUEUE_HOST
);

var uuid = require('node-uuid');


var queueName = "myqueue";
var metadata = { 'class': 'test' };

var messageText1 = "おっぱいおっぱい at " + new Date().toString();

// Create だが、IfNotExists もある
// queueService.createQueue(queueName, { metadata: metadata }, function (createError, queue, createResponse) {
queueService.createQueueIfNotExists(queueName, { metadata: metadata }, function (createError, queue, createResponse) {
   console.log("createError = " + createError)
   console.log(queue);
   console.log("createResponse.isSuccessful = " + createResponse.isSuccessful);
});

queueService.getMessages(queueName, function (getError, getQueueMessages, getResponse) {
   console.log(getError);
   if( 0 < getQueueMessages.length ){
     for( var i=0; i<getQueueMessages.length ; i++ ){
        console.log(getQueueMessages[i].messagetext);
        queueService.deleteMessage(queueName, getQueueMessages[i].messageid, getQueueMessages[i].popreceipt, function (deleteError, deleted, deleteResponse) {
           console.log("deleteError = " + deleteError);
           console.log("deleted = " + deleted);
           console.log(deleteResponse);
        });
     }
   }
   //console.log(getResponse);
});

出力結果は以下になる。挿入したメッセージが文字化けしている点に注意してほしい。

>node.exe queue-main2.js
createError = null
false
createResponse.isSuccessful = true
null
&#198;4 at Sat Feb 11 2012 17:37:29 GMT+0900 ,B&#128;&#138;J
deleteError = null
deleted = true
{ isSuccessful: true,
  statusCode: 204,
  body: '',
  headers:
   { 'content-length': '0',
     server: 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0',
     'x-ms-request-id': '12dc6438-5c08-4510-a934-2b3002cf8f46',
     'x-ms-version': '2011-08-18',
     date: 'Sat, 11 Feb 2012 08:37:44 GMT' },
  md5: '1B2M2Y8AsgTpgAmY7PhCfg==' }