読者です 読者をやめる 読者になる 読者になる

しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Web サイトの環境情報をクラウドサービスっぽく取得するためのクラスを書いてみた

Azure クラウドサービスには RoleEnvironment クラスがあり、このクラスを使うことでロールの情報とか構成ファイルが変更されたイベントなどをキャッチ出来るのですが、Azure Web サイトは普通の IIS で動く Web アプリケーションなので特にそういったものは用意されていません。

参考までに RoleEnvironment クラスのリファレンスを貼っておきます。

RoleEnvironment Class (Microsoft.WindowsAzure.ServiceRuntime)

普通の IIS で動くと言いつつも、割と Web サイト向けにカスタムモジュールが入っていたりするので、そのあたりの情報を環境変数から読み取って使いやすくしたクラスを作りました。

public static class WebsiteEnvironment
{
    public static bool IsAvailable
    {
        get { return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")); }
    }

    public static bool Is64BitPlatform
    {
        get { return Environment.Is64BitProcess; }
    }

    public static string InstanceId
    {
        get { return Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"); }
    }

    public static string ShortInstanceId
    {
        get { return InstanceId != null ? InstanceId.Substring(0, 6) : null; }
    }

    public static string SiteName
    {
        get { return Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); }
    }

    public static string HostName
    {
        get { return Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"); }
    }

    public static WebsiteComputeMode? ComputeMode
    {
        get { return EnumHelper.Convert<WebsiteComputeMode>(Environment.GetEnvironmentVariable("WEBSITE_COMPUTE_MODE")); }
    }

    public static WebsiteSiteMode? SiteMode
    {
        get { return EnumHelper.Convert<WebsiteSiteMode>(Environment.GetEnvironmentVariable("WEBSITE_SITE_MODE")); }
    }

    public static WebsiteSku? Sku
    {
        get { return EnumHelper.Convert<WebsiteSku>(Environment.GetEnvironmentVariable("WEBSITE_SKU")); }
    }

    public static IDictionary<string, string> AppSettings
    {
        get { return EnvironmentHelper.GetVariables("APPSETTING_"); }
    }

    public static IDictionary<string, string> MySqlConnections
    {
        get { return EnvironmentHelper.GetVariables("MYSQLCONNSTR_"); }
    }

    public static IDictionary<string, string> SqlServerConnections
    {
        get { return EnvironmentHelper.GetVariables("SQLAZURECONNSTR_"); }
    }

    internal class EnvironmentHelper
    {
        public static IDictionary<string, string> GetVariables(string prefix)
        {
            return Environment.GetEnvironmentVariables()
                                .Cast<DictionaryEntry>()
                                .Where(p => ((string)p.Key).StartsWith(prefix))
                                .ToDictionary(p => ((string)p.Key).Substring(prefix.Length), p => (string)p.Value);
        }
    }

    internal class EnumHelper
    {
        public static TEnum? Convert<TEnum>(string name) where TEnum : struct
        {
            TEnum result;

            if (Enum.TryParse(name, true, out result))
            {
                return result;
            }

            return null;
        }
    }

    public enum WebsiteComputeMode
    {
        Shared,
        Dedicated,
    }

    public enum WebsiteSiteMode
    {
        Limited,
        Basic
    }

    public enum WebsiteSku
    {
        Free,
        Shared,
        Basic,
        Standard,
    }
}

Web サイトのみで定義されている環境変数を読み取るので、ローカルの開発環境では動きません。実際に Web サイトにデプロイして各種情報を出力してみると以下の通りです。

f:id:shiba-yan:20140829001736p:plain

個人的には InstanceId / ShortInstanceId が取れたら満足な感じです。後はデプロイしているスロット名を何とか取りたいのですが、ちょっと難しい感じでした。

コードは Gist にも置いてあるので、そっちを使ってもらっても問題ないです。

https://gist.github.com/shibayan/d07ac1a7c98ecf0daf8c

Management REST API を叩けば、もっとさまざまな情報が取れますが、証明書周りがめんどくさいのとレスポンスが返ってくるまでに時間が結構かかるので止めておきました。

出来れば IIS を再起動するメソッドとかを実装したいですね。