Skip to content

Instantly share code, notes, and snippets.

@paulryan
Created July 24, 2014 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulryan/cbfaa966571d6a9cdb8b to your computer and use it in GitHub Desktop.
Save paulryan/cbfaa966571d6a9cdb8b to your computer and use it in GitHub Desktop.
public class DeploymentActionCreateSiteCollection : DeploymentAction<bool>
{
public DeploymentActionCreateSiteCollection(ClientContext adminTenantContext, IDeploymentActionCreateSiteCollectionArgs args, string webTemplate)
: base(adminTenantContext, "Checking for existing site collection", args.Verbose)
{
this.CommandLineArguments = args;
this.WebTemplate = webTemplate;
}
protected IDeploymentActionCreateSiteCollectionArgs CommandLineArguments { get; set; }
protected string WebTemplate { get; set; }
protected override bool Action()
{
var tenant = new Tenant(this.Context);
var siteStatus = SPCsomUtil.SiteUtil.GetSiteStatus(tenant, this.CommandLineArguments.SiteCollectionUrl);
switch (siteStatus)
{
case SiteStatus.Exists:
if (this.CommandLineArguments.DeleteSiteCollection)
{
RecycleSiteCollection(tenant);
DeleteRecycledSiteCollection(tenant);
}
else
{
this.Print("Using existing site collection");
return true;
}
break;
case SiteStatus.Recycled:
DeleteRecycledSiteCollection(tenant);
break;
case SiteStatus.NotExists:
this.Print("Cannot find existing site collection");
break;
case SiteStatus.Creating:
WaitForSiteProvision(tenant);
return true;
default:
throw new Exception("Unhandled site status type: " + siteStatus.ToString());
}
// Initialise site creation properties
this.Print("Creating new site collection");
var siteCreationProps = new SiteCreationProperties()
{
Title = this.CommandLineArguments.SiteCollectionTitle,
Url = this.CommandLineArguments.SiteCollectionUrl,
Owner = this.CommandLineArguments.SiteCollectionOwner,
Template = this.WebTemplate,
StorageMaximumLevel = Configuration.SiteCreation.Storage.MaximumLevel.Get(),
StorageWarningLevel = Configuration.SiteCreation.Storage.WarningLevel.Get(),
UserCodeMaximumLevel = Configuration.SiteCreation.UserCode.MaximumLevel.Get(),
UserCodeWarningLevel = Configuration.SiteCreation.UserCode.WarningLevel.Get()
//Lcid = Constants.Locales.Lcid.English_UK
//TimeZoneId = ??
};
// Create site collection
tenant.CreateSite(siteCreationProps);
this.Context.Load(tenant);
this.Context.ExecuteQuery();
WaitForSiteProvision(tenant);
return true;
}
private void WaitForSiteProvision(Tenant tenant)
{
this.Print("Provisioning site collection");
ConsoleAppUtil.WaitUntilSiteStatus(
tenant,
this.CommandLineArguments.SiteCollectionUrl,
new SiteStatus[] { SiteStatus.Exists },
new SiteStatus[] { SiteStatus.Creating },
() => { this.Print(Constants.Text.Waiting); });
}
private void RecycleSiteCollection(Tenant tenant)
{
this.Print("Sending existing site collection to the recycle bin");
tenant.RemoveSite(this.CommandLineArguments.SiteCollectionUrl);
this.Context.Load(tenant);
this.Context.ExecuteQuery();
ConsoleAppUtil.WaitUntilSiteStatus(
tenant,
this.CommandLineArguments.SiteCollectionUrl,
new SiteStatus[] { SiteStatus.Recycled },
new SiteStatus[] { SiteStatus.Exists },
() => { this.Print(Constants.Text.Waiting); });
}
private void DeleteRecycledSiteCollection(Tenant tenant)
{
this.Print("Deleting existing site collection from the recycle bin");
// After deleting a site to the recycle bin, it goes into a funny state for
// a while where it can't be deleted but still returns the recycled state.
// We use this try catch in loop to wait until it works.
ConsoleAppUtil.WaitUntil(() =>
{
try
{
tenant.RemoveDeletedSite(this.CommandLineArguments.SiteCollectionUrl);
this.Context.Load(tenant);
this.Context.ExecuteQuery();
return false;
}
catch (Exception ex)
{
if (ex.HResult == -2146233088)
{
// Stay in loop and try again
this.Print(Constants.Text.Waiting);
}
else
{
throw ex;
}
}
return true;
});
ConsoleAppUtil.WaitUntilSiteStatus(
tenant,
this.CommandLineArguments.SiteCollectionUrl,
new SiteStatus[] { SiteStatus.NotExists },
new SiteStatus[] { SiteStatus.Recycled },
() => { this.Print(Constants.Text.Waiting); });
}
}
public static class ConsoleAppUtil
{
public static void WaitUntilSiteStatus(Tenant tenant, string siteUrl, IEnumerable<SiteStatus> successStatuses, IEnumerable<SiteStatus> waitStatuses, Action printFunc)
{
if (tenant == null || string.IsNullOrEmpty(siteUrl) || successStatuses == null || !successStatuses.Any() || waitStatuses == null || !waitStatuses.Any())
{
throw new WaitTimeoutException("WaitUntilSiteStatus received invalid parameters");
}
WaitUntil(() =>
{
bool isWaiting;
var siteStatus = SPCsomUtil.SiteUtil.GetSiteStatus(tenant, siteUrl);
if (successStatuses.Contains(siteStatus))
{
isWaiting = false;
}
else if (waitStatuses.Contains(siteStatus))
{
printFunc();
isWaiting = true;
}
else
{
throw new WaitTimeoutException("WaitUntilSiteStatus encountered unexpected site status");
}
return isWaiting;
});
}
public static void WaitUntil(Func<bool> waitUntilFalseFunc)
{
bool isWaiting = true;
for (int i = 0; isWaiting && i < Configuration.SiteCreation.WaitPeriodIterations; i++)
{
Thread.Sleep(Configuration.SiteCreation.WaitPeriodMs);
isWaiting = waitUntilFalseFunc();
}
if (isWaiting)
{
throw new WaitTimeoutException("WaitUntil has timed out");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment