動的にモジュールを読み込む

Windows Azure Blog Storage上にアセンブリを置いて動的に読み込んでみましょう。

何の変哲もないインターフェース用意して

image

適当に2つほど実装して個別のアセンブリを作っておきます。

imageimage

MarshalByRefObjectがポイントですね。

ビルドしたアセンブリはBlobにUpしておきましょう。

一応Privateコンテナです。

さて今回はサンプルなのでWorkerRole内でアセンブリをロードして定期的に実行するようにします。

で、実際にアセンブリをロードするわけです。

		private void LoadAssembly(string AssemblyUrl,string AssemblyTypeName)
		{
			if (SampleAppDomain != null)
			{
				AppDomain.Unload(SampleAppDomain);
			}

			PermissionSet trustedLoadFromRemoteSourceGrantSet
				= new PermissionSet(PermissionState.Unrestricted);

			AppDomainSetup trustedLoadFromRemoteSourcesSetup = new AppDomainSetup();
				trustedLoadFromRemoteSourcesSetup.ApplicationBase =
					AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

			SampleAppDomain = AppDomain.CreateDomain("SampleDomain", null, trustedLoadFromRemoteSourcesSetup, trustedLoadFromRemoteSourceGrantSet);
			var webpermission = new WebPermission(
						NetworkAccess.Connect,
						AssemblyUrl
					);
			SampleAppDomain.PermissionSet.SetPermission(webpermission);
			SampleAppDomain.PermissionSet.Demand();
			SampleAssembly = (ISample.ISample)SampleAppDomain.CreateInstanceFromAndUnwrap(AssemblyUrl, AssemblyTypeName);
		}

 

こんな感じですね。リモートホスト上にアセンブリがあるのでWebPermissionで権限を付けてます。それ以外はいたって普通。

あとBlobをプライベートコンテナに置いているので、共有アクセス署名(SAS: Shared Access Signature)を付けないとアクセスできません。

		private string GetAssemblyUrl()
		{
			var assemblyName = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobName");
			var assemblyContainerName = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobContainerName"); ;
			var connectionString = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobStorage"); ;

			var account = CloudStorageAccount.Parse(connectionString);
			var client = account.CreateCloudBlobClient();

			var assemblyBlobContainer = client.GetContainerReference(assemblyContainerName);

			var policy = new SharedAccessPolicy
			{
				Permissions = SharedAccessPermissions.Read,
				SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),
				SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(10)
			};

			CloudBlob blob = assemblyBlobContainer.GetBlobReference(assemblyName);
			var accessurl = blob.Uri.ToString() + blob.GetSharedAccessSignature(policy);
			Trace.WriteLine(accessurl);

			return accessurl;
		}

 

SAS付けた状態のURLを返してもらって、そいつをCreateInstanceFromAndUnwrapに渡します。

ポイントはアクセス期限の開始時刻を現在時刻からマイナス5分してるところぐらいですかね。。。Blob Storage上の時刻よりローカルPCのほうが進んでたために、アクセスした時刻が署名で許可してる期間外になってFileNotFoundExceptionになるというヒドイ目を見ました。ふぅ。

最後にロードしたいアセンブリの情報をサービス設定ファイルに書いておきましょう。

image

で、サービス設定ファイルが更新されたらアセンブリをロードしなおすようにします。

		public override bool OnStart()
		{
			LoadAssembly(GetAssemblyUrl(), RoleEnvironment.GetConfigurationSettingValue("AssemblyTypeName"));

			RoleEnvironment.Changed += (s, e) =>
			{
				if (e.Changes.Any(chg => chg is RoleEnvironmentConfigurationSettingChange))
				{
					LoadAssembly(GetAssemblyUrl(), RoleEnvironment.GetConfigurationSettingValue("AssemblyTypeName"));
				}
			};

			return base.OnStart();
		}

とりあえずこんな感じ。

じゃ実行してみましょう。

起動した時はSample1.dllがロードされて、サービス設定ファイルをSample2.dllに変更してUpdateしたらちゃんとロードしなおされてますね!

