using Google.Protobuf; using Microsoft.Azure; using Microsoft.Azure.Management.Sql; using Microsoft.SqlServer.Management.Smo; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Authentication; using System.Threading.Tasks; using System.Web.Hosting; using System.Web.Http; using Tango.BL; using Tango.BL.Builders; using Tango.BL.Entities; using Tango.Core.DB; using Tango.Core.Helpers; using Tango.Core.IO; using Tango.Logging; using Tango.MachineService.Helpers; using Tango.MachineService.Models; using Tango.MachineService.SMO; using Tango.PMR.Stubs; using Tango.PMR.Synchronization; using Tango.Synchronization.Local; using Tango.Synchronization.Remote; namespace Tango.MachineService.Controllers { public class SynchronizationController : ProtoController { ///// ///// Expects a DB synchronization request from a remote machine and returns the synchronized version of the machine database. ///// ///// The request. ///// //[HttpPost] //public SynchronizeDBResponse Synchronize(SynchronizeDBRequest request) //{ // var tempFolder = TemporaryManager.Default.CreateFolder(); // try // { // //File path for the reflected remote data base SQLite. // String masterSQLiteFile = Path.Combine(tempFolder, "Remote.db"); // //File path for the received machine SQLite db. // String slaveSQLiteFile = Path.Combine(tempFolder, "Local.db"); // //Save the machine db to file. // File.WriteAllBytes(slaveSQLiteFile, request.LocalDB.ToByteArray()); // //Copy an SQLite db template. // File.Copy(HostingEnvironment.MapPath(@"~/App_Data/Tango.db"), masterSQLiteFile); // //Synchronize the SQL Server db with the new SQLite template. (Overwrite basically) // RemoteDBSynchronizer.Synchronize(masterSQLiteFile, request.SerialNumber, true); // //Synchronize the received machine db with the filled template. // LocalDBSynchronizer.Synchronize(masterSQLiteFile, slaveSQLiteFile); // //Send the synchronized machine db to the machine to the machine. // SynchronizeDBResponse response = new SynchronizeDBResponse(); // response.RemoteDB = ByteString.CopyFrom(File.ReadAllBytes(slaveSQLiteFile)); // return response; // } // catch (Exception) // { // throw; // } // finally // { // //Remove all temporary files and folder. // tempFolder.Delete(); // } //} [HttpPost] public MachineSetupResponse MachineSetup(MachineSetupRequest request) { MachineSetupResponse response = new MachineSetupResponse(); LogManager.Log("Setup request received: " + request.ToString()); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.Configuration.LazyLoadingEnabled = false; String serial_number = request.SerialNumber; var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number); if (machine == null) { throw new AuthenticationException("The specified serial number could not be found."); } var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; var client = StorageHelper.GetStorageBlobClient(); var container = StorageHelper.GetTangoVersionsContainer(client); var blob = container.GetBlockBlobReference(latest_machine_version.BlobName); response.BlobAddress = StorageHelper.GenerateBlobReadSignature(blob, TimeSpan.FromMinutes(60)); DbCredentials credentials = new DbCredentials(); using (SmoManager manager = new SmoManager()) { credentials = manager.CreateRandomLoginAndUser(); Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) => { using (SmoManager m = new SmoManager()) { m.DeleteLoginAndUser(credentials.UserName); } }); } response.DbAddress = Config.DB_ADDRESS; response.DbUserName = credentials.UserName; response.DbPassword = credentials.Password; } return response; } [HttpPost] public DownloadUpdateResponse MachineUpdate(DownloadUpdateRequest request) { DownloadUpdateResponse response = new DownloadUpdateResponse(); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.Configuration.LazyLoadingEnabled = false; String serial_number = request.SerialNumber; var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number); if (machine == null) { throw new AuthenticationException("The specified serial number could not be found."); } var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; var client = StorageHelper.GetStorageBlobClient(); var container = StorageHelper.GetTangoVersionsContainer(client); var blob = container.GetBlockBlobReference(latest_machine_version.BlobName); response.BlobAddress = StorageHelper.GenerateBlobReadSignature(blob, TimeSpan.FromMinutes(60)); DbCredentials credentials = new DbCredentials(); using (SmoManager manager = new SmoManager()) { credentials = manager.CreateRandomLoginAndUser(); Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) => { using (SmoManager m = new SmoManager()) { m.DeleteLoginAndUser(credentials.UserName); } }); } response.DbAddress = Config.DB_ADDRESS; response.DbUserName = credentials.UserName; response.DbPassword = credentials.Password; } return response; } [HttpPost] public CheckForUpdateResponse CheckForUpdate(CheckForUpdateRequest request) { CheckForUpdateResponse response = new CheckForUpdateResponse(); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.Configuration.LazyLoadingEnabled = false; var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber); if (machine == null) { throw new AuthenticationException("The specified serial number could not be found."); } var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); if (Version.Parse(latest_machine_version.Version) > Version.Parse(request.Version)) { response.IsUpdateAvailable = true; } response.Version = latest_machine_version.Version; } return response; } [HttpPost] public UpdateDBResponse UpdateDB(UpdateDBRequest request) { UpdateDBResponse response = new UpdateDBResponse(); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.Configuration.LazyLoadingEnabled = false; String serial_number = request.SerialNumber; var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number); if (machine == null) { throw new AuthenticationException("The specified serial number could not be found."); } DbCredentials credentials = new DbCredentials(); using (SmoManager manager = new SmoManager()) { credentials = manager.CreateRandomLoginAndUser(); Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) => { using (SmoManager m = new SmoManager()) { m.DeleteLoginAndUser(credentials.UserName); } }); } response.DbAddress = Config.DB_ADDRESS; response.DbUserName = credentials.UserName; response.DbPassword = credentials.Password; } return response; } [HttpPost] public Machine PersonTest(Person p) { using (var db = ObservablesContextHelper.CreateContext()) { var machine = new MachineBuilder(db) .Set(x => x.SerialNumber == "1111") .WithOrganization() .WithConfiguration().Build(); return machine; } } } }