using System; using System.Collections.Generic; using System.IO; using System.Linq; using Umbraco.Core; using Umbraco.Core.Collections; using Umbraco.Core.Hosting; using Umbraco.Core.Serialization; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install { /// /// An internal in-memory status tracker for the current installation /// public class InstallStatusTracker { private readonly IHostingEnvironment _hostingEnvironment; private readonly IJsonSerializer _jsonSerializer; public InstallStatusTracker(IHostingEnvironment hostingEnvironment, IJsonSerializer jsonSerializer) { _hostingEnvironment = hostingEnvironment; _jsonSerializer = jsonSerializer; } private static ConcurrentHashSet _steps = new ConcurrentHashSet(); private string GetFile(Guid installId) { var file = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/" + "install_" + installId.ToString("N") + ".txt"); return file; } public void Reset() { _steps = new ConcurrentHashSet(); ClearFiles(); } public void ClearFiles() { var dir = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/"); if (Directory.Exists(dir)) { var files = Directory.GetFiles(dir); foreach (var f in files) { File.Delete(f); } } else { Directory.CreateDirectory(dir); } } public IEnumerable InitializeFromFile(Guid installId) { //check if we have our persisted file and read it var file = GetFile(installId); if (File.Exists(file)) { var deserialized = _jsonSerializer.Deserialize>( File.ReadAllText(file)); foreach (var item in deserialized) { _steps.Add(item); } } else { throw new InvalidOperationException("Cannot initialize from file, the installation file with id " + installId + " does not exist"); } return new List(_steps); } public IEnumerable Initialize(Guid installId, IEnumerable steps) { //if there are no steps in memory if (_steps.Count == 0) { //check if we have our persisted file and read it var file = GetFile(installId); if (File.Exists(file)) { var deserialized = _jsonSerializer.Deserialize>( File.ReadAllText(file)); foreach (var item in deserialized) { _steps.Add(item); } } else { ClearFiles(); //otherwise just create the steps in memory (brand new install) foreach (var step in steps.OrderBy(x => x.ServerOrder)) { _steps.Add(new InstallTrackingItem(step.Name, step.ServerOrder)); } //save the file var serialized = _jsonSerializer.Serialize(new List(_steps)); Directory.CreateDirectory(Path.GetDirectoryName(file)); File.WriteAllText(file, serialized); } } else { //ensure that the file exists with the current install id var file = GetFile(installId); if (File.Exists(file) == false) { ClearFiles(); //save the correct file var serialized = _jsonSerializer.Serialize(new List(_steps)); Directory.CreateDirectory(Path.GetDirectoryName(file)); File.WriteAllText(file, serialized); } } return new List(_steps); } public void SetComplete(Guid installId, string name, IDictionary additionalData = null) { var trackingItem = _steps.Single(x => x.Name == name); if (additionalData != null) { trackingItem.AdditionalData = additionalData; } trackingItem.IsComplete = true; //save the file var file = GetFile(installId); var serialized = _jsonSerializer.Serialize(new List(_steps)); File.WriteAllText(file, serialized); } public static IEnumerable GetStatus() { return new List(_steps).OrderBy(x => x.ServerOrder); } } }