From 50b5a229c4fe547a896539f24c96e5e9a86ebb80 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 20 Oct 2020 20:58:32 +0300 Subject: DATA STORE ! --- .../Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj') diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index 09799c0ed..218652c1b 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -138,6 +138,7 @@ + @@ -212,6 +213,14 @@ {38197109-8610-4d3f-92b9-16d48df94d7c} Tango.DAL.Remote + + {fa96bc0c-4055-475c-9dcc-70a5a9436b10} + Tango.DataStore.Lite + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + {ca87a608-7b17-4c98-88f2-42abee10f4c1} Tango.Documents @@ -306,7 +315,7 @@ - + \ No newline at end of file -- cgit v1.3.1 From e8cec64cf5c35b17fed6a1f8f4ea0665d4ddf39b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 21 Oct 2020 04:06:23 +0300 Subject: DataStore EF ! --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../DataStore/RemoteDataStoreCollection.cs | 38 ++++++- .../DataStore/DefaultDataStoreService.cs | 3 +- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 6 +- .../Web/DownloadMachineDataRequest.cs | 2 + .../Web/DownloadMachineDataResponse.cs | 2 + .../NotifyMachineDataDownloadCompletedRequest.cs | 2 + .../Web/UploadMachineDataRequest.cs | 2 + .../Web/UploadMachineDataResponse.cs | 3 + .../Tango.DataStore.EF/EFDataStoreCollection.cs | 117 +++++++++++++++++++++ .../Tango.DataStore.EF/EFDataStoreHelper.cs | 80 ++++++++++++++ .../Tango.DataStore.EF/EFDataStoreItem.cs | 28 +++++ .../Tango.DataStore.EF/EFDataStoreManager.cs | 33 ++++++ .../Tango.DataStore.EF/ExtensionMethods.cs | 22 ++++ .../Tango.DataStore.EF/Properties/AssemblyInfo.cs | 7 ++ .../Tango.DataStore.EF/Tango.DataStore.EF.csproj | 82 +++++++++++++++ .../Tango.DataStore.EF/packages.config | 5 + .../LiteDBDataStoreCollection.cs | 8 +- .../Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs | 7 ++ .../Tango.DataStore/IDataStoreCollection.cs | 5 + .../Tango.DataStore/IDataStoreItem.cs | 10 ++ .../Tango.Emulations/Emulators/MachineEmulator.cs | 12 +-- .../Tango.UnitTesting/Tango.UnitTesting.csproj | 6 +- Software/Visual_Studio/Tango.sln | 34 ++++-- .../Controllers/PPCController.cs | 89 +++++++++++++--- .../Properties/AssemblyInfo.cs | 2 +- 29 files changed, 567 insertions(+), 38 deletions(-) create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/packages.config (limited to 'Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 04e72ca45..77b6f4120 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index e8aac16f8..4cfc85ea4 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 47b8e26d2..4e178ad92 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 88b1f2c1d..6e0fefa06 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs index 323a1b550..b7325cd48 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs @@ -60,27 +60,55 @@ namespace Tango.FSE.UI.DataStore public List GetAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetAllRequest() + { + Collection = Name + }).Result; + + return result.Items; } public void Delete(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreDeleteRequest() + { + Collection = Name, + Key = key + }).Result; } public void DeleteAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreDeleteAllRequest() + { + Collection = Name, + }).Result; } public int Count() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreCountRequest() + { + Collection = Name + }).Result; + + return result.Count; } public IDataStoreItem GetItem(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetItemRequest() + { + Collection = Name, + Key = key + }).Result; + + return result.Item; + } + + public List GetUnsynchronized() + { + return GetAll().Where(x => !x.IsSynchronized).ToList(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index 02d8e1858..e5bec90f2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using Tango.Core.DI; using Tango.DataStore; +using Tango.DataStore.EF; using Tango.DataStore.Lite; using Tango.DataStore.Remote; using Tango.Integration.ExternalBridge; @@ -34,7 +35,7 @@ namespace Tango.PPC.Common.DataStore { if (_manager == null) { - _manager = new LiteDBDataStoreManager(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "DataStore", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".db")); + _manager = new EFDataStoreManager(); } return _manager; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index fec0dfd1a..0a6e57f5d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -383,6 +383,10 @@ {58e8825f-0c96-449c-b320-1e82b0aa876b} Tango.CSV + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + {fa96bc0c-4055-475c-9dcc-70a5a9436b10} Tango.DataStore.Lite @@ -507,7 +511,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs index 66fca8e36..bbb0e883b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs @@ -14,9 +14,11 @@ namespace Tango.PPC.Common.Web public bool RequestJobs { get; set; } public bool RequestJobRuns { get; set; } public bool RequestMachineEvents { get; set; } + public bool RequestDataStoreItems { get; set; } public int MaxJobs { get; set; } public int MaxJobRuns { get; set; } public int MaxMachinesEvents { get; set; } + public int MaxDataStoreItems { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs index 5c3f7ba78..e90c7c2ac 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List Jobs { get; set; } public List JobRuns { get; set; } public List MachineEvents { get; set; } + public List DataStoreItems { get; set; } public DownloadMachineDataResponse() { Jobs = new List(); JobRuns = new List(); MachineEvents = new List(); + DataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs index fc135c234..fda7a4666 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List SynchronizedJobs { get; set; } public List SynchronizedJobRuns { get; set; } public List SynchronizedMachineEvents { get; set; } + public List SynchronizedDataStoreItems { get; set; } public NotifyMachineDataDownloadCompletedRequest() { SynchronizedJobs = new List(); SynchronizedJobRuns = new List(); SynchronizedMachineEvents = new List(); + SynchronizedDataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs index d7475819c..8eee667cd 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs @@ -15,6 +15,7 @@ namespace Tango.PPC.Common.Web public List JobRuns { get; set; } public List MachineEvents { get; set; } public List OfflineUpdates { get; set; } + public List DataStoreItems { get; set; } public String ApplicationVersion { get; set; } public String FirmwareVersion { get; set; } @@ -24,6 +25,7 @@ namespace Tango.PPC.Common.Web JobRuns = new List(); MachineEvents = new List(); OfflineUpdates = new List(); + DataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs index 0119c07b6..ba0b4089b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs @@ -15,6 +15,8 @@ namespace Tango.PPC.Common.Web public List FailedJobRuns { get; set; } public List FailedMachineEvents { get; set; } public List FailedOfflineUpdates { get; set; } + public List FailedDataStoreItems { get; set; } + public String NotifyCompletedToken { get; set; } public UploadMachineDataResponse() @@ -23,6 +25,7 @@ namespace Tango.PPC.Common.Web FailedJobRuns = new List(); FailedMachineEvents = new List(); FailedOfflineUpdates = new List(); + FailedDataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs new file mode 100644 index 000000000..769533445 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs @@ -0,0 +1,117 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreCollection : IDataStoreCollection + { + public string Name { get; } + + public EFDataStoreCollection(String name) + { + Name = name; + } + + public void Put(string key, T value) + { + Put(key, (object)value); + } + + public void Put(string key, object value) + { + Put(key, DataStoreHelper.GetDataType(value), value); + } + + public void Put(string key, DataType type, object value) + { + using (var db = ObservablesContext.CreateDefault()) + { + DataStoreItem item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + item = new DataStoreItem(); + db.DataStoreItems.Add(item); + } + + item.CollectionName = Name; + item.Key = key; + item.DataType = (int)type; + item.Value = EFDataStoreHelper.CreateBytes(type, value); + + db.SaveChanges(); + } + } + + public T Get(string key) + { + return (T)Get(key); + } + + public object Get(string key) + { + return GetItem(key).Value; + } + + public IDataStoreItem GetItem(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + var item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + throw new KeyNotFoundException("The specified data store key was not found."); + } + + return item.ToDataStoreItem(); + } + } + + public List GetAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public List GetUnsynchronized() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name && !x.IsSynchronized).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public void Delete(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}' AND KEY = '{key}'"); + } + } + + public void DeleteAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}'"); + } + } + + public int Count() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Count(x => x.CollectionName == Name); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs new file mode 100644 index 000000000..c51c54b7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public static class EFDataStoreHelper + { + public static byte[] CreateBytes(DataType type, Object obj) + { + switch (type) + { + case DataType.Int32: + return BitConverter.GetBytes((int)obj); + case DataType.Float: + return BitConverter.GetBytes((float)obj); + case DataType.Double: + return BitConverter.GetBytes((double)obj); + case DataType.Boolean: + return BitConverter.GetBytes((bool)obj); + case DataType.String: + return Encoding.Default.GetBytes(obj.ToString()); + case DataType.Bytes: + return (byte[])obj; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static Object CreateObject(DataType type, byte[] bytes) + { + switch (type) + { + case DataType.Int32: + return BitConverter.ToInt32(bytes, 0); + case DataType.Float: + return BitConverter.ToSingle(bytes, 0); + case DataType.Double: + return BitConverter.ToDouble(bytes, 0); + case DataType.Boolean: + return BitConverter.ToBoolean(bytes, 0); + case DataType.String: + return Encoding.Default.GetString(bytes); + case DataType.Bytes: + return bytes; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static IDataStoreItem CreateDataStoreItem(DataStoreItem item) + { + return new EFDataStoreItem() + { + Guid = item.Guid, + Date = item.LastUpdated, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + Type = (DataType)item.DataType, + Value = CreateObject((DataType)item.DataType, item.Value) + }; + } + + public static DataStoreItem CreateDbDataStoreItem(IDataStoreItem item) + { + return new DataStoreItem() + { + Guid = item.Guid, + LastUpdated = item.Date, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + DataType = (int)item.Type, + Value = CreateBytes(item.Type, item.Value) + }; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs new file mode 100644 index 000000000..45061c7ef --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreItem : IDataStoreItem + { + public string Guid { get; set; } + public string Key { get; set; } + public DataType Type { get; set; } + public object Value { get; set; } + public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public EFDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } + + public override string ToString() + { + return $"{Key}: {Value}"; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs new file mode 100644 index 000000000..4314a25f9 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreManager : IDataStoreManager + { + public IDataStoreCollection GetCollection(string name) + { + using (var db = ObservablesContext.CreateDefault()) + { + return new EFDataStoreCollection(name); + } + } + + public List GetCollectionNames() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Select(x => x.CollectionName).Distinct().ToList(); + } + } + + public void Dispose() + { + //DO Nothing. + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs new file mode 100644 index 000000000..361a37a7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.DataStore; +using Tango.DataStore.EF; + +public static class ExtensionMethods +{ + public static IDataStoreItem ToDataStoreItem(this DataStoreItem item) + { + return EFDataStoreHelper.CreateDataStoreItem(item); + } + + public static DataStoreItem ToDbDataStoreItem(this IDataStoreItem item) + { + return EFDataStoreHelper.CreateDbDataStoreItem(item); + } +} + diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c59e45461 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Data Store Entity Framework Implementation")] +[assembly: AssemblyVersion("2.0.4.1608")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj new file mode 100644 index 000000000..53e288584 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4} + Library + Properties + Tango.DataStore.EF + Tango.DataStore.EF + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + GlobalVersionInfo.cs + + + + + + + + + + + + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/packages.config b/Software/Visual_Studio/Tango.DataStore.EF/packages.config new file mode 100644 index 000000000..1127d4e32 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs index 9c939797a..e61385ab8 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs @@ -35,7 +35,8 @@ namespace Tango.DataStore.Lite Key = key, Date = DateTime.UtcNow, Type = type, - Value = value + Value = value, + IsSynchronized = false, }); } @@ -80,5 +81,10 @@ namespace Tango.DataStore.Lite { return _collection.FindById(key); } + + public List GetUnsynchronized() + { + return _collection.Find(x => !x.IsSynchronized).ToList(); + } } } diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs index 6a5a44462..544a15b61 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs @@ -9,11 +9,18 @@ namespace Tango.DataStore.Lite { public class LiteDBDataStoreItem : IDataStoreItem { + public String Guid { get; set; } [BsonId] public string Key { get; set; } public DataType Type { get; set; } public object Value { get; set; } public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public LiteDBDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } public override string ToString() { diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs index 45f5d3406..e73d02328 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs @@ -61,6 +61,11 @@ namespace Tango.DataStore /// List GetAll(); /// + /// Gets all the data store unsynchronized items in the collection. + /// + /// + List GetUnsynchronized(); + /// /// Deleted an item by the specified key. /// /// The key. diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs index 1e58518ff..9c03f40ee 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs @@ -11,6 +11,11 @@ namespace Tango.DataStore /// public interface IDataStoreItem { + /// + /// Gets or sets the unique identifier (Use only for synchronization). + /// + String Guid { get; set; } + /// /// Gets or sets item id. /// @@ -30,5 +35,10 @@ namespace Tango.DataStore /// Gets or sets the item update UTC date. /// DateTime Date { get; set; } + + /// + /// Gets or sets a value indicating whether this item is synchronized with the remote service. + /// + bool IsSynchronized { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 0c47f5e34..f8682dd18 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -1786,7 +1786,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "int", DataType = DataType.Int32, @@ -1826,7 +1826,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "float", DataType = DataType.Float, @@ -1866,7 +1866,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "double", DataType = DataType.Double, @@ -1906,7 +1906,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bool", DataType = DataType.Boolean, @@ -1946,7 +1946,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "string", DataType = DataType.String, @@ -1986,7 +1986,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bytes", DataType = DataType.Bytes, diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index 218652c1b..0371c1cca 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -213,6 +213,10 @@ {38197109-8610-4d3f-92b9-16d48df94d7c} Tango.DAL.Remote + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + {fa96bc0c-4055-475c-9dcc-70a5a9436b10} Tango.DataStore.Lite @@ -315,7 +319,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index c77985b68..615dc2154 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -425,6 +425,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Lite", "Tan EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Remote", "Tango.DataStore.Remote\Tango.DataStore.Remote.csproj", "{29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.EF", "Tango.DataStore.EF\Tango.DataStore.EF.csproj", "{88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4012,6 +4014,26 @@ Global {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x64.Build.0 = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.ActiveCfg = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4157,12 +4179,12 @@ Global {EA4233F1-4B7B-4CCF-A6DE-2D17612EBA90} = {E728CBD9-1AF4-4814-A218-E4BD26E7EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} - BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear - BuildVersion_UpdateAssemblyVersion = True - BuildVersion_UpdateFileVersion = False - BuildVersion_StartDate = 2000/1/1 - BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs BuildVersion_UseGlobalSettings = False + BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs + BuildVersion_StartDate = 2000/1/1 + BuildVersion_UpdateFileVersion = False + BuildVersion_UpdateAssemblyVersion = True + BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear + SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} EndGlobalSection EndGlobal diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2c1c27f52..2eb2b01c4 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -562,26 +562,38 @@ namespace Tango.MachineService.Controllers } } - //Insert JobRuns. - foreach (var dto in request.JobRuns) + //Insert Update DataStore Items + foreach (var dto in request.DataStoreItems) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var run = dto.ToObservable(); - run.ID = 0; - run.IsSynchronized = true; + var dataStoreItem = dto.ToObservable(); + dataStoreItem.MachineGuid = RequestToken.Object.MachineGuid; - if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) + dataStoreItem.ID = 0; + dataStoreItem.IsSynchronized = true; + + var existingItem = db.DataStoreItems.SingleOrDefault(x => x.Guid == dataStoreItem.Guid); + + if (existingItem == null) { - db.JobRuns.Add(run); + db.DataStoreItems.Add(dataStoreItem); + db.SaveChanges(); + } + else if (dataStoreItem.LastUpdated > existingItem.LastUpdated) + { + existingItem.DataType = dataStoreItem.DataType; + existingItem.Value = dataStoreItem.Value; + existingItem.IsSynchronized = true; + existingItem.LastUpdated = dataStoreItem.LastUpdated; db.SaveChanges(); } } catch (Exception ex) { - response.FailedJobRuns.Add(new SynchronizationFailedEntity() + response.FailedDataStoreItems.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -590,26 +602,26 @@ namespace Tango.MachineService.Controllers } } - //Insert MachineEvents. - foreach (var dto in request.MachineEvents) + //Insert JobRuns. + foreach (var dto in request.JobRuns) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var ev = dto.ToObservable(); - ev.ID = 0; - ev.IsSynchronized = true; + var run = dto.ToObservable(); + run.ID = 0; + run.IsSynchronized = true; - if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) { - db.MachinesEvents.Add(ev); + db.JobRuns.Add(run); db.SaveChanges(); } } catch (Exception ex) { - response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + response.FailedJobRuns.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -645,6 +657,34 @@ namespace Tango.MachineService.Controllers } } } + + //Insert MachineEvents. + foreach (var dto in request.MachineEvents) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var ev = dto.ToObservable(); + ev.ID = 0; + ev.IsSynchronized = true; + + if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + { + db.MachinesEvents.Add(ev); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } } catch (Exception ex) { @@ -711,6 +751,18 @@ namespace Tango.MachineService.Controllers response.MachineEvents.Add(dto); } } + + //Send DataStore Items + if (request.RequestDataStoreItems) + { + var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); + + foreach (var item in dataStoreItems) + { + DataStoreItemDTO dto = DataStoreItemDTO.FromObservable(item); + response.DataStoreItems.Add(dto); + } + } } return response; @@ -745,6 +797,11 @@ namespace Tango.MachineService.Controllers { db.Database.ExecuteSqlCommand($"UPDATE MACHINES_EVENTS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedMachineEvents.Select(x => "'" + x + "'"))});"); } + + if (request.SynchronizedDataStoreItems.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE DATA_STORE_ITEMS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedDataStoreItems.Select(x => "'" + x + "'"))});"); + } } return response; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index 11c9ee72a..41fa77771 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.5.0")] +[assembly: AssemblyVersion("3.0.6.0")] -- cgit v1.3.1 From adaddad79352c156303e9178a6f172a18af50cd2 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 24 Oct 2020 06:40:07 +0300 Subject: Refactored DataStore Proto. --- .../PMR/Messages/DataStore/DataStoreItem.proto | 4 ++ Software/PMR/Messages/DataStore/DataType.proto | 1 + .../DataStore/RemoteDataStoreCollection.cs | 27 +++++++- .../DataStore/DefaultDataStoreService.cs | 14 ++++- .../Tango.Core/Bson/BsonUtcSerializer.cs | 44 +++++++++++++- .../Tango.DataStore.EF/EFDataStoreHelper.cs | 14 ++++- .../Tango.DataStore.EF/Tango.DataStore.EF.csproj | 7 +++ .../Tango.DataStore.EF/packages.config | 1 + .../RemoteDataStoreGetResponse.cs | 24 +++++++- .../Tango.DataStore.Remote/RemoteDataStoreItem.cs | 22 ++++++- .../RemoteDataStorePutRequest.cs | 23 ++++++- .../Tango.DataStore.Remote.csproj | 10 +++ .../Tango.DataStore.Remote/packages.config | 5 ++ .../Tango.DataStore/DataStoreHelper.cs | 70 +++++++++++++-------- .../Tango.DataStore/DataStoreProtoObject.cs | 71 ++++++++++++++++++++++ Software/Visual_Studio/Tango.DataStore/DataType.cs | 3 +- .../Tango.DataStore/Tango.DataStore.csproj | 21 +++++++ .../Visual_Studio/Tango.DataStore/packages.config | 5 ++ .../Tango.Emulations/Emulators/MachineEmulator.cs | 42 +++++++++++++ .../Tango.PMR/DataStore/DataStoreItem.cs | 48 ++++++++++++--- .../Visual_Studio/Tango.PMR/DataStore/DataType.cs | 7 ++- Software/Visual_Studio/Tango.PMR/MessageFactory.cs | 32 ++++++++++ .../Tango.UnitTesting/DataStore/DataStore_TST.cs | 34 ++++++++++- .../Tango.UnitTesting/Tango.UnitTesting.csproj | 6 +- 24 files changed, 484 insertions(+), 51 deletions(-) create mode 100644 Software/Visual_Studio/Tango.DataStore.Remote/packages.config create mode 100644 Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs create mode 100644 Software/Visual_Studio/Tango.DataStore/packages.config (limited to 'Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj') diff --git a/Software/PMR/Messages/DataStore/DataStoreItem.proto b/Software/PMR/Messages/DataStore/DataStoreItem.proto index f516fa92c..d4b329799 100644 --- a/Software/PMR/Messages/DataStore/DataStoreItem.proto +++ b/Software/PMR/Messages/DataStore/DataStoreItem.proto @@ -1,6 +1,7 @@ syntax = "proto3"; import "DataType.proto"; +import "MessageType.proto"; package Tango.PMR.DataStore; option java_package = "com.twine.tango.pmr.datastore"; @@ -14,4 +15,7 @@ message DataStoreItem bool BooleanValue = 5; string StringValue = 6; bytes BytesValue = 7; + + //Use only when DataType = Proto. + PMR.Common.MessageType ProtoType = 20; } \ No newline at end of file diff --git a/Software/PMR/Messages/DataStore/DataType.proto b/Software/PMR/Messages/DataStore/DataType.proto index 17f9403ec..3c6ae0e05 100644 --- a/Software/PMR/Messages/DataStore/DataType.proto +++ b/Software/PMR/Messages/DataStore/DataType.proto @@ -13,4 +13,5 @@ enum DataType Boolean = 3; String = 4; Bytes = 5; + Proto = 6; } \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs index 0ff387e85..4cf64a688 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs @@ -1,4 +1,5 @@ -using System; +using Google.Protobuf; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -33,6 +34,18 @@ namespace Tango.FSE.UI.DataStore public void Put(string key, DataType type, object value) { + if (type == DataType.Proto) + { + if (value is IMessage protoMessage) + { + value = DataStoreProtoObject.FromMessage(protoMessage); + } + else + { + throw new InvalidOperationException("DataType if Proto but actual message is not part of the PMR."); + } + } + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStorePutRequest() { Collection = Name, @@ -59,13 +72,23 @@ namespace Tango.FSE.UI.DataStore public object Get(string key, object defaultValue) { + if (defaultValue is IMessage defaultValueMessage) + { + defaultValue = DataStoreProtoObject.FromMessage(defaultValueMessage); + } + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetRequest() { Collection = Name, Key = key, - DefaultValue = defaultValue + DefaultValue = defaultValue, }).Result; + if (result.DataType == DataType.Proto) + { + return result.ProtoObject.Message; + } + return result.Value; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index f11d37659..bf0eadae1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -52,17 +52,18 @@ namespace Tango.PPC.Common.DataStore [ExternalBridgeRequestHandlerMethod(typeof(RemoteDataStorePutRequest), RequestHandlerLoggingMode.LogRequestName)] public async Task OnRemoteDataStorePutRequest(RemoteDataStorePutRequest request, String token, ExternalBridgeReceiver receiver) { - GetManager().GetCollection(request.Collection).Put(request.Key, request.DataType, request.Value); + GetManager().GetCollection(request.Collection).Put(request.Key, request.Value); await receiver.SendGenericResponse(new RemoteDataStorePutResponse(), token); } [ExternalBridgeRequestHandlerMethod(typeof(RemoteDataStoreGetRequest), RequestHandlerLoggingMode.LogRequestName)] public async Task OnRemoteDataStoreGetRequest(RemoteDataStoreGetRequest request, String token, ExternalBridgeReceiver receiver) { - var value = GetManager().GetCollection(request.Collection).Get(request.Key, request.DefaultValue); + var item = GetManager().GetCollection(request.Collection).GetItem(request.Key, request.DefaultValue); await receiver.SendGenericResponse(new RemoteDataStoreGetResponse() { - Value = value + DataType = item.Type, + Value = item.Value, }, token); } @@ -227,6 +228,11 @@ namespace Tango.PPC.Common.DataStore case Tango.DataStore.DataType.Bytes: pmr.BytesValue = Google.Protobuf.ByteString.CopyFrom((byte[])Convert.ChangeType(item.Value, typeof(byte[]))); break; + case Tango.DataStore.DataType.Proto: + DataStoreProtoObject proto = item.Value as DataStoreProtoObject; + pmr.BytesValue = Google.Protobuf.ByteString.CopyFrom(proto.Data); + pmr.ProtoType = proto.MessageType; + break; } return pmr; @@ -250,6 +256,8 @@ namespace Tango.PPC.Common.DataStore return item.StringValue; case PMR.DataStore.DataType.Bytes: return item.BytesValue.ToByteArray(); + case PMR.DataStore.DataType.Proto: + return DataStoreProtoObject.FromPMRDataStoreItem(item); } throw new NotSupportedException("The specified data type if not supported."); diff --git a/Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs b/Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs index 6f5cb7700..7621bd132 100644 --- a/Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs +++ b/Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs @@ -1,14 +1,56 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Bson; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tango.Core.Bson { + public static class BsonConvert + { + private static BsonUtcSerializer _serializer; + + static BsonConvert() + { + _serializer = new BsonUtcSerializer(); + } + + public static byte[] Serialize(Object obj) + { + MemoryStream ms = new MemoryStream(); + using (BsonWriter writer = new BsonWriter(ms)) + { + _serializer.Serialize(writer, obj); + return ms.ToArray(); + } + } + + public static byte[] Serialize(T obj) + { + return Serialize((Object)obj); + } + + public static Object Deserialize(byte[] data, Type type) + { + MemoryStream ms = new MemoryStream(data); + using (BsonReader reader = new BsonReader(ms)) + { + Object obj = _serializer.Deserialize(reader, type); + return obj; + } + } + + public static T Deserialize(byte[] data) + { + return (T)Deserialize(data, typeof(T)); + } + } + public class BsonUtcSerializer : JsonSerializer { private class DateTimeConverter : JsonConverter @@ -65,4 +107,4 @@ namespace Tango.Core.Bson DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; } } -} +} \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs index c51c54b7c..0fbb0d4fe 100644 --- a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs @@ -1,4 +1,5 @@ -using System; +using Google.Protobuf; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -25,6 +26,15 @@ namespace Tango.DataStore.EF return Encoding.Default.GetBytes(obj.ToString()); case DataType.Bytes: return (byte[])obj; + case DataType.Proto: + if (obj is DataStoreProtoObject protoMessage) + { + return protoMessage.ToBytes(); + } + else + { + throw new NotSupportedException($"Data type is 'Proto' but object is not of type '{nameof(DataStoreProtoObject)}'."); + } } throw new NotSupportedException("The specified type is not supported."); @@ -46,6 +56,8 @@ namespace Tango.DataStore.EF return Encoding.Default.GetString(bytes); case DataType.Bytes: return bytes; + case DataType.Proto: + return DataStoreProtoObject.FromBytes(bytes); } throw new NotSupportedException("The specified type is not supported."); diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj index 53e288584..96ecb5ad1 100644 --- a/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj +++ b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj @@ -37,6 +37,9 @@ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + ..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll @@ -77,6 +80,10 @@ {e0364dfa-0721-4637-9d32-9d22aac109d6} Tango.DataStore + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/packages.config b/Software/Visual_Studio/Tango.DataStore.EF/packages.config index 1127d4e32..13be55da1 100644 --- a/Software/Visual_Studio/Tango.DataStore.EF/packages.config +++ b/Software/Visual_Studio/Tango.DataStore.EF/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetResponse.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetResponse.cs index a3c5eb99c..cc3b157e8 100644 --- a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetResponse.cs +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetResponse.cs @@ -8,6 +8,28 @@ namespace Tango.DataStore.Remote { public class RemoteDataStoreGetResponse { - public Object Value { get; set; } + public DataType DataType { get; set; } + + private Object _value; + public Object Value + { + get + { + return DataType == DataType.Proto ? ProtoObject : _value; + } + set + { + if (value is DataStoreProtoObject protoValue) + { + ProtoObject = protoValue; + } + else + { + _value = value; + } + } + } + + public DataStoreProtoObject ProtoObject { get; set; } } } diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreItem.cs index c58e3ab28..4327a0bd6 100644 --- a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreItem.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -11,7 +12,24 @@ namespace Tango.DataStore.Remote public string Guid { get; set; } public string Key { get; set; } public DataType Type { get; set; } - public object Value { get; set; } + + private object _value; + public object Value + { + get + { + if (_value is JObject jObject) + { + return (jObject.ToObject()); + } + else + { + return _value; + } + } + set { _value = value; } + } + public DateTime Date { get; set; } public bool IsSynchronized { get; set; } diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStorePutRequest.cs b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStorePutRequest.cs index 6ea13bf6b..77aa5e41f 100644 --- a/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStorePutRequest.cs +++ b/Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStorePutRequest.cs @@ -11,6 +11,27 @@ namespace Tango.DataStore.Remote public String Collection { get; set; } public DataType DataType { get; set; } public String Key { get; set; } - public Object Value { get; set; } + + private Object _value; + public Object Value + { + get + { + return DataType == DataType.Proto ? ProtoObject : _value; + } + set + { + if (value is DataStoreProtoObject protoValue) + { + ProtoObject = protoValue; + } + else + { + _value = value; + } + } + } + + public DataStoreProtoObject ProtoObject { get; set; } } } diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj b/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj index 87a9c4766..2b05d6af3 100644 --- a/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj +++ b/Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj @@ -31,6 +31,12 @@ 4 + + ..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + @@ -69,5 +75,9 @@ Tango.DataStore + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.Remote/packages.config b/Software/Visual_Studio/Tango.DataStore.Remote/packages.config new file mode 100644 index 000000000..026e719c3 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Remote/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs index 53745990e..3cf24bdd0 100644 --- a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs +++ b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs @@ -1,8 +1,14 @@ -using System; +using Google.Protobuf; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core.ExtensionMethods; +using Tango.PMR; +using Tango.PMR.Common; namespace Tango.DataStore { @@ -53,6 +59,14 @@ namespace Tango.DataStore { return DataType.Bytes; } + else if (type == typeof(DataStoreProtoObject)) + { + return DataType.Proto; + } + else if (typeof(IMessage).IsAssignableFrom(type)) + { + return DataType.Proto; + } throw new NotSupportedException($"The specified type '{type.Name}' is not supported by the data store."); } @@ -63,26 +77,28 @@ namespace Tango.DataStore /// The type. /// /// The specified data type is not supported. - public static Type GetType(DataType type) - { - switch (type) - { - case DataType.Boolean: - return typeof(bool); - case DataType.Bytes: - return typeof(byte[]); - case DataType.Double: - return typeof(double); - case DataType.Float: - return typeof(float); - case DataType.Int32: - return typeof(Int32); - case DataType.String: - return typeof(String); - } + //public static Type GetType(DataType type) + //{ + // switch (type) + // { + // case DataType.Boolean: + // return typeof(bool); + // case DataType.Bytes: + // return typeof(byte[]); + // case DataType.Double: + // return typeof(double); + // case DataType.Float: + // return typeof(float); + // case DataType.Int32: + // return typeof(Int32); + // case DataType.String: + // return typeof(String); + // case DataType.Proto: + // return typeof(DataStoreProtoObject); + // } - throw new NotSupportedException("The specified data type is not supported."); - } + // throw new NotSupportedException("The specified data type is not supported."); + //} /// /// Formats the data store item as a string. @@ -91,11 +107,7 @@ namespace Tango.DataStore /// public static String FormatDataStoreItem(IDataStoreItem item) { - if (item.Type != DataType.Bytes) - { - return $"{item.Key}: {item.Value}"; - } - else + if (item.Type == DataType.Bytes) { byte[] bytes = (byte[])item.Value; @@ -106,6 +118,14 @@ namespace Tango.DataStore } return hex.ToString(); } + else if (item.Type == DataType.Proto) + { + return (item.Value as DataStoreProtoObject).Message.ToJsonString(); + } + else + { + return $"{item.Key}: {item.Value}"; + } } } } diff --git a/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs b/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs new file mode 100644 index 000000000..ec4cf1057 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs @@ -0,0 +1,71 @@ +using Google.Protobuf; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Bson; +using Tango.PMR; +using Tango.PMR.Common; +using Tango.PMR.DataStore; + +namespace Tango.DataStore +{ + public class DataStoreProtoObject + { + public MessageType MessageType { get; set; } + public Type Type { get; set; } + public byte[] Data { get; set; } + + + private IMessage _message; + [JsonIgnore] + public IMessage Message + { + get + { + if (_message == null) + { + _message = MessageFactory.ParseProtoMessage(Data, Type); + } + + return _message; + } + private set { _message = value; } + } + + public byte[] ToBytes() + { + return BsonConvert.Serialize(this); + } + + public static DataStoreProtoObject FromBytes(byte[] data) + { + var instance = BsonConvert.Deserialize(data); + instance.Message = MessageFactory.ParseProtoMessage(instance.Data, instance.Type); + + return instance; + } + + public static DataStoreProtoObject FromMessage(IMessage message) + { + DataStoreProtoObject proto = new DataStoreProtoObject(); + proto.Type = message.GetType(); + proto.MessageType = MessageFactory.ParseMessageType(proto.Type.Name); + proto.Data = message.ToByteArray(); + proto.Message = message; + return proto; + } + + public static DataStoreProtoObject FromPMRDataStoreItem(DataStoreItem item) + { + DataStoreProtoObject proto = new DataStoreProtoObject(); + proto.MessageType = item.ProtoType; + proto.Type = MessageFactory.GetPMRTypeFromMessageType(item.ProtoType); + proto.Data = item.BytesValue.ToByteArray(); + return proto; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore/DataType.cs b/Software/Visual_Studio/Tango.DataStore/DataType.cs index ddb8adf4d..132bff28e 100644 --- a/Software/Visual_Studio/Tango.DataStore/DataType.cs +++ b/Software/Visual_Studio/Tango.DataStore/DataType.cs @@ -16,6 +16,7 @@ namespace Tango.DataStore Double, Boolean, String, - Bytes + Bytes, + Proto } } diff --git a/Software/Visual_Studio/Tango.DataStore/Tango.DataStore.csproj b/Software/Visual_Studio/Tango.DataStore/Tango.DataStore.csproj index 37c0ecfc2..8035af7b4 100644 --- a/Software/Visual_Studio/Tango.DataStore/Tango.DataStore.csproj +++ b/Software/Visual_Studio/Tango.DataStore/Tango.DataStore.csproj @@ -33,6 +33,12 @@ bin\Release\Tango.DataStore.xml + + ..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + @@ -47,11 +53,26 @@ GlobalVersionInfo.cs + + + + + + + + {A34EE0F0-649D-41C8-8489-B6F1CC6924EE} + Tango.Core + + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore/packages.config b/Software/Visual_Studio/Tango.DataStore/packages.config new file mode 100644 index 000000000..026e719c3 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 05752c378..e5296ab4c 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -2018,6 +2018,48 @@ namespace Tango.Emulations.Emulators LogManager.Log(ex, "Failed."); } } + + { + try + { + LogManager.Log("Testing proto..."); + + var response = await Transporter.SendRequest(new PutDataStoreItemRequest() + { + Collection = "TEST", + Key = "proto", + Item = new PMR.DataStore.DataStoreItem() + { + DataType = DataType.Proto, + BytesValue = new CalculateRequest() { A = 10, B = 15 }.ToByteString(), + ProtoType = MessageType.CalculateRequest, + } + }); + + if (response.Container.Error != ErrorCode.None) + { + LogManager.Log("Put Failed."); + LogManager.Log(response.ToJsonString()); + } + else + { + var res = await Transporter.SendRequest(new GetDataStoreItemRequest() + { + Collection = "TEST", + Key = "proto" + }); + + LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); + + LogManager.Log(CalculateRequest.Parser.ParseFrom(res.Message.Item.BytesValue).ToJsonString()); + LogManager.Log(res.ToJsonString()); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Failed."); + } + } } #endregion diff --git a/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItem.cs b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItem.cs index 4b7534738..f560237ae 100644 --- a/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItem.cs +++ b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItem.cs @@ -23,16 +23,17 @@ namespace Tango.PMR.DataStore { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "ChNEYXRhU3RvcmVJdGVtLnByb3RvEhNUYW5nby5QTVIuRGF0YVN0b3JlGg5E", - "YXRhVHlwZS5wcm90byK8AQoNRGF0YVN0b3JlSXRlbRIvCghEYXRhVHlwZRgB", - "IAEoDjIdLlRhbmdvLlBNUi5EYXRhU3RvcmUuRGF0YVR5cGUSEgoKSW50MzJW", - "YWx1ZRgCIAEoBRISCgpGbG9hdFZhbHVlGAMgASgCEhMKC0RvdWJsZVZhbHVl", - "GAQgASgBEhQKDEJvb2xlYW5WYWx1ZRgFIAEoCBITCgtTdHJpbmdWYWx1ZRgG", - "IAEoCRISCgpCeXRlc1ZhbHVlGAcgASgMQh8KHWNvbS50d2luZS50YW5nby5w", - "bXIuZGF0YXN0b3JlYgZwcm90bzM=")); + "YXRhVHlwZS5wcm90bxoRTWVzc2FnZVR5cGUucHJvdG8i7gEKDURhdGFTdG9y", + "ZUl0ZW0SLwoIRGF0YVR5cGUYASABKA4yHS5UYW5nby5QTVIuRGF0YVN0b3Jl", + "LkRhdGFUeXBlEhIKCkludDMyVmFsdWUYAiABKAUSEgoKRmxvYXRWYWx1ZRgD", + "IAEoAhITCgtEb3VibGVWYWx1ZRgEIAEoARIUCgxCb29sZWFuVmFsdWUYBSAB", + "KAgSEwoLU3RyaW5nVmFsdWUYBiABKAkSEgoKQnl0ZXNWYWx1ZRgHIAEoDBIw", + "CglQcm90b1R5cGUYFCABKA4yHS5UYW5nby5QTVIuQ29tbW9uLk1lc3NhZ2VU", + "eXBlQh8KHWNvbS50d2luZS50YW5nby5wbXIuZGF0YXN0b3JlYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { global::Tango.PMR.DataStore.DataTypeReflection.Descriptor, }, + new pbr::FileDescriptor[] { global::Tango.PMR.DataStore.DataTypeReflection.Descriptor, global::Tango.PMR.Common.MessageTypeReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.DataStore.DataStoreItem), global::Tango.PMR.DataStore.DataStoreItem.Parser, new[]{ "DataType", "Int32Value", "FloatValue", "DoubleValue", "BooleanValue", "StringValue", "BytesValue" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.DataStore.DataStoreItem), global::Tango.PMR.DataStore.DataStoreItem.Parser, new[]{ "DataType", "Int32Value", "FloatValue", "DoubleValue", "BooleanValue", "StringValue", "BytesValue", "ProtoType" }, null, null, null) })); } #endregion @@ -70,6 +71,7 @@ namespace Tango.PMR.DataStore { booleanValue_ = other.booleanValue_; stringValue_ = other.stringValue_; bytesValue_ = other.bytesValue_; + protoType_ = other.protoType_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -154,6 +156,20 @@ namespace Tango.PMR.DataStore { } } + /// Field number for the "ProtoType" field. + public const int ProtoTypeFieldNumber = 20; + private global::Tango.PMR.Common.MessageType protoType_ = 0; + /// + ///Use only when DataType = Proto. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Tango.PMR.Common.MessageType ProtoType { + get { return protoType_; } + set { + protoType_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as DataStoreItem); @@ -174,6 +190,7 @@ namespace Tango.PMR.DataStore { if (BooleanValue != other.BooleanValue) return false; if (StringValue != other.StringValue) return false; if (BytesValue != other.BytesValue) return false; + if (ProtoType != other.ProtoType) return false; return true; } @@ -187,6 +204,7 @@ namespace Tango.PMR.DataStore { if (BooleanValue != false) hash ^= BooleanValue.GetHashCode(); if (StringValue.Length != 0) hash ^= StringValue.GetHashCode(); if (BytesValue.Length != 0) hash ^= BytesValue.GetHashCode(); + if (ProtoType != 0) hash ^= ProtoType.GetHashCode(); return hash; } @@ -225,6 +243,10 @@ namespace Tango.PMR.DataStore { output.WriteRawTag(58); output.WriteBytes(BytesValue); } + if (ProtoType != 0) { + output.WriteRawTag(160, 1); + output.WriteEnum((int) ProtoType); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -251,6 +273,9 @@ namespace Tango.PMR.DataStore { if (BytesValue.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeBytesSize(BytesValue); } + if (ProtoType != 0) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) ProtoType); + } return size; } @@ -280,6 +305,9 @@ namespace Tango.PMR.DataStore { if (other.BytesValue.Length != 0) { BytesValue = other.BytesValue; } + if (other.ProtoType != 0) { + ProtoType = other.ProtoType; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -318,6 +346,10 @@ namespace Tango.PMR.DataStore { BytesValue = input.ReadBytes(); break; } + case 160: { + protoType_ = (global::Tango.PMR.Common.MessageType) input.ReadEnum(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.PMR/DataStore/DataType.cs b/Software/Visual_Studio/Tango.PMR/DataStore/DataType.cs index 0c2a2c1ab..3ec396931 100644 --- a/Software/Visual_Studio/Tango.PMR/DataStore/DataType.cs +++ b/Software/Visual_Studio/Tango.PMR/DataStore/DataType.cs @@ -22,10 +22,10 @@ namespace Tango.PMR.DataStore { static DataTypeReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "Cg5EYXRhVHlwZS5wcm90bxITVGFuZ28uUE1SLkRhdGFTdG9yZSpQCghEYXRh", + "Cg5EYXRhVHlwZS5wcm90bxITVGFuZ28uUE1SLkRhdGFTdG9yZSpbCghEYXRh", "VHlwZRIJCgVJbnQzMhAAEgkKBUZsb2F0EAESCgoGRG91YmxlEAISCwoHQm9v", - "bGVhbhADEgoKBlN0cmluZxAEEgkKBUJ5dGVzEAVCHwodY29tLnR3aW5lLnRh", - "bmdvLnBtci5kYXRhc3RvcmViBnByb3RvMw==")); + "bGVhbhADEgoKBlN0cmluZxAEEgkKBUJ5dGVzEAUSCQoFUHJvdG8QBkIfCh1j", + "b20udHdpbmUudGFuZ28ucG1yLmRhdGFzdG9yZWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.DataStore.DataType), }, null)); @@ -41,6 +41,7 @@ namespace Tango.PMR.DataStore { [pbr::OriginalName("Boolean")] Boolean = 3, [pbr::OriginalName("String")] String = 4, [pbr::OriginalName("Bytes")] Bytes = 5, + [pbr::OriginalName("Proto")] Proto = 6, } #endregion diff --git a/Software/Visual_Studio/Tango.PMR/MessageFactory.cs b/Software/Visual_Studio/Tango.PMR/MessageFactory.cs index 6a796bf55..d23970e88 100644 --- a/Software/Visual_Studio/Tango.PMR/MessageFactory.cs +++ b/Software/Visual_Studio/Tango.PMR/MessageFactory.cs @@ -1,6 +1,7 @@ using Google.Protobuf; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Text; @@ -36,6 +37,16 @@ namespace Tango.PMR } } + /// + /// Returns the matching PMR type from the PMR message type. + /// + /// Type of the message. + /// + public static Type GetPMRTypeFromMessageType(MessageType messageType) + { + return _pmrTypes[messageType]; + } + /// /// Creates a new . /// @@ -205,5 +216,26 @@ namespace Tango.PMR { return typeof(MessageFactory).Assembly.GetTypes().Where(x => x.Namespace != null && x.Namespace.Contains("Stubs") && !x.Name.Contains("Reflection")).ToList(); } + + /// + /// Parses the proto message from the specified bytes. Requires the message type. + /// + /// The data. + /// The type. + /// + public static IMessage ParseProtoMessage(byte[] data, Type type) + { + using (MemoryStream ms = new MemoryStream(data)) + { + ms.Position = 0; + + using (BinaryReader reader = new BinaryReader(ms)) + { + IMessage message = Activator.CreateInstance(type) as IMessage; + MessageParser parser = type.GetProperty("Parser").GetValue(message) as MessageParser; + return parser.ParseFrom(data); + } + } + } } } diff --git a/Software/Visual_Studio/Tango.UnitTesting/DataStore/DataStore_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/DataStore/DataStore_TST.cs index 1428aa210..594c8d7f8 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/DataStore/DataStore_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/DataStore/DataStore_TST.cs @@ -11,6 +11,9 @@ using Tango.DataStore; using Tango.DataStore.Lite; using Tango.Core.IO; using Tango.DataStore.EF; +using Tango.PMR.Stubs; +using Tango.Transport; +using Tango.DataStore.Remote; namespace Tango.UnitTesting.DataStore { @@ -32,6 +35,27 @@ namespace Tango.UnitTesting.DataStore Run_Test(new EFDataStoreManager()); } + [TestMethod] + public void Remote_Data_Store_Working() + { + CalculateRequest calc = new CalculateRequest() + { + A = 10, + B = 15, + }; + + RemoteDataStoreGetResponse response = new RemoteDataStoreGetResponse(); + response.ProtoObject = DataStoreProtoObject.FromMessage(calc); + + byte[] data = GenericMessageSerializer.Serialize(response, PMR.Integration.GenericMessageProtocol.Bson); + + RemoteDataStoreGetResponse des = GenericMessageSerializer.Deserialize(data, PMR.Integration.GenericMessageProtocol.Bson); + + CalculateRequest cc = des.ProtoObject.Message as CalculateRequest; + + Assert.AreEqual(calc, cc); + } + private void Run_Test(IDataStoreManager manager) { IDataStoreCollection collection = manager.GetCollection("TEST"); @@ -72,7 +96,13 @@ namespace Tango.UnitTesting.DataStore Assert.AreEqual(value[0], 255); } - Assert.IsTrue(collection.Count() == 6); + { + collection.Put("calc", new CalculateRequest() { A = 10, B = 15 }); + CalculateRequest value = collection.Get("calc"); + Assert.AreEqual(value, new CalculateRequest() { A = 10, B = 15 }); + } + + Assert.IsTrue(collection.Count() == 7); Assert.ThrowsException(() => collection.Put("somekey", this)); @@ -82,7 +112,7 @@ namespace Tango.UnitTesting.DataStore collection.Delete("float"); Assert.ThrowsException(() => collection.Get("float")); - Assert.IsTrue(collection.Count() == 4); + Assert.IsTrue(collection.Count() == 5); collection.DeleteAll(); Assert.IsTrue(collection.Count() == 0); diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index 0371c1cca..b24079da0 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -221,6 +221,10 @@ {fa96bc0c-4055-475c-9dcc-70a5a9436b10} Tango.DataStore.Lite + + {29448f3c-9b3e-4da6-8555-46a8b9a6b3aa} + Tango.DataStore.Remote + {e0364dfa-0721-4637-9d32-9d22aac109d6} Tango.DataStore @@ -319,7 +323,7 @@ - + \ No newline at end of file -- cgit v1.3.1