あとは気が向いたらBlob上のDLLを入れ替えるなりしてロードしなおせばいいわけです。

もちろんロードした後はローカルのキャッシュで動作してるので、SASの期限切れても問題ないですしBlob上からファイルがなくなっても問題ないです。

拡張モジュールの実装とかいろいろ出来そうですね。AppDomainを工夫したらマルチテナントで遊べると思います。

 

おまけ。


using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
namespace WorkerRole1
{
public class WorkerRole : RoleEntryPoint
{
private ISample.ISample SampleAssembly;
private AppDomain SampleAppDomain;
public override void Run()
{
while (true)
{
Trace.WriteLine(SampleAssembly.Execute());
Thread.Sleep(5000);
}
}
public override void OnStop()
{
if (SampleAppDomain != null)
{
AppDomain.Unload(SampleAppDomain);
}
base.OnStop();
}
public override bool OnStart()
{
LoadAssembly(GetAssemblyUrl(), RoleEnvironment.GetConfigurationSettingValue("AssemblyTypeName"));
RoleEnvironment.Changed += (s, e) =>
{
if (e.Changes.Any(chg => chg is RoleEnvironmentConfigurationSettingChange))
{
LoadAssembly(GetAssemblyUrl(), RoleEnvironment.GetConfigurationSettingValue("AssemblyTypeName"));
}
};
return base.OnStart();
}
private void LoadAssembly(string AssemblyUrl,string AssemblyTypeName)
{
if (SampleAppDomain != null)
{
AppDomain.Unload(SampleAppDomain);
}
PermissionSet trustedLoadFromRemoteSourceGrantSet
= new PermissionSet(PermissionState.Unrestricted);
AppDomainSetup trustedLoadFromRemoteSourcesSetup = new AppDomainSetup();
trustedLoadFromRemoteSourcesSetup.ApplicationBase =
AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
SampleAppDomain = AppDomain.CreateDomain("SampleDomain", null, trustedLoadFromRemoteSourcesSetup, trustedLoadFromRemoteSourceGrantSet);
var webpermission = new WebPermission(
NetworkAccess.Connect,
AssemblyUrl
);
SampleAppDomain.PermissionSet.SetPermission(webpermission);
SampleAppDomain.PermissionSet.Demand();
SampleAssembly = (ISample.ISample)SampleAppDomain.CreateInstanceFromAndUnwrap(AssemblyUrl, AssemblyTypeName);
}
private string GetAssemblyUrl()
{
var assemblyName = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobName");
var assemblyContainerName = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobContainerName"); ;
var connectionString = RoleEnvironment.GetConfigurationSettingValue("AssemblyBlobStorage"); ;
var account = CloudStorageAccount.Parse(connectionString);
var client = account.CreateCloudBlobClient();
var assemblyBlobContainer = client.GetContainerReference(assemblyContainerName);
var policy = new SharedAccessPolicy
{
Permissions = SharedAccessPermissions.Read,
SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),
SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(10)
};
CloudBlob blob = assemblyBlobContainer.GetBlobReference(assemblyName);
var accessurl = blob.Uri.ToString() + blob.GetSharedAccessSignature(policy);
Trace.WriteLine(accessurl);
return accessurl;
}
}
}

view raw

gistfile1.cs

hosted with ❤ by GitHub

Facebook Open Graphを使ってみる

FacebookのOpen Graphを実際に触ってみよう企画です。

※サンプルソースのリポジトリ名がfacebookappli04なのは連載回数を間違えて4回目と思ってたからです(

Open Graphおもしろいね!

余談ですが、だんだんとAzure分が少なってきてますね。(まぁしょうがない気もする)

Go Azure

6月29日~6月30日の2日間、ベルサール汐留 でMicrosoftとJAZUGの共催イベント、Go Azureが開催されます。

image

内容は最新のWindows Azureに関する情報てんこ盛り!

Day 1
パブリック クラウド活用の成功事例や Windows Azure のもたらす新しい可能性など、最新情報をお伝えします。

Day 2
Japan Windows Azure User Group (JAZ) が中心となって、Windows Azure 関連の技術セッションやハンズオン セミナーのほか、エキスパートへの質問コーナー、さらにネットワーキング パーティなどを予定しています。

日付を見ても分かる通り、「MEET Windows Azure」の後、、、ということは、言わなくてもわかるな?(

ぜひ予定を空けて今後の情報をお待ちください!

Cloud meet up in YOKOTE

6月15日~6月17日、秋田県横手市で開催される「ITエースをねらえプロジェクト – Cloud meet up in YOKOTE」で講師します。

ITエースをねらえプロジェクト

ITエースをねらえプロジェクト では、Cloud Meet upをテーマに、6月15日から17日までの3日間、クラウドサービスを利用した5つのセッションをお送りします。クラウドサービスって何?という方から、クラウドを利用したサービスを開始したい方まで、すべての方に楽しんでいただけるワークショップとセミナーです!

担当は「クラウドサービスデベロップメントミーティング」ということで開発よりの話になるかと思います。

ちなみにJAZUGからは @harutama と一緒に2人で参加します。他の講師陣もパクえ先生始め、えらく豪華なので最寄りの方はぜひご参加ください!

秋田でMeet up!

Community Open Day 2012

6月9日に全国で行われるCommunity Open Day 2012の大阪会場でしゃべります。

 

コミュニティに所属している方はもちろん、未だコミュニティに所属していない方々にコミュニティの活動内容(勉強会)を披露し、興味があればそのコミュニティに参加してもらう機会を構築するオンライン/オフラインイベントです。
6月9日に全国のコミュニティと合同で、勉強会を行い会場に参加できる方は会場に参加、会場が遠地のため参加できない場合は「USTREAM」で参加するといったイベントです。
イベント自体はコミュニティ主体ですが、後援としてマイクロソフト社が付いているため、午前中はWindows 8を題材にしたキーノートや、DeveloperやITPro、などをターゲットにしたジェネラルセッションを実施します。
午後は各コミュニティから現場視点での話や先進的な技術の紹介などの勉強会を実施します。

6月8日に何かあるみたいなので、そのあたり含めて最新情報も盛り込めるかも? ちなみに @k1hash と一緒になので大阪で会われてない方もぜひぜひ遊びに来てください!

TechFieldersの集い 2012 初夏

直近ですが、5/19と5/26にTechFieldersの集いでしゃべります。

今回のテーマは、ずばり「System Center」。
そう、マイクロソフトの運用管理製品群の総称です。
2012 年はシステム管理者にとって重要な年です。なぜならば、System Center がこぞってリニューアルされるからです。
System Center 萌えの皆さまにとっては、まさに血湧き肉躍る年と言えます。
今回の「集い」では、恒例「普段表に出ないマイクロソフト エンジニアによるセッション」をご用意している他、各界の System Center 名人の方々に成功事例、失敗体験、儲かった話、損した話、System Center への文句…などをお話しいただきます。
いままで System Center をご存知なかった方も、この機会に是非ともお見知りおきいただければ幸いです。
イベントの後には、やはり恒例の懇親会も開催しますので体調を整えてご参加ください。
希少なロゴ グッズが当選するじゃんけん大会も予定しています。

おいらは「パブリック クラウド担当の現場も注目している System Center 2012 ~その理由は?」というタイトルで何か喋ります。

ご都合よろしければご参加くださいませ。

Windows Azure のセキュリティとプライバシー

プライバシーについて

2012年5月にWindows Azureのプライバシーに関する声明が更新されました。

あくまでマイクロソフトと、顧客である我々(Windows Azureの契約者)との話であることに注意が必要です。冒頭にもある通りWindows Azureを使用して提供しているアプリケーション等が扱うデータ等のプライバシーポリシーはマイクロソフトではなくそのサービス、アプリケーションのベンダーが責任を負います。

マイクロソフトはWindows Azure上に保存・アップロードされるデータはサービスを提供する目的でのみ使用される(使用というとあれですがGeoレプリケーションしありとかそういう使用かな)とのこと。ただ文中にもありますがGeoレプリケーションなど暗黙的に保存されてるデータの場所が国をまたがる場合があるのでそのあたりも気を付けましょう。なおプレビュー版(CTPやベータなど)は若干ポリシーが異なります。

セキュリティについて

こちらにまとまってます。

また、各クラウドのセキュリティアセスメントを登録し、だれでも参照できるCSA (Cloud Security Alliance)といったサイトがあるのですが、こちらのSTAR (Security Trust and Assurance Registry)にWindows Azure(とOffice 365、Dynamics CRM)が登録されています。

このサイトからおなじみのWindows Azureのセキュリティに関する状況を参照・確認(ダウンロード)することができますので便利ですね。また今後登録されるクラウドコンピューティング提供者が増えると比較したりする際の情報取りまとめサイトとして成長されることが期待されます。

※但しこのCSA自体は第三者機関による認証等はないので、登録される情報はあくまで各クラウドベンダーの自己申告です。とはいえ少し探しにくいこの手の情報にまとめてアクセスできるのはいいですね。

法律関連

よく導入検討時などに言われる米国愛国者法(いわゆるパトリオット法)などの懸念や誤解については以下のサイトがよくまとまっています。

心配な方はよく読んでくださいね。

また特に大事なところとしては準拠法と管轄裁判所ですね。

準拠法と管轄裁判所は日本

グローバルに展開するクラウドの場合、準拠法や管轄裁判所が米国などの海外になっている場合があります。マイクロソフトのOffice 365の場合は、準拠法は日本法、管轄裁判所は基本的に東京地方裁判所となっています。

※上記サイトより引用

Windows Azureなど契約する際に利用するMicrosoft Online Services Customer Portal のオンラインサブスクリプション契約の条件には以下の通り記載があります。

10. 雑則
  1. 準拠法   本契約は日本の法律を準拠法とします。1980 年国際物品売買契約に関する国連条約およびその付属文書は、本契約には適用されません。本製品は、著作権およびその他の知的財産権関連法ならびに国際条約により保護されています。

  2. 紛争の解決   本契約の強制履行を求めて提訴する場合は、東京地方裁判所に提起しなければなりません。上記にかかわらず、いずれの当事者も、知的財産権の侵害または秘密保持義務の違反に関する差止請求を行う場合には、任意の管轄裁判所において行えるものとします。

※オンライン サブスクリプション契約 ご契約条件 より引用

というわけでマイクロソフトのオンラインサービス関連はかなり日本ユーザーにやさしい柔軟な対応をしてもらえるようです。

 

余談

各ページ、シンプルで集約されつつあってわかりやすくなりましたね。後はもろもろ足らない部分の日本語化、Windows AzureだけじゃなくGFSやMIcrosoft Online Services全般の情報もどこからか集約して見れるとうれしいな。というか必要だと思います。

プロ生@大阪 & Windows Developer Days

今週末および来週以下のイベントで登壇します。

4/21 プログラミング生放送勉強会 第15回@大阪 [Windows 8, JavaScript, Azure, Kinect 他] #pronama

プロ生はWindows AzureとKinectです。すごく浅いところを喋ります。ネタ思案中。

 

Windows Developer Days

こちらは4月24日~25日にあるMicrosoftのイベントです。2日目(25日)の SP-011 Windows 8 と Azure で更に広がる VOCALOID の世界 というブレイクアウトセッションで、ボーカロイドの父、劔持さんと一緒に登壇します。Day 2のキーノートが先にあるので、そちらも是非!

Windows Azure Media Servicesがアナウンスされました

National Association of Broadcasters (NAB) 2012 にてWindows Azure Media Servicesがアナウンスされました。

そもそもWindows Azure Media Servicesってなんでしょう?

発表されたばかりのこのサービスを利用すると、スマートテレビやセットトップボックス、MacOS、iOS、AndroidなどMS以外のプラットフォーム、それからもちろんXBoxやWindows Phone、Windows PCを含むほぼすべてのデバイスへのメディア配信を簡素化できるようです。

もともとこれらの機能はPlayReadyでおなじみのMicrosoft Media Platformで培われた機能ですね。つまり簡単に言うとMicrosoft Media PlatformのサーバーサイドがWindows Azureのサービスとして追加されるということです。

素晴らしいですね~!

さてサービス化されて何ができるんでしょう?まだ細かい機能が公開されてないので公式サイトを適当に見てみます。

End to Endのワークフロー

メディアワークフローが構築できます。ニーズに合わせて構成を組み合わせたり構成済みの設定を利用したり。アップロードやエンコーディング、フォーマット変換、コンテンツ保護(DRM)、配信が行えます。

ハイブリッドワークフロー

複数のフォーマットに変換して3rd Party製のCDNに配信したり外部アプリとREST API経由で連携したりできるみたいです。

Windows、Xbox、iOS、Androidのサポート

各デバイスに必要なメディアの作成や管理、複数デバイス間での配信機能などを提供。

Media Servicesのベネフィット

Windows Azure Media ServicesはMicrosoft Media Platformのクラウドサービス版です。既存のソリューションやカスタムワークフローなどニーズに合わせて簡単にサービスを管理できます。

取り込み

標準的なHTTPや、3rd Party製のエージェントを使用したセキュアで高速なUDP通信を使用してWindows Azure Media Servicesのストレージにメディアをアップロードできます。

エンコード

標準的なコデックとフォーマット、Smooth StreamingやHTTP Live Streaming、MPEG-DASHやFlashなどビルトインで提供されるWindows Azure Media Encoderまたは3rd Party製のエンコーダを利用できます。

フォーマット変換

ストリームの入力と出力を制御してライブラリ全体や個々のストリームを変換できます。

コンテンツ保護

Liveやオンデマンドの音声やビデオを標準的なMPEG Common EncryptionやMicrosoft Play Readyを使って暗号化することができます。業界でも最も受け入れられているDRMをコンテンツに追加できます。またウォーターマークや電子透かしを追加することもできます。

オンデマンドストリーミング

Windows Azure CDNや3rd Party製のCDNを経由してコンテンツをシームレスに提供することができます。

ライブストリーミング

ライブチャンネルのストリーミングやMedia Servicesを使ったエンコード、外部フィードからの配信などを簡単に作成し、配信できます。サーバー側DVRやリプレイ機能なども利用できます。

価格など

今時点ではプレビュー版なのでコストはかかりません。(但しストレージやネットワーク転送料、CDNなどの既存のWindows Azure機能に関するコストは発生します)

サインアップするにはメールしましょう!(※想定してるシナリオも書いてねとのこと)

開発するには

この辺参照 → Windows Azure Media Services Preview for Developers

おまけ

この辺の詳細はWindows Developer DaysのSC-008 Windows Azure Platformでの動画配信アプリケーション開発で聞けるみたいですよ!

Azure Blob Storageのコンテナのパーミッションを変更する

小ネタです。Azure Storage Explorerだと出来なさそうだったのでPowerShellでサクッとAzure Blob Storageのコンテナのパーミッションを変更します。

  • Windows Azure PowerShell Cmdlets を利用するので、あらかじめインストールしておいてください。
  • 理屈的には大したことしてませんのでAzure SDKを使ったマネージコードでもできます。

Windows Azure PowerShell Cmdletsを起動して、Get-Containerコマンドでコンテナを取得します。

$container = Get-Container -StorageAccountName ***YourAzureStorageAccount*** -StorageAccountKey ***YourStorageKey***

 

取得できたらInstance(コンテナ)のGetPermission()メソッドを呼んで現在の権限を取得します。

$permission = $container[3].Instance.GetPermissions()

 

PublicAccessプロパティが現在の値です。(OffがPrivateコンテナ、ContanierがPublic Contanier、BlobがPublic Blobになります)

今現在はOffなのでPrivate(非公開)です。

image

image

このPublicAccessプロパティに”Container”等をセットし、Instanceプロパティ(コンテナ)のSetPermissions()メソッドを呼び出して設定を反映させます。

$permission.PublicAccess = "Container"
$container[3].Instance.SetPermissions($permission)

 

image

無事コンテナのアクセスレベルが変わりました。

image