diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-12-03 10:29:17 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-12-03 10:29:17 +0200 |
| commit | 05c7e42a8ce55a21c94338febad593bfbf638655 (patch) | |
| tree | 5465475f3565da1b724f4cd9bfcc0eb3b67fd167 /Software/Visual_Studio | |
| parent | 3a70d596ada24ad6f92f729d564ab29c3e249f06 (diff) | |
| download | Tango-05c7e42a8ce55a21c94338febad593bfbf638655.tar.gz Tango-05c7e42a8ce55a21c94338febad593bfbf638655.zip | |
MERGE
Diffstat (limited to 'Software/Visual_Studio')
18 files changed, 691 insertions, 47 deletions
diff --git a/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix b/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix Binary files differnew file mode 100644 index 000000000..2a0b7a89a --- /dev/null +++ b/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix diff --git a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs index dd613ac5e..146dbbade 100644 --- a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs +++ b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs @@ -9,6 +9,10 @@ namespace Tango.Core.Helpers { public static class PathHelper { + /// <summary> + /// Creates a temporary folder in %temp%\Twine\{Random} and returns the path to that folder. + /// </summary> + /// <returns></returns> public static String GetTempFolderPath() { String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", Path.GetRandomFileName()); diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs new file mode 100644 index 000000000..54efa1062 --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs @@ -0,0 +1,188 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: SynchronizeDBRequest.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from SynchronizeDBRequest.proto</summary> + public static partial class SynchronizeDBRequestReflection { + + #region Descriptor + /// <summary>File descriptor for SynchronizeDBRequest.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static SynchronizeDBRequestReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChpTeW5jaHJvbml6ZURCUmVxdWVzdC5wcm90bxIZVGFuZ28uUE1SLlN5bmNo", + "cm9uaXphdGlvbiI9ChRTeW5jaHJvbml6ZURCUmVxdWVzdBIUCgxTZXJpYWxO", + "dW1iZXIYASABKAkSDwoHTG9jYWxEQhgCIAEoDEIlCiNjb20udHdpbmUudGFu", + "Z28ucG1yLnN5bmNocm9uaXphdGlvbmIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.SynchronizeDBRequest), global::Tango.PMR.Synchronization.SynchronizeDBRequest.Parser, new[]{ "SerialNumber", "LocalDB" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class SynchronizeDBRequest : pb::IMessage<SynchronizeDBRequest> { + private static readonly pb::MessageParser<SynchronizeDBRequest> _parser = new pb::MessageParser<SynchronizeDBRequest>(() => new SynchronizeDBRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<SynchronizeDBRequest> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.SynchronizeDBRequestReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBRequest(SynchronizeDBRequest other) : this() { + serialNumber_ = other.serialNumber_; + localDB_ = other.localDB_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBRequest Clone() { + return new SynchronizeDBRequest(this); + } + + /// <summary>Field number for the "SerialNumber" field.</summary> + public const int SerialNumberFieldNumber = 1; + private string serialNumber_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string SerialNumber { + get { return serialNumber_; } + set { + serialNumber_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "LocalDB" field.</summary> + public const int LocalDBFieldNumber = 2; + private pb::ByteString localDB_ = pb::ByteString.Empty; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pb::ByteString LocalDB { + get { return localDB_; } + set { + localDB_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as SynchronizeDBRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(SynchronizeDBRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (SerialNumber != other.SerialNumber) return false; + if (LocalDB != other.LocalDB) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (SerialNumber.Length != 0) hash ^= SerialNumber.GetHashCode(); + if (LocalDB.Length != 0) hash ^= LocalDB.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (SerialNumber.Length != 0) { + output.WriteRawTag(10); + output.WriteString(SerialNumber); + } + if (LocalDB.Length != 0) { + output.WriteRawTag(18); + output.WriteBytes(LocalDB); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (SerialNumber.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(SerialNumber); + } + if (LocalDB.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeBytesSize(LocalDB); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(SynchronizeDBRequest other) { + if (other == null) { + return; + } + if (other.SerialNumber.Length != 0) { + SerialNumber = other.SerialNumber; + } + if (other.LocalDB.Length != 0) { + LocalDB = other.LocalDB; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + SerialNumber = input.ReadString(); + break; + } + case 18: { + LocalDB = input.ReadBytes(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs new file mode 100644 index 000000000..e25a903b9 --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs @@ -0,0 +1,160 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: SynchronizeDBResponse.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from SynchronizeDBResponse.proto</summary> + public static partial class SynchronizeDBResponseReflection { + + #region Descriptor + /// <summary>File descriptor for SynchronizeDBResponse.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static SynchronizeDBResponseReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChtTeW5jaHJvbml6ZURCUmVzcG9uc2UucHJvdG8SGVRhbmdvLlBNUi5TeW5j", + "aHJvbml6YXRpb24iKQoVU3luY2hyb25pemVEQlJlc3BvbnNlEhAKCFJlbW90", + "ZURCGAEgASgMQiUKI2NvbS50d2luZS50YW5nby5wbXIuc3luY2hyb25pemF0", + "aW9uYgZwcm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.SynchronizeDBResponse), global::Tango.PMR.Synchronization.SynchronizeDBResponse.Parser, new[]{ "RemoteDB" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class SynchronizeDBResponse : pb::IMessage<SynchronizeDBResponse> { + private static readonly pb::MessageParser<SynchronizeDBResponse> _parser = new pb::MessageParser<SynchronizeDBResponse>(() => new SynchronizeDBResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<SynchronizeDBResponse> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.SynchronizeDBResponseReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBResponse() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBResponse(SynchronizeDBResponse other) : this() { + remoteDB_ = other.remoteDB_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public SynchronizeDBResponse Clone() { + return new SynchronizeDBResponse(this); + } + + /// <summary>Field number for the "RemoteDB" field.</summary> + public const int RemoteDBFieldNumber = 1; + private pb::ByteString remoteDB_ = pb::ByteString.Empty; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pb::ByteString RemoteDB { + get { return remoteDB_; } + set { + remoteDB_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as SynchronizeDBResponse); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(SynchronizeDBResponse other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (RemoteDB != other.RemoteDB) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (RemoteDB.Length != 0) hash ^= RemoteDB.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (RemoteDB.Length != 0) { + output.WriteRawTag(10); + output.WriteBytes(RemoteDB); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (RemoteDB.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeBytesSize(RemoteDB); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(SynchronizeDBResponse other) { + if (other == null) { + return; + } + if (other.RemoteDB.Length != 0) { + RemoteDB = other.RemoteDB; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + RemoteDB = input.ReadBytes(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj index 7fd2a734f..e58d76ef2 100644 --- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj +++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj @@ -59,6 +59,8 @@ <Compile Include="Stubs\CalculateResponse.cs" /> <Compile Include="Stubs\ProgressRequest.cs" /> <Compile Include="Stubs\ProgressResponse.cs" /> + <Compile Include="Synchronization\SynchronizeDBRequest.cs" /> + <Compile Include="Synchronization\SynchronizeDBResponse.cs" /> <Compile Include="TangoMessage.cs" /> </ItemGroup> <ItemGroup> diff --git a/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs new file mode 100644 index 000000000..ca58686f3 --- /dev/null +++ b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Synchronization.Local +{ + public class LocalDBSynchronizer + { + public static void Synchronize(String masterSQLiteFile, String slaveSQLiteFile) + { + using (LocalDBComparer comparer = new LocalDBComparer(new SQLiteDataBase(masterSQLiteFile), new SQLiteDataBase(slaveSQLiteFile))) + { + var diffs = comparer.Compare(); + foreach (var diff in diffs) + { + diff.Commit(); + } + } + } + + public static Task SynchronizeAsync(String masterSQLiteFile, String slaveSQLiteFile) + { + return Task.Factory.StartNew(() => Synchronize(masterSQLiteFile, slaveSQLiteFile)); + } + } +} diff --git a/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs b/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs index 83a14b493..b3d259e8c 100644 --- a/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs +++ b/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Threading; namespace Tango.Synchronization.Local { @@ -487,6 +488,24 @@ namespace Tango.Synchronization.Local public void Dispose() { _connection.Close(); + _connection.Dispose(); + GC.Collect(); + + while (true) + { + try + { + using (FileStream stream = File.Open(Source, FileMode.Open, FileAccess.Read)) + { + return; + } + } + catch (IOException) + { + GC.Collect(); + Thread.Sleep(200); + } + } } } } diff --git a/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs b/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs new file mode 100644 index 000000000..2cd9e2d41 --- /dev/null +++ b/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using remote = Tango.DAL.Remote.DB; +using local = Tango.DAL.Local.DB; + +namespace Tango.Synchronization.Remote +{ + public class RemoteDBSynchronizer + { + public static void Synchronize(String sqliteDbFile, String serialNumber) + { + using (var remoteDB = new remote.RemoteDB("LOCALHOST\\SQLEXPRESS", false)) + { + using (var localDB = new local.LocalDB(sqliteDbFile)) + { + RemoteDBComparer comparer = new RemoteDBComparer(remoteDB, localDB, serialNumber); + var diffs = comparer.Compare(); + + foreach (var diff in diffs) + { + diff.Commit(); + } + + remoteDB.SaveChanges(); + localDB.SaveChanges(); + } + } + } + + public static Task SynchronizeAsync(String sqliteDBFile, String serialNumber) + { + return Task.Factory.StartNew(() => + { + Synchronize(sqliteDBFile, serialNumber); + }); + } + } +} diff --git a/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj b/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj index 36719516a..30208539c 100644 --- a/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj +++ b/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj @@ -69,12 +69,14 @@ <Compile Include="Local\Constants.cs" /> <Compile Include="Local\ExtensionMethods.cs" /> <Compile Include="Local\ILocalDataBase.cs" /> + <Compile Include="Local\LocalDBSynchronizer.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Local\LocalDBComparer.cs" /> <Compile Include="Diff.cs" /> <Compile Include="DiffAction.cs" /> <Compile Include="Local\SQLiteDataBase.cs" /> <Compile Include="Remote\RemoteDBComparer.cs" /> + <Compile Include="Remote\RemoteDBSynchronizer.cs" /> <Compile Include="SyncConfiguration.cs" /> </ItemGroup> <ItemGroup> diff --git a/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs index a5b29b413..26d197bcf 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs @@ -19,22 +19,7 @@ namespace Tango.UnitTesting { var console = Helper.InitializeLogging(true); - using (var remoteDB = new remote.RemoteDB("LOCALHOST\\SQLEXPRESS", false)) - { - using (var localDB = new local.LocalDB(Helper.GetSQLiteFilePath())) - { - RemoteDBComparer comparer = new RemoteDBComparer(remoteDB, localDB, "1234"); - var diffs = comparer.Compare(); - - foreach (var diff in diffs) - { - diff.Commit(); - } - - remoteDB.SaveChanges(); - localDB.SaveChanges(); - } - } + RemoteDBSynchronizer.Synchronize(Helper.GetSQLiteFilePath(), "1234"); console.WaitForConsoleExit().Wait(); } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db b/Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db Binary files differnew file mode 100644 index 000000000..293ca63e0 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db diff --git a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs index 3cc7ae3c9..15f0e7afc 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs @@ -19,6 +19,8 @@ namespace Tango.MachineService routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); + + config.Formatters.Insert(0, new ProtoBufFormatter()); } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs new file mode 100644 index 000000000..fd87815c9 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs @@ -0,0 +1,47 @@ +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Web.Hosting; +using System.Web.Http; +using Tango.Core.Helpers; +using Tango.PMR.Stubs; +using Tango.PMR.Synchronization; +using Tango.Synchronization.Local; +using Tango.Synchronization.Remote; + +namespace Tango.MachineService.Controllers +{ + public class SynchronizationController : ApiController + { + [HttpPost] + public SynchronizeDBResponse Synchronize(SynchronizeDBRequest request) + { + String tempFolder = PathHelper.GetTempFolderPath(); + + String masterSQLiteFile = Path.Combine(tempFolder, "Remote.db"); + String slaveSQLiteFile = Path.Combine(tempFolder, "Local.db"); + + File.WriteAllBytes(slaveSQLiteFile, request.LocalDB.ToByteArray()); + + + + File.Copy(HostingEnvironment.MapPath(@"~/App_Data/Tango.db"), masterSQLiteFile); + + RemoteDBSynchronizer.Synchronize(masterSQLiteFile, request.SerialNumber); + + LocalDBSynchronizer.Synchronize(masterSQLiteFile, slaveSQLiteFile); + + SynchronizeDBResponse response = new SynchronizeDBResponse(); + response.RemoteDB = ByteString.CopyFrom(File.ReadAllBytes(slaveSQLiteFile)); + + PathHelper.TryDeleteFolder(tempFolder); + + return response; + } + } +} diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs b/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs index a96c7016e..ca2e5f00a 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using System.Web.Hosting; using System.Web.Http; +using System.Web.Http.Filters; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; @@ -11,11 +13,32 @@ namespace Tango.MachineService { public class WebApiApplication : System.Web.HttpApplication { + //Create filter + public class LogExceptionFilterAttribute : ExceptionFilterAttribute + { + public override void OnException(HttpActionExecutedContext context) + { + ErrorLogService.LogError(context.Exception); + } + } + protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); + + //register your filter with Web API pipeline + GlobalConfiguration.Configuration.Filters.Add(new LogExceptionFilterAttribute()); + } + + //common service to be used for logging errors + public static class ErrorLogService + { + public static void LogError(Exception ex) + { + //Email developers, call fire department, log to database etc. + } } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs b/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs new file mode 100644 index 000000000..1edf01acf --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs @@ -0,0 +1,72 @@ +using Google.Protobuf; +using System; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Tango.PMR.Stubs; + +namespace Tango.MachineService +{ + public class ProtoBufFormatter : MediaTypeFormatter + { + private static readonly MediaTypeHeaderValue mediaType = new MediaTypeHeaderValue("application/x-protobuf"); + + public ProtoBufFormatter() + { + SupportedMediaTypes.Add(mediaType); + } + + public static MediaTypeHeaderValue DefaultMediaType + { + get { return mediaType; } + } + + public override bool CanReadType(Type type) + { + return true; + } + + public override bool CanWriteType(Type type) + { + return true; + } + + public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger) + { + var tcs = new TaskCompletionSource<object>(); + + try + { + MessageParser parser = type.GetProperty("Parser").GetValue(null, null) as MessageParser; + IMessage req = parser.ParseFrom(stream); + tcs.SetResult(req); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + + return tcs.Task; + } + + public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext) + { + var tcs = new TaskCompletionSource<object>(); + + try + { + (value as IMessage).WriteTo(stream); + tcs.SetResult(null); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + + return tcs.Task; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj index 698254b62..4875386c6 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -46,6 +46,15 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> + <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll</HintPath> + </Reference> + <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll</HintPath> + </Reference> + <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> <Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath> </Reference> @@ -53,6 +62,17 @@ <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Data.SQLite, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.Core.1.0.106.0\lib\net46\System.Data.SQLite.dll</HintPath> + </Reference> + <Reference Include="System.Data.SQLite.EF6, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.EF6.1.0.106.0\lib\net46\System.Data.SQLite.EF6.dll</HintPath> + <Private>True</Private> + </Reference> + <Reference Include="System.Data.SQLite.Linq, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.106.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath> + <Private>True</Private> + </Reference> <Reference Include="System.Drawing" /> <Reference Include="System.Web.DynamicData" /> <Reference Include="System.Web.Entity" /> @@ -148,9 +168,11 @@ <ItemGroup> <Compile Include="App_Start\BundleConfig.cs" /> <Compile Include="App_Start\FilterConfig.cs" /> + <Compile Include="ProtoBufFormatter.cs" /> <Compile Include="App_Start\RouteConfig.cs" /> <Compile Include="App_Start\WebApiConfig.cs" /> <Compile Include="Controllers\HomeController.cs" /> + <Compile Include="Controllers\SynchronizationController.cs" /> <Compile Include="Controllers\ValuesController.cs" /> <Compile Include="Global.asax.cs"> <DependentUpon>Global.asax</DependentUpon> @@ -172,10 +194,27 @@ </Content> </ItemGroup> <ItemGroup> - <Folder Include="App_Data\" /> + <Content Include="packages.config" /> </ItemGroup> <ItemGroup> - <Content Include="packages.config" /> + <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> + <ProjectReference Include="..\..\Tango.Synchronization\Tango.Synchronization.csproj"> + <Project>{7ada4e86-cad7-4968-a210-3a8a9e5153ab}</Project> + <Name>Tango.Synchronization</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Content Include="..\..\..\DB\Tango.db"> + <Link>App_Data\Tango.db</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> </ItemGroup> <PropertyGroup> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> @@ -211,7 +250,12 @@ </PropertyGroup> <Error Condition="!Exists('..\..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props'))" /> <Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" /> + <Error Condition="!Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets'))" /> </Target> + <Import Project="..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" /> + <PropertyGroup> + <PreBuildEvent>copy /Y "$(SolutionDir)..\DB\Tango.db" "$(ProjectDir)App_Data\Tango.db"</PreBuildEvent> + </PropertyGroup> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config index dea42c025..53a9de5fd 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config +++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config @@ -1,14 +1,18 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit https://go.microsoft.com/fwlink/?LinkId=301879 --> <configuration> + <configSections> + <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> + <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> + </configSections> <appSettings> - <add key="webpages:Version" value="3.0.0.0"/> - <add key="webpages:Enabled" value="false"/> - <add key="ClientValidationEnabled" value="true"/> - <add key="UnobtrusiveJavaScriptEnabled" value="true"/> + <add key="webpages:Version" value="3.0.0.0" /> + <add key="webpages:Enabled" value="false" /> + <add key="ClientValidationEnabled" value="true" /> + <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <!-- For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367. @@ -19,57 +23,74 @@ </system.Web> --> <system.web> - <compilation debug="true" targetFramework="4.6"/> - <httpRuntime targetFramework="4.5"/> + <compilation debug="true" targetFramework="4.6" /> + <httpRuntime targetFramework="4.5" /> <httpModules> - <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/> + <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" /> </httpModules> </system.web> <system.webServer> <handlers> - <remove name="ExtensionlessUrlHandler-Integrated-4.0"/> - <remove name="OPTIONSVerbHandler"/> - <remove name="TRACEVerbHandler"/> - <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> + <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> + <remove name="OPTIONSVerbHandler" /> + <remove name="TRACEVerbHandler" /> + <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> - <validation validateIntegratedModeConfiguration="false"/> + <validation validateIntegratedModeConfiguration="false" /> <modules> - <remove name="ApplicationInsightsWebTracking"/> - <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/> + <remove name="ApplicationInsightsWebTracking" /> + <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" /> </modules> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> - <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/> - <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/> + <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" /> + <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/> - <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/> + <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/> - <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234"/> + <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/> - <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> + <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/> - <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> + <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/> - <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0"/> + <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" /> </dependentAssembly> </assemblyBinding> </runtime> <system.codedom> <compilers> - <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/> - <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/> + <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" /> + <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" /> </compilers> </system.codedom> + <entityFramework> + <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> + <providers> + <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> + <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> + </providers> + </entityFramework> + <system.data> + <DbProviderFactories> + <remove invariant="System.Data.SQLite.EF6" /> + <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> + <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories> + </system.data> </configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/packages.config b/Software/Visual_Studio/Web/Tango.MachineService/packages.config index d842d5f8e..e73c5452b 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/packages.config +++ b/Software/Visual_Studio/Web/Tango.MachineService/packages.config @@ -1,6 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <packages> <package id="Antlr" version="3.4.1.9004" targetFramework="net45" /> + <package id="EntityFramework" version="6.0.0" targetFramework="net46" /> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" /> <package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net45" requireReinstallation="true" /> <package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.0.6" targetFramework="net45" /> <package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.2.0" targetFramework="net45" /> @@ -23,5 +25,9 @@ <package id="Modernizr" version="2.6.2" targetFramework="net45" /> <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" /> <package id="Respond" version="1.2.0" targetFramework="net45" /> + <package id="System.Data.SQLite" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.Core" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.EF6" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.Linq" version="1.0.106.0" targetFramework="net46" /> <package id="WebGrease" version="1.5.2" targetFramework="net45" /> </packages>
\ No newline at end of file |
