csharp Sitecore部署管理器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp Sitecore部署管理器相关的知识,希望对你有一定的参考价值。
using Sitecore.Data.Managers;
using Sitecore.Data.Serialization;
using Sitecore.Diagnostics;
using Sitecore.Exceptions;
using Sitecore.Publishing;
using Sitecore.SecurityModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Think.UKB.Deployment.Logging;
namespace Think.UKB.Deployment
{
public class DeploymentManager
{
/// <summary>
/// Lock to prevent serialization and deserialization to be running at same time.
/// re-entrant locks will prevent a deadlock in the case of this called by the DeserializeFromZip and then DeserializeAll (etc)
/// </summary>
private static readonly object LockAll = new object();
#region Properties
/// <summary>
/// Get the folder to read serialized content from. Defaults to SerializationFolder from Sitecore settings (web.config)
/// For deserializing it must be SerializationFolder from Sitecore settings (web.config)
/// </summary>
public string SerializationRootFolder { get; protected set; }
public ILogger Log { get; set; }
private static LoadOptions _options;
protected LoadOptions Options { get { return _options ?? (_options = new LoadOptions { DisableEvents = true }); } }
#endregion Properties
#region Constants
protected const string WebDb = "web";
protected const string MasterDb = "master";
protected const string CoreDb = "core";
protected const string RootItem = "sitecore";
protected const string ContentRoot = RootItem + "\\content";
protected const string LayoutRoot = RootItem + "\\layout";
protected const string RenderingsRoot = LayoutRoot + "\\renderings";
protected const string SublayoutsRoot = LayoutRoot + "\\sublayouts";
protected const string SystemRoot = RootItem + "\\system";
protected const string MediaRoot = RootItem + "\\media library";
protected const string TemplateRoot = RootItem + "\\templates";
#endregion Constants
#region Constructor
public DeploymentManager()
{
SerializationRootFolder = System.Web.HttpContext.Current.Server.MapPath(Sitecore.Configuration.Settings.SerializationFolder);
Log = new HtmlLogger();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="log">change the default logger</param>
/// <param name="serializationRoot">use a different root for serialization - warning Sitecore will fail if deserializing if it's not the SerializationFolder</param>
public DeploymentManager(ILogger log, string serializationRoot)
{
SerializationRootFolder = serializationRoot;
Log = log;
}
#endregion Constructor
#region Deserialize
/// <summary>
/// Given a zip file, will unzip and load the serialized content - will clear all existing serialized content from the disk.
/// </summary>
/// <param name="zipFilePath"></param>
public void DeserializeFromZipFile(string zipFilePath)
{
lock (LockAll)
{
var timer = GetTimer();
var zipReader = new Sitecore.Zip.ZipReader(zipFilePath);
//The serialization has to start from the web.config settings folder, otherwsie
//the deserialize methods will throw exceptions about the folder location.
var unzipPath = SerializationRootFolder;
try
{
if (Directory.Exists(unzipPath))
Directory.Delete(unzipPath, true);
}
catch (Exception e)
{
Log.Error("Could not remove previous unzipped content. " + e.Message);
Log.Info("Derializing halted");
return;
}
foreach (var entry in zipReader.Entries)
{
if (entry.IsDirectory)
{
Directory.CreateDirectory(Path.Combine(unzipPath, entry.Name));
continue;
}
var path = Path.GetDirectoryName(Path.Combine(unzipPath, entry.Name));
if (string.IsNullOrEmpty(path))
throw new Exception("Error getting path location during unzip.");
try
{
if (!Directory.Exists(path))
{
//Log.Info("Creating folder " + path);
Directory.CreateDirectory(path);
}
}
catch (Exception e)
{
Log.Error("Couldn't create path " + path + e.Message);
}
try
{
using (var stream = entry.GetStream())
using (var output = File.OpenWrite(Path.Combine(unzipPath, entry.Name)))
{
byte[] buffer = new byte[0x1000];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
output.Write(buffer, 0, read);
}
}
catch (Exception ex)
{
Log.Error("Error while unzipping content" + ex.Message);
return;
}
}
timer.Stop();
Log.Info(string.Format("Unzip took {0} seconds", timer.Elapsed.TotalSeconds));
DeserializeAll();
}
}
/// <summary>
/// Update everything from the file system.
/// </summary>
public void DeserializeAll()
{
lock (LockAll)
{
Log.Info("Deserialize All");
var timer = GetTimer();
try
{
//disable the automatic serialization (in all threads) while this is running
ItemHandler.Disabled = true;
DeserializeMedia();
DeserialiseTemplates();
DeserializeLayouts();
DeserializeCoreDb();
DeserializeContent();
}
finally
{
ItemHandler.Disabled = false;
}
timer.Stop();
Log.Info(string.Format("Deserialize all took : {0} seconds", timer.Elapsed.TotalSeconds));
}
}
/// <summary>
/// Updates everything in core/sitecore
/// </summary>
public void DeserializeCoreDb()
{
lock (LockAll)
{
var contentPath = Path.Combine(new[] { SerializationRootFolder, CoreDb, RootItem });
DeserialiseTree(contentPath);
}
}
/// <summary>
/// Updates master/sitecore/system recursively
/// </summary>
public void DeserializeSystemSettings()
{
lock (LockAll)
{
var contentPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, SystemRoot });
DeserialiseTree(contentPath);
}
}
/// <summary>
/// Updates master sitecore/layout recursively
/// </summary>
public void DeserializeLayouts()
{
lock (LockAll)
{
var contentPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, LayoutRoot });
DeserialiseTree(contentPath);
}
}
/// <summary>
/// Updates master/sitecore/content recursively
/// </summary>
public void DeserializeContent()
{
lock (LockAll)
{
var contentPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, ContentRoot });
DeserialiseTree(contentPath);
}
}
/// <summary>
/// Updates master/sitecore/layout/sublayouts
/// </summary>
public void DeserialiseSubLayouts()
{
lock (LockAll)
{
var sublayoutsPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, SublayoutsRoot });
DeserialiseTree(sublayoutsPath);
}
}
/// <summary>
/// Updates master/sitecore/layout/renderings recursively
/// </summary>
public void DeserialiseRenderings()
{
lock (LockAll)
{
var renderingPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, RenderingsRoot });
DeserialiseTree(renderingPath);
}
}
/// <summary>
/// Updates master/sitecore/media library recursively
/// </summary>
public void DeserializeMedia()
{
lock (LockAll)
{
var mediaItemsPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, MediaRoot });
DeserialiseTree(mediaItemsPath);
}
}
/// <summary>
/// Updates master/sitecore/Templates recursively
/// </summary>
public void DeserialiseTemplates()
{
lock (LockAll)
{
var templatesPath = Path.Combine(new[] { SerializationRootFolder, MasterDb, TemplateRoot });
DeserialiseTree(templatesPath);
}
}
/// <summary>
/// Calls the sitecore load to deserialize and and create/update the tree with the items found
/// </summary>
/// <param name="contentPath"></param>
private void DeserialiseTree(string contentPath)
{
Log.Debug("Getting all from " + contentPath);
try
{
using (new SecurityDisabler())
{
Manager.LoadTree(contentPath, Options);
}
}
catch (Exception e)
{
Log.Error(e);
}
}
#endregion Deserialize
#region Serialize
/// <summary>
/// Serialize All the things
/// </summary>
/// <returns></returns>
public void SerializeAll()
{
lock (LockAll)
{
var timer = GetTimer();
Log.Info("Serialize All");
Manager.CleanupPath(SerializationRootFolder, true);
SerializeContent();
SerializeLayouts();
SerializeMedia();
SerializeTemplates();
//SerializeCore();
timer.Stop();
Log.Info(string.Format("Serialize All took {0} seconds", timer.Elapsed.TotalSeconds));
}
}
public void SerializeCore()
{
lock (LockAll)
{
Log.Info("Serialize Core");
DumpTree(ContentRoot, CoreDb);
}
}
/// <summary>
/// Serialize the tree from /sitecore/content
/// </summary>
public void SerializeContent()
{
lock (LockAll)
{
Log.Info("Serialize Content");
DumpTree(ContentRoot);
}
}
/// <summary>
/// Serailize layouts.
/// </summary>
public void SerializeLayouts()
{
lock (LockAll)
{
Log.Info("Serialize Layouts");
DumpTree(LayoutRoot);
}
}
/// <summary>
/// Serialize Media items
/// </summary>
public void SerializeMedia()
{
lock (LockAll)
{
Log.Info("Serialize Media");
DumpTree(MediaRoot);
}
}
/// <summary>
/// Serializes Templates section
/// </summary>
public void SerializeTemplates()
{
lock (LockAll)
{
Log.Info("Serialize Templates");
DumpTree(TemplateRoot);
}
}
/// <summary>
/// Serialize the tree from the given (sitecore) path. Assumes master DB if name not supplied.
/// </summary>
/// <param name="path"></param>
/// <param name="database"></param>
protected void DumpTree(string path, string database = MasterDb)
{
if (string.IsNullOrEmpty(database))
throw new InvalidValueException("Invalid database name");
var db = Sitecore.Data.Database.GetDatabase(database);
if (db == null)
throw new InvalidValueException(string.Format("{0} in not a vaild database", database));
var itemPath = ConvertToSitecorePath(path);
//Need security disabled to allow access to core/other sections that may be restricted for anon access.
using (new SecurityDisabler())
{
var item = db.GetItem(itemPath);
if (item == null)
{
Log.Warn(string.Format("Path '{0}' didn't return an item for db '{1}'", itemPath, database));
return;
}
Manager.DumpTree(item);
}
}
/// <summary>
/// Convert folder path to sitecore path (swap '\' with '/')
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static string ConvertToSitecorePath(string path)
{
var itemPath = "/" + path.Replace("\\", "/");
return itemPath;
}
private static Stopwatch GetTimer()
{
var timer = new Stopwatch();
timer.Start();
return timer;
}
/// <summary>
/// Creates a new zip file of all currently serialized content.
/// </summary>
/// <returns>Full path to the zip file</returns>
public string CreateZipFile()
{
lock (LockAll)
{
var timer = GetTimer();
var zipFile = Path.Combine(SerializationRootFolder, "content.zip");
try
{
Log.Info("Remove previous zip file");
if (File.Exists(zipFile))
{
File.Delete(zipFile);
}
}
catch
{
Log.Warn("Unable to delete previous zip file.");
}
using (var fileWriter = new Sitecore.Zip.ZipWriter(zipFile))
{
var files = GetFiles(SerializationRootFolder, "*.item|*.user|*.role",
SearchOption.AllDirectories);
Log.Info(string.Format("Adding files ({0})", files.Count()));
var length = SerializationRootFolder.Length;
if (!SerializationRootFolder.EndsWith("\\"))
length += 1;
foreach (var file in files)
{
fileWriter.AddEntry(file.Remove(0, length), file);
}
}
timer.Stop();
Log.Info(string.Format("Zip took {0} seconds", timer.Elapsed.TotalSeconds));
return zipFile;
}
}
/// <summary>
/// Get all files based on search string supplied.
/// </summary>
/// <param name="path"></param>
/// <param name="searchPattern"></param>
/// <param name="searchOption"></param>
/// <returns></returns>
protected static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
{
string[] searchPatterns = searchPattern.Split('|');
List<string> files = new List<string>();
foreach (string sp in searchPatterns)
files.AddRange(Directory.GetFiles(path, sp, searchOption));
files.Sort();
return files.ToArray();
}
#endregion Serialize
#region Publish
/// <summary>
/// Perform incremental publish of all master -> web.
/// </summary>
/// <param name="targetDb">db name - eg "web", "web_cd" - default is "Web"</param>
public void PublishIncremental(string targetDb = WebDb)
{
if (string.IsNullOrEmpty(targetDb)) throw new ArgumentNullException("targetDb");
lock (LockAll)
{
Sitecore.Context.SetActiveSite("shell");
using (new SecurityDisabler())
{
Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase(MasterDb);
Sitecore.Data.Database target = Sitecore.Configuration.Factory.GetDatabase(targetDb);
Assert.IsNotNull(master, "Could not find master database");
Assert.IsNotNull(target, string.Format("Could not find '{0}' database", targetDb));
PublishManager.PublishIncremental(master, new[] { target },
LanguageManager.GetLanguages(master).ToArray());
}
}
}
#endregion
}
}
public partial class DeploymentController : Controller
{
private DeploymentManager _manager;
protected DeploymentManager Manager
{
get { return _manager ?? (_manager = new DeploymentManager()); }
}
public virtual ActionResult Delete()
{
Manager.Logger = new HtmlLogger();
Manager.DeleteAll();
ViewBag.LogInfo = Manager.Logger.ToString();
CheckForErrors();
return View();
}
public string DeleteCatalogues()
{
Manager.DeleteCatalogues();
return string.Format("Delete completed at {0}.", DateTime.Now.ToString("s"));
}
/// <summary>
/// Deserialize what already is there (manual unzip/web deploy etc)
/// </summary>
/// <returns></returns>
public virtual ActionResult DeserializeAll(bool cleanUp = false)
{
Manager.Logger = new HtmlLogger();
Manager.DeserializeAll();
if (cleanUp)
{
Manager.DeleteAll();
}
ViewBag.LogInfo = Manager.Logger.ToString();
CheckForErrors();
return View();
}
/// <summary>
/// Deserialize what already is there (manual unzip/web deploy etc), Force full update ignoring local changes
/// </summary>
/// <returns></returns>
public virtual ActionResult DeserializeAllForceUpdate()
{
Manager.Logger = new HtmlLogger();
Manager.Options = new LoadOptions {DisableEvents = true, ForceUpdate = true};
Manager.DeserializeAll();
ViewBag.LogInfo = Manager.Logger.ToString();
CheckForErrors();
return View();
}
/// <summary>
/// Present the form for uploading a file
/// </summary>
/// <returns></returns>
public virtual ActionResult DeserializeFile()
{
ViewBag.SerializationFolder = Manager.SerializationRootFolder;
CheckForErrors();
return View();
}
/// <summary>
/// Handle the uploaded file
/// </summary>
/// <param name="theFile"></param>
/// <returns></returns>
[HttpPost]
public virtual ActionResult DeserializeFile(HttpPostedFileBase theFile)
{
if (theFile == null || theFile.ContentLength == 0 || !theFile.ContentType.Contains("zip"))
{
return RedirectToAction("DeserializeFile");
}
var rootPath = Server.MapPath("~/temp/deploy/");
var upload = Path.Combine(rootPath, "content.zip");
try
{
if (!Directory.Exists(rootPath))
Directory.CreateDirectory(rootPath);
if (System.IO.File.Exists(upload))
System.IO.File.Delete(upload);
}
catch (Exception e)
{
Log.Error("Failed to remove previous uploaded file", e, this);
}
theFile.SaveAs(upload);
Manager.DeserializeFromZipFile(upload);
ViewBag.LogInfo = Manager.Logger.ToString();
CheckForErrors();
return View("DeserializeAll");
}
/// <summary>
/// Deserialize what already is there (manual unzip/web deploy etc)
/// </summary>
/// <returns></returns>
public string Publish()
{
Manager.Publish();
return string.Format("Publish completed at {0}.", DateTime.Now.ToString("s"));
}
public virtual ActionResult SerializeAll()
{
ViewBag.File = SerializeAndZip();
ViewBag.LogInfo = Manager.Logger.ToString();
return View("SerializeAll");
}
/// <summary>
/// Serializ(s)es all content and returns a zip file of it all.
/// </summary>
/// <returns></returns>
public virtual FileResult SerializeAllFile()
{
var file = SerializeAndZip();
ViewBag.File = file;
var cd = new ContentDisposition
{
FileName = Path.GetFileName(file),
Inline = false,
};
Response.AppendHeader("content-disposition", cd.ToString());
return File(System.IO.File.OpenRead(file), "application/zip");
}
/// <summary>
/// Deserialise and pubish site
/// </summary>
/// <returns></returns>
public virtual ActionResult Update()
{
Manager.Logger = new HtmlLogger();
Manager.DeserializeAll();
Manager.Publish();
Manager.Logger.Info("Smart Publish site content");
ViewBag.LogInfo = Manager.Logger.ToString();
return View();
}
private void CheckForErrors()
{
if (Manager.Logger.As<HtmlLogger>().ContainsErrors())
{
Response.StatusCode = 500;
}
}
private string SerializeAndZip()
{
Manager.Logger = new HtmlLogger();
Manager.SerializeAll();
return Manager.CreateZipFile();
}
}
以上是关于csharp Sitecore部署管理器的主要内容,如果未能解决你的问题,请参考以下文章