Windows Azure SDK for Visual Studio Novemberについて色々確認してみた
以前 id:waritohutsu:20091115 で記述したとおり、Windows Azure SDK for Visual Studio Novemberにおいて、Windows Azureストレージに対するアクセス方法が大幅に変更されました。具体的に、以下の点が大きな変更点だと思っています。
- 設定ファイルを読み取る際に、予め初期化処理が必要
- ストレージアクセスの設定(*.cscfg、*.csdef)のフォーマット変更
- ストレージアクセスに用いるクラス名の変更
- サポートされたLINQメソッドが変更している*1
設定ファイルを読み取る際に、予め初期化処理が必要
以下の手順を踏まないと、Windows Azure SDK for Visual Studio Novemberでは *.cscfgファイルから設定値を読み取る際に例外が発生します。
- RoleEntryPointクラスを継承したクラスを作成し、RoleEntryPoint#OnStartメソッドをオーバーライド
- 上記メソッド内で、CloudStorageAccount.SetConfigurationSettingPublisherにハンドラを登録
以下が、件のRoleEntryPoint#OnStartのメソッド
public class WebRole : RoleEntryPoint { public override bool OnStart() { DiagnosticMonitor.Start("DiagnosticsConnectionString"); #region Setup CloudStorageAccount Configuration Setting Publisher // This code sets up a handler to update CloudStorageAccount instances when their corresponding // configuration settings change in the service configuration file. CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => { // Provide the configSetter with the initial value configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)); RoleEnvironment.Changed += (sender, arg) => { if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>() .Any((change) => (change.ConfigurationSettingName == configName))) { // The corresponding configuration setting has changed, propagate the value if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))) { // In this case, the change to the storage account credentials in the // service configuration is significant enough that the role needs to be // recycled in order to use the latest settings. (for example, the // endpoint has changed) RoleEnvironment.RequestRecycle(); } } }; }); #endregion on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. RoleEnvironment.Changing += RoleEnvironmentChanging; return base.OnStart(); } private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e) { // If a configuration setting is changing if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)) { // Set e.Cancel to true to restart this role instance e.Cancel = true; } } }
ストレージアクセスの設定(*.cscfg、*.csdef)が変わっている
新旧二つの*.cscfg設定ファイルを例として記述します。ご覧の通り、旧設定ファイルがWindows Azure独自形式な事に対して、新設定ファイルはADO.NETを意識した記述方法になっています。
- 新*.cscfg
設定ファイルは以下の形式となります
<Role name="WebRole1"> <Instances count="1" /> <ConfigurationSettings> <Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" /> <Setting name="DataConnectionString" value="DefaultEndpointsProtocol=http;AccountName=<アカウント名>;AccountKey=<ハッシュキー>" /> </ConfigurationSettings> </Role>
設定ファイルの値を取得する方法は以下となります。
CloudStorageAccount cloudStorageAccount
= CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
CloudTableClient cloudTableClient = cloudStorageAccount.CreateCloudTableClient();
- 旧*.cscfgについて
設定ファイルは以下の形式となります
<Role name="WebRole1"> <Instances count="1" /> <ConfigurationSettings > <Setting name="BlobStorageEndpoint" value="http://<アカウント名>.blob.core.windows.net/" /> <Setting name="QueueStorageEndpoint" value="http://<アカウント名>.queue.core.windows.net/" /> <Setting name="TableStorageEndpoint" value="http://<アカウント名>.table.core.windows.net/" /> <Setting name="AccountName" value="<アカウント名>" /> <Setting name="AccountSharedKey" value="<ポータルサイトに表示されるキー>" /> </ConfigurationSettings> </Role>
設定ファイルの値を取得する方法は以下となります。
StorageAccountInfo tableAaccountInfo = StorageAccountInfo.GetAccountInfoFromConfiguration("TableStorageEndpoint"); //TableStorageDataServiceContextを継承したクラスから、テーブルを作成 TableStorage.CreateTablesFromModel(typeof(CommentDataServiceContext), tableAccountInfo);
ストレージアクセスに用いるクラス名の変更
分かっている範囲の情報において、Windows AzureストレージTableについての情報を記述します*2。ご覧の通り、設定ファイルからの値取得、テーブルの作成方法、クラス名等々が結構変わってます。実際に開発する際にはこれらに注意する必要があります。
- 新SDKにおける、Windows AzureストレージTableの操作方法
//アカウント情報取得 CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); //TableClient作成 CloudTableClient cloudTableClient = cloudStorageAccount.CreateCloudTableClient(); cloudTableClient.CreateTableIfNotExist("Comments"); //サービスコンテキストを定義 CommentServiceContext commentServiceContext = new CommentServiceContext( cloudStorageAccount.TableEndpoint.ToString(), cloudStorageAccount.Credentials); //Table内のデータにアクセス var query = commentServiceContext.CreateQuery<Comment>("Comments").AsQueryable();
- 旧SDKにおける、Windows AzureストレージTableの操作方法
//アカウント情報取得 StorageAccountInfo accountInfo = StorageAccountInfo.GetAccountInfoFromConfiguration("TableStorageEndpoint"); //TableClient作成 TableStorage.CreateTablesFromModel(typeof(CommentDataServiceContext), accountInfo); //サービスコンテキストを定義 CommentServiceContext commentServiceContext = new CommentDataServiceContext(accountInfo); //Table内のデータにアクセス var query = commentServiceContext.Comments.AsQueryable();
サポートされたLINQメソッドが変更している
自作アプリケーションを用いて、Windows Azure SDK for Visual Studio NovemberでサポートさているLINQメソッドを一部チェックしてみました。
- サポート
- Select
- Where
- ToList
- Take
- OrderBy 今回新たにサポート
- OrderByDescending 今回新たにサポート
- FirstOrDefault
- 未サポート
- SingleOrDefault
- LastOrDefault
- Count
- Min
- Max
- Average
- All
- Any
- LongCount
相変わらずCountやらAnyやらAllやらのメソッドは駄目らしい。「特定の条件に合ったEntityが一件以上存在するか?」というクエリを発行させようと思ったら、以下の様に記述すればOK?
bool isExistRecord = commentServiceContext.CreateQuery<Comment>("Comments") .Where( comment => IsValid(comment) ).FirstOrDefault() != null
*1:現在はWindows AzureストレージTableのみ確認
*2:同様の変更がQueue、Blobでも行われています