7)Issues with v1.3 SDK
- 質問:
Azure SDK 1.2で作成されたソリューションを、1.3にアップグレードするやり方を教えてください。[開発][初級]
- 回答:
Visual Studio 2010のウィザードに従って実施してください。
- 解説:
Visual Studio 2010では、Azure SDK 1.2からAzure SDK 1.3への移行が可能です。
Azure SDK 1.2で作成されたソリューションを開くと自動的にウィザードが表示されます。ウィザードに従って変換してください。
では、変更点を見ていきます。
1. servicedefinition.csdefファイルの変更
ウィザードに従って変換するとservicedefinition.csdefファイルが変更されます。変換前後で比較してみたいと思います。
Azure SDK 1.2の場合は以下になります。
<?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="CloudService2" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <WebRole name="WebRole1"> <InputEndpoints> <InputEndpoint name="HttpIn" protocol="http" port="80" /> </InputEndpoints> <ConfigurationSettings> <Setting name="DiagnosticsConnectionString" /> </ConfigurationSettings> <InternalEndpoint name="InternalHttpIn" protocol="http" /> </WebRole> </ServiceDefinition>
一方Azure SDK 1.3では以下のようになります。
<?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="CloudService1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <WebRole name="WebRole1"> <Sites> <Site name="Web"> <Bindings> <Binding name="HttpIn" endpointName="HttpIn" /> </Bindings> </Site> </Sites> <ConfigurationSettings> <Setting name="DiagnosticsConnectionString" /> </ConfigurationSettings> <Endpoints> <InputEndpoint name="HttpIn" protocol="http" port="80" /> <InternalEndpoint name="Endpoint2" protocol="http" /> </Endpoints> </WebRole> </ServiceDefinition>
比較すると、まず<Sites>タグが追加されるのと、<InputEndpoint>の前に<Endpoints>タグが付与されているのが分かります。
Azure SDK 1.2まではHWC(Hosted Web Core)と呼ばれるIISのサブセットを使用していたため1つのアプリケーションしかホストできなかったのですが、SDK 1.3でIISの全機能がサポート(FullIIS)されたことにより複数のアプリケーションをホストできるようになりました。<Sites>タグは、SDK 1.3で複数のアプリケーションをホストできるようになって追加されたタグです。次に<Endpoints>タグですが、これはこれまでの<InputEndpoints>タグとInternalEndpoint>タグを整理して可読性を向上するためのようです。
2. アプリケーションの動作
CloudStorageAccount.FromConfigurationSetting()が実行時に例外を出力するようになりました。
CloudStorageAccount.FromConfigurationSetting()は、ストレージアカウントをセットする際の構成データを表現するCloudCloudStorageAccountオブジェクトを取得するメソッドです。CloudStorageAccount.SetConfigurationSettingPublisher()でストレージアカウントを設定するのでペアで使用しています。
これがエラーになったのはFullIISがサポートされた影響です。Azure SDK 1.2ではWebRole.csで定義していたRoleEntryPointクラスのコードとWebアプリケーションはすべてWaWebHost.exe内部で実行されていました。そのためRoleEntryPointクラスでCloudStorageAccount.SetConfigurationSettingPublisher()を定義すれば、すべての箇所で取得することができました。しかし、Azure SDK 1.3ではFullIISをサポートしたことによりRoleEntryPointはWallSHost.exeで実行されてWebアプリケーションはすべてw3wp.exeで実行されるようになりました。w3wp.exeは通常のIISのプロセスでそれぞれが自前のアプリケーションドメインで実行されます。よって、別プロセス/別ドメインでそれぞれが動作するのでRoleEntryPointクラスでCloudStorageAccount.SetConfigurationSettingPublisher()を設定したとしても、Webアプリケーション側でCloudStorageAccount.FromConfigurationSetting()を呼び出した際にエラーになってしまうようになったのです。
なので、対策は同一プロセス/同一ドメインでCloudStorageAccount.SetConfigurationSettingPublisher()を動作させる事です。つまり各Webアプリケーションの全体の設定を行うGlobal.asaxを開き、Application_Startメソッド内に追加します。
protected void Application_Start(object sender, EventArgs e) { CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) => { var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName); configSettingPublisher(connectionString); }); }
また、毎回RoleEnvironment.GetConfigurationSettingValue()で取得してParseしてCloudCloudStorageAccountオブジェクトを取得することも可能です。
var cloudStorageAccount = CloudStorageAccount.Parse (RoleEnvironment.GetConfigurationSettingValue("DataConnectionString"));
3. プロジェクトファイル(ccproj)の変更
ProductVersionが1.2から1.3に変更されています。
以上が1.2から1.3の変更点です。特にFullIISの影響が大きいので注意が必要です。