aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj17
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs285
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs16
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs14
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs21
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config1
7 files changed, 362 insertions, 1 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index 7c0851d01..3ce667afe 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -59,6 +59,9 @@
<HintPath>..\..\Referenced Assemblies\SMO\Microsoft.SqlServer.AzureStorageEnum.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
@@ -83,6 +86,9 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="..\..\PPC\Tango.PPC.Common\Publish\PublishInfo.cs">
+ <Link>Tup\PublishInfo.cs</Link>
+ </Compile>
<Compile Include="..\..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
@@ -95,6 +101,10 @@
<Compile Include="Converters\UserRoleToVisibilityConverter.cs" />
<Compile Include="MachineStudioTheme.cs" />
<Compile Include="Resources\SharedResourceDictionary.cs" />
+ <Compile Include="Tup\TupFileBuilder.cs" />
+ <Compile Include="Tup\TupFileBuilderProgressEventArgs.cs" />
+ <Compile Include="Web\DownloadLatestPPCVersionRequest.cs" />
+ <Compile Include="Web\DownloadLatestPPCVersionResponse.cs" />
<Compile Include="Web\LoginRequest.cs" />
<Compile Include="Web\LoginResponse.cs" />
<Compile Include="AutoComplete\MachinesProvider.cs" />
@@ -291,6 +301,10 @@
<Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
<Name>Tango.SharedUI</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.SQLExaminer\Tango.SQLExaminer.csproj">
+ <Project>{e1e66ed9-597d-45fa-8048-de90a6930484}</Project>
+ <Name>Tango.SQLExaminer</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
<Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
<Name>Tango.Transport</Name>
@@ -387,10 +401,11 @@
<ItemGroup>
<Resource Include="Images\ti-tm4c129x.png" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs
new file mode 100644
index 000000000..6dd8b82f7
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs
@@ -0,0 +1,285 @@
+using Ionic.Zip;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.BL;
+using Tango.Core;
+using Tango.Core.DB;
+using Tango.Core.DI;
+using Tango.MachineStudio.Common.Web;
+using Tango.SQLExaminer;
+using Tango.Transport.Web;
+using Tango.Core.ExtensionMethods;
+using Tango.PPC.Common.Publish;
+using Tango.Settings;
+using Tango.Core.Components;
+using System.Text.RegularExpressions;
+
+namespace Tango.MachineStudio.Common.Tup
+{
+ public class TupFileBuilder : ExtendedObject
+ {
+ public event EventHandler<TupFileBuilderProgressEventArgs> Progress;
+
+ public Task Build(String serialNumber, String filePath)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ String tempDbName = "Tango_TUP";
+ var tempPackageFolder = TemporaryManager.CreateFolder();
+ String tempBackupFolder = "C:\\MachineStudioTUP";
+ String tempBackupFile = Path.Combine(tempBackupFolder, tempDbName + ".bak");
+ var tempZipFile = TemporaryManager.CreateImaginaryFile();
+ DbManager dbManager = null;
+
+ LogManager.Log("Generating tup file...");
+ LogManager.Log($"Tup file: '{filePath}.'");
+ LogManager.Log($"Temporary db name: '{tempDbName}'.");
+ LogManager.Log($"Temporary package folder: '{tempPackageFolder}'.");
+ LogManager.Log($"Temporary db backup folder: '{tempBackupFolder}'.");
+ LogManager.Log($"Temporary db backup file: '{tempBackupFile}'.");
+ LogManager.Log($"Temporary zip file: '{tempZipFile}'.");
+
+ try
+ {
+ LogManager.Log("Initializing...");
+
+ OnProgress("Initializing...");
+
+ Core.DataSource localDataSource = new Core.DataSource()
+ {
+ Address = "localhost\\SQLEXPRESS",
+ IntegratedSecurity = true,
+ Type = DataSourceType.SQLServer,
+ Catalog = null,
+ };
+
+ try
+ {
+ LogManager.Log($"Trying to connect via SQLEXPRESS:\n{localDataSource.ToJsonString()}");
+ dbManager = DbManager.FromDataSource(localDataSource);
+ }
+ catch (Exception ex)
+ {
+ try
+ {
+ LogManager.Log(ex, "Could not connect using SQLEXPRESS. Trying local DB...");
+
+ CmdCommand command = new CmdCommand("sqllocaldb", "info \"MSSQLLocalDB\"");
+ var result = command.Run().Result;
+
+ String pattern = "np:.+";
+ Regex reg = new Regex(pattern);
+ var match = reg.Match(result.StandardOutput);
+ String address = match.ToString();
+ if (address.Contains("np:"))
+ {
+ localDataSource.Address = address;
+ address = address.Trim().Replace("\r", "");
+ }
+ else
+ {
+ throw new ArgumentException("Could not parse LocalDB address string.");
+ }
+
+ LogManager.Log($"Trying to connect via LocalDB:\n{localDataSource.ToJsonString()}");
+ dbManager = DbManager.FromDataSource(localDataSource);
+ }
+ catch (Exception x)
+ {
+ LogManager.Log(x, "Could not find any database service for this operation.");
+ throw x;
+ }
+ }
+
+
+
+ OnProgress("Downloading latest PPC version...");
+
+ LogManager.Log("Connecting to machine service...");
+ MachineStudioWebClient client = TangoIOC.Default.GetInstance<MachineStudioWebClient>();
+
+ LogManager.Log("Requesting latest PPC version from machine service...");
+ var response = client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber }).Result;
+
+ LogManager.Log($"Machine service response:\n{response.ToJsonString()}");
+
+ var remoteDataSource = response.DataSource;
+
+ using (AutoFileDownloader downloader = new AutoFileDownloader(response.BlobAddress, response.CdnAddress, tempZipFile))
+ {
+ downloader.Progress += (x, e) =>
+ {
+ OnProgress($"Downloading latest PPC version '{response.Version}'...", false, e.Current, e.Total);
+ };
+
+ downloader.ResolveMode().GetAwaiter().GetResult();
+
+ LogManager.Log($"Downloading latest PPC version from: '{downloader.Address}'");
+
+ downloader.Download().Wait();
+ }
+
+ LogManager.Log("Extracting PPC version package...");
+
+ OnProgress("Extracting PPC package...");
+
+ using (ZipFile zip = new ZipFile(tempZipFile))
+ {
+ int currentEntry = 0;
+
+ zip.ExtractProgress += (x, args) =>
+ {
+ if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry)
+ {
+ OnProgress("Extracting PPC package...", false, currentEntry++, zip.Entries.Count);
+ }
+ };
+
+ zip.ExtractAll(tempPackageFolder);
+ }
+
+ OnProgress("Extracting version information...");
+ LogManager.Log("Extracting publish information...");
+ PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(tempPackageFolder, "version.json")));
+ LogManager.Log($"Publish Information:\n{publishInfo}");
+
+ LogManager.Log("Modifying publish information to custom tup file...");
+ publishInfo.IsMachineTupPackage = true;
+ publishInfo.MachineSerialNumber = serialNumber;
+ publishInfo.MachineDeploymentSlot = SettingsManager.Default.GetOrCreate<MachineStudioSettings>().DeploymentSlot;
+
+ OnProgress("Creating temporary database...");
+
+ LogManager.Log($"Creating temporary db backup directory '{tempBackupFolder}'");
+
+ Directory.CreateDirectory(tempBackupFolder);
+
+ LogManager.Log($"Creating new database: '{tempDbName}'");
+
+ //Create temp db
+ dbManager.Create(tempDbName, Path.Combine(tempBackupFolder, tempDbName + ".mdf"));
+
+ OnProgress("Generating database snapshot...");
+
+ LogManager.Log("Starting database synchronization...");
+
+ Thread.Sleep(2000);
+
+ localDataSource.Catalog = tempDbName;
+
+ ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner(
+ Path.Combine(tempPackageFolder, "Provision Scripts", "config.xml"),
+ Path.Combine(tempPackageFolder, "Provision Scripts"),
+ remoteDataSource,
+ localDataSource,
+ serialNumber);
+
+ runner.ScriptExecuting += (x, item) =>
+ {
+ LogManager.Log($"Executing script '{item.FileName}'...");
+ OnProgress($"{item.Name}...");
+ };
+
+ runner.Log += (x, log) =>
+ {
+ LogManager.Log(log);
+ };
+
+ runner.Run().GetAwaiter().GetResult();
+
+ OnProgress("Generating database snapshot...");
+
+ if (File.Exists(tempBackupFile))
+ {
+ LogManager.Log($"Deleting file '{tempBackupFile}'");
+ File.Delete(tempBackupFile);
+ }
+
+ LogManager.Log($"Generating backup for '{tempDbName}' to '{tempBackupFile}'...");
+
+ dbManager.Backup(tempDbName, tempBackupFile);
+
+ OnProgress("Injecting database snapshot to PPC package...");
+
+ using (ZipFile zip = new ZipFile(tempZipFile))
+ {
+ LogManager.Log($"Injecting file '{tempBackupFile}' to original package at '{tempZipFile}'...");
+ zip.AddFile(tempBackupFile, "/");
+
+ LogManager.Log($"Injecting modified publish information...");
+ zip.UpdateEntry("version.json", publishInfo.ToJson());
+
+ zip.Save();
+ }
+
+ LogManager.Log($"Copying '{tempZipFile}' to '{filePath}'...");
+
+ File.Copy(tempZipFile, filePath, true);
+
+ OnProgress("Completed", false, 100, 100);
+
+ LogManager.Log("TUP file generation completed successfully.");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "TUP file generation failed.");
+ OnProgress("Failed", false, 0, 100);
+ throw ex;
+ }
+ finally
+ {
+ LogManager.Log($"Removing '{tempZipFile}'.");
+ tempZipFile.Delete();
+ LogManager.Log($"Removing '{tempPackageFolder}'.");
+ tempPackageFolder.Delete();
+
+ try
+ {
+ LogManager.Log($"Removing database '{tempDbName}'.");
+ dbManager.SetOffline(tempDbName);
+ dbManager.SetOnline(tempDbName);
+ dbManager.Delete(tempDbName);
+ dbManager.Dispose();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error removing temp database '{tempDbName}'.");
+ }
+
+ try
+ {
+ LogManager.Log($"Removing '{tempBackupFolder}'.");
+ Directory.Delete(tempBackupFolder, true);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error removing folder '{tempBackupFolder}'.");
+ }
+ }
+ });
+ }
+
+ public async Task<String> GetLatestPPCVersion(String serialNumber)
+ {
+ MachineStudioWebClient client = TangoIOC.Default.GetInstance<MachineStudioWebClient>();
+ var response = await client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber });
+ return response.Version;
+ }
+
+ private void OnProgress(String message, bool isIntermediate = true, double progress = 0, double total = 100)
+ {
+ Progress?.Invoke(this, new TupFileBuilderProgressEventArgs()
+ {
+ Message = message,
+ IsIntermediate = isIntermediate,
+ Progress = progress,
+ Total = total,
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs
new file mode 100644
index 000000000..ada69dd40
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.Tup
+{
+ public class TupFileBuilderProgressEventArgs
+ {
+ public double Progress { get; set; }
+ public double Total { get; set; }
+ public bool IsIntermediate { get; set; }
+ public String Message { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs
new file mode 100644
index 000000000..24d465e69
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport.Web;
+
+namespace Tango.MachineStudio.Common.Web
+{
+ public class DownloadLatestPPCVersionRequest : WebRequestMessage
+ {
+ public String SerialNumber { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs
new file mode 100644
index 000000000..2cc6b731a
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Transport.Web;
+
+namespace Tango.MachineStudio.Common.Web
+{
+ public class DownloadLatestPPCVersionResponse : WebResponseMessage
+ {
+ public String Version { get; set; }
+
+ public String BlobAddress { get; set; }
+
+ public String CdnAddress { get; set; }
+
+ public DataSource DataSource { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
index 131f89515..c2d0dd3e6 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
@@ -94,5 +94,14 @@ namespace Tango.MachineStudio.Common.Web
return Post<Tango.MachineStudio.Common.Web.RefreshTokenRequest, Tango.MachineStudio.Common.Web.RefreshTokenResponse>("RefreshToken", request);
}
+ /// <summary>
+ /// Executes the DownloadLatestPPCVersion action and returns Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse.
+ /// </summary>
+ /// <returns></returns>
+ public Task<Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse> DownloadLatestPPCVersion(Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionRequest request)
+ {
+ return Post<Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionRequest, Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse>("DownloadLatestPPCVersion", request);
+ }
+
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
index f871776f5..6fd5091a8 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
@@ -9,4 +9,5 @@
<package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />
<package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />
<package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
</packages> \ No newline at end of file