Thursday, 21 January 2016

Sitecore Azure module - Updated create database pipeline

One of the first things I noticed with the Azure module (when I initially started using it, not knowing much about how it worked) was that if it cannot connect to the databases using the connection strings that you (did or didn't) set, it will attempt to create your Azure databases automatically, from your local Sitecore databases.  Unfortunately the version I was using was using an old syntax for Azure (missing the SERVICE_OBJECTIVE), so even though we didn't end up using it to create databases (I ended up using SQL Management Studio 2014 'deploy database to Azure' task) I quickly whipped up a fixed pipeline.  The new class is pretty much a duplicate of the original, with a check for the new naming (eg. 'Standard S0') and the new SQL syntax.

CreateDatabaseNewSyntax.cs

using System.Data.SqlClient;
using System.Linq;

using Sitecore.Azure.Deployments.DatabaseProjects;
using Sitecore.Azure.Managers.AzureManagers;
using Sitecore.Azure.Pipelines.BasePipeline;
using Sitecore.Azure.Pipelines.DeployDatabase;
using Sitecore.Data.Sql;
using Sitecore.Diagnostics;


/// <summary>
/// Create database pipeline to fix the edition (newer Azure editions)
/// See https://msdn.microsoft.com/en-us/library/dn268335.aspx for syntax
/// </summary>
public class CreateDatabaseNewSyntax : CreateDatabase
{
  protected override void Action(RolePipelineArgsBase args)
  {
    Assert.ArgumentNotNull(args, "args");
    DeployDatabasePipelineArgs deployDatabasePipelineArgs = args as DeployDatabasePipelineArgs;
    Assert.IsNotNull(deployDatabasePipelineArgs, "deployDatabasePipelineArgs");
    if (deployDatabasePipelineArgs.DatabaseReference.Database.SqlAzureServiceDefinition.Tiers.All(t => t.Value.ToString() != deployDatabasePipelineArgs.Edition))
    {
      Sitecore.Azure.Configuration.Settings.GetRetryer().ExecuteNoResult(() => this.CreateAzureDatabase(
        deployDatabasePipelineArgs.TargetServer.ConnectionContext.ConnectionString,
        deployDatabasePipelineArgs.TargetDatabaseName,
        deployDatabasePipelineArgs.Edition,
        deployDatabasePipelineArgs.Size));
    }
    else
    {
      Sitecore.Azure.Configuration.Settings.GetRetryer().ExecuteNoResult(() => this.CreateAzureDatabase(deployDatabasePipelineArgs.DatabaseReference));
    }

    deployDatabasePipelineArgs.TargetServer.Refresh();
    deployDatabasePipelineArgs.TargetDatabase = Sitecore.Azure.Configuration.Settings.GetRetryer().Execute(() => deployDatabasePipelineArgs.TargetServer.Databases[deployDatabasePipelineArgs.TargetDatabaseName]);
    Assert.IsNotNull(deployDatabasePipelineArgs.TargetDatabase, "deployDatabasePipelineArgs.TargetDatabase");
    deployDatabasePipelineArgs.TargetDatabase.AutoClose = true;
  }

  private void CreateAzureDatabase(DatabaseReference databaseReference)
  {
    Assert.IsNotNull(databaseReference, "databaseReference");
    AzureSqlManager.Current.CreateDatabase(databaseReference);
  }

  private void CreateAzureDatabase(string connectionString, string name, string edition, string size)
  {
    Assert.ArgumentNotNull(connectionString, "connectionString");
    Assert.ArgumentNotNull(name, "name");
    Assert.ArgumentNotNull(edition, "edition");
    Assert.ArgumentNotNull(size, "size");
    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      SqlCommand command = sqlConnection.CreateCommand();
      sqlConnection.Open();
      string str = string.Empty;
      if (edition != string.Empty)
      {
        if (edition.IndexOf(' ') > 0)
        {
          // eg. "Standard S0"
          string[] editionValues = edition.Split(' ');
          str = string.Format(", EDITION = '{0}', SERVICE_OBJECTIVE = '{1}'", editionValues[0].ToLower(), editionValues[1]);
        }
        else
        {
          // eg. "business"
          str = string.Format(", EDITION = '{0}'", edition);
        }
      }
      command.CommandText = "CREATE DATABASE [" + name + "] (MAXSIZE = " + size + str + ")";
      SqlUtil.ExecuteNonQuery(command);
    }
  }
}

App_Config/Include/z/CustomAzure.configInclude in the 'z' folder so it is patched in at the end

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <DeployDatabase>
        <processor patch:instead="processor[@type='Sitecore.Azure.Pipelines.DeployDatabase.CreateDatabase, Sitecore.Azure']"
type="Custom.CreateDatabaseNewSyntax, Custom" />
      </DeployDatabase>
    </processors>
  </sitecore>
</configuration>

No comments:

Post a Comment