// ----------------------------------------------------------------------------------
// Unified Logging
//
// Copyright (c) UL Analytics, LLC. All rights reserved.
//
// ----------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.AccessControl;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace UnifiedLogging.Web.Site
{
public static class UmbracoAzureSetup
{
#region public Static Methods
///
/// Sets up umbraco for load balancing in Azure.
/// Things to Note:
/// 1) This is coded to work with one Site element under Sites in the RoleModel.xml.
/// Update the code if this is not your case.
/// 2) Sets permissions for NETWORK SERVICE, if the app pool is different update the code.
///
public static void Setup()
{
SetPermissions();
UpdateUmbracoSettings();
}
#endregion
#region private Static Methods
///
/// This will get the attribute of the first Site under Sites in the RoleModel.xml.
/// If there are multpile site elements be sure to update this method to return the correct physical path.
///
///
private static string GetWebSiteDirectory()
{
var rootPath = string.Empty;
var roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
var roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("empty",
"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition");
var siteElement = roleModelDoc.XPathSelectElement("/empty:RoleModel/empty:Sites/empty:Site",
namespaceManager);
if (siteElement != null)
{
var attr = siteElement.Attribute("physicalDirectory");
if (attr != null)
{
rootPath = Path.Combine(roleRootDir, attr.Value);
}
}
return rootPath + Path.DirectorySeparatorChar;
}
///
/// Will set full control permissions for NETWORK SERVICE on the entire web directory.
///
private static void SetPermissions()
{
var roleRootDir = GetWebSiteDirectory();
if (String.IsNullOrEmpty(roleRootDir) == false)
{
roleRootDir = roleRootDir.TrimEnd('\\');
var accessControl = Directory.GetAccessControl(roleRootDir);
accessControl.AddAccessRule(new FileSystemAccessRule("NETWORK SERVICE", FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit |
InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow));
Directory.SetAccessControl(roleRootDir, accessControl);
}
}
///
/// Updates the umbracosetting.config with the ip addresses of the instances in the role.
///
private static void UpdateUmbracoSettings()
{
var serverIps = new List();
if (RoleEnvironment.IsAvailable)
{
foreach (RoleInstance roleInstance in RoleEnvironment.CurrentRoleInstance.Role.Instances)
{
foreach (RoleInstanceEndpoint endpoint in roleInstance.InstanceEndpoints.Values)
{
var ipString = endpoint.IPEndpoint.Address.ToString();
if (serverIps.Contains(ipString) == false)
{
serverIps.Add(ipString);
}
}
}
}
WriteDistributedServers(serverIps);
}
private static void WriteDistributedServers(List serverIps)
{
var websiteRoot = GetWebSiteDirectory();
//taken from umbraco source:)
var configPath = websiteRoot + "config" +
Path.DirectorySeparatorChar + "umbracoSettings.config";
var umbracoSettings = XDocument.Load(configPath);
var serversElement = umbracoSettings.XPathSelectElement("/settings/distributedCall/servers");
if (serversElement != null)
{
serversElement.RemoveNodes();
foreach (var serverIp in serverIps)
{
var serverElement = new XElement("server", serverIp);
serversElement.Add(serverElement);
}
umbracoSettings.Save(configPath);
}
}
#endregion
}
}