From 14e4bd850fa6730eecd7d15bd7044f364b41c986 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 12 Nov 2020 20:38:57 +0200 Subject: Working on data store view. --- .../Web/Tango.MachineService/Controllers/PPCController.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index fbc4f8a0a..0e96c14c8 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -186,6 +186,15 @@ namespace Tango.MachineService.Controllers LogManager.Log(ex, $"Error resetting synchronized job runs for machine '{machine.SerialNumber}'."); } + try + { + b.DataStoreItems.Where(x => x.MachineGuid == machine.Guid).Update(x => new DataStoreItem() { IsSynchronized = false }); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error resetting synchronized data store items for machine '{machine.SerialNumber}'."); + } + //Reset Events. //b.MachinesEvents.Where(x => x.MachineGuid == machine.Guid).Update(x => new MachinesEvent() { IsSynchronized = false }); //Reset Jobs. @@ -755,7 +764,7 @@ namespace Tango.MachineService.Controllers //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(); + var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized & !x.IsDeleted).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); foreach (var item in dataStoreItems) { -- cgit v1.3.1 From 0ee81ef847af3702b3b37f94cc62e835f9294e55 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 16 Nov 2020 14:35:19 +0200 Subject: Working on DataStore WebAPI & CLI. --- .../DataStore/Tango.DataStore.CLI/App.config | 28 ++++ .../DataStore/Tango.DataStore.CLI/Options.cs | 51 +++++++ .../DataStore/Tango.DataStore.CLI/Program.cs | 49 +++++++ .../Tango.DataStore.CLI/Properties/AssemblyInfo.cs | 36 +++++ .../Tango.DataStore.CLI/Tango.DataStore.CLI.csproj | 86 ++++++++++++ .../DataStore/Tango.DataStore.CLI/packages.config | 5 + .../Tango.DataStore.EF/EFDataStoreCollection.cs | 15 ++- .../Tango.DataStore/DataStoreProtoObject.cs | 2 + Software/Visual_Studio/Tango.sln | 35 ++++- .../Controllers/DataStoreController.cs | 150 +++++++++++++++++++++ .../DataStore/DataStoreWebItem.cs | 26 ++++ .../DataStore/DataStoreWebItemType.cs | 14 ++ .../Tango.MachineService.csproj | 13 +- 13 files changed, 500 insertions(+), 10 deletions(-) create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/App.config create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Options.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Program.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Tango.DataStore.CLI.csproj create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.CLI/packages.config create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItem.cs create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItemType.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/App.config b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/App.config new file mode 100644 index 000000000..a46da65da --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/App.config @@ -0,0 +1,28 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Options.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Options.cs new file mode 100644 index 000000000..80b3caf7e --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Options.cs @@ -0,0 +1,51 @@ +using CommandLine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Web; + +namespace Tango.DataStore.CLI +{ + public class OptionsBase + { + [Option(longName: "email", HelpText = "Email address", Required = true)] + public String Email { get; set; } + + [Option(longName: "password", HelpText = "Password")] + public String Password { get; set; } + + [Option(longName: "env", HelpText = "Environment")] + public DeploymentSlot Environment { get; set; } + } + + [Verb("get", HelpText = "Get a data store item.")] + public class GetOptions : OptionsBase + { + [Option(longName: "sn", HelpText = "Machine serial number")] + public String MachineSerialNumber { get; set; } + + [Option(longName: "collection", HelpText = "Collection name")] + public String Collection { get; set; } + + [Option(longName: "key", HelpText = "Item key")] + public String Key { get; set; } + } + + [Verb("put", HelpText = "Get a data store item.")] + public class PutOptions : OptionsBase + { + [Option(longName: "sn", HelpText = "Machine serial number")] + public String MachineSerialNumber { get; set; } + + [Option(longName: "collection", HelpText = "Collection name")] + public String Collection { get; set; } + + [Option(longName: "key", HelpText = "Item key")] + public String Key { get; set; } + + [Option(longName: "value", HelpText = "Item value")] + public String Value { get; set; } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Program.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Program.cs new file mode 100644 index 000000000..e27f76c79 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Program.cs @@ -0,0 +1,49 @@ +using CommandLine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; + +namespace Tango.DataStore.CLI +{ + class Program + { + static void Main(string[] args) + { + var result = Parser.Default.ParseArguments(args) + .WithParsed((options) => + { + Console.WriteLine($"{options.Email}, {options.Password}"); + }) + .WithParsed((options) => + { + Console.WriteLine($"{options.Email}, {options.Password}"); + }) + .WithNotParsed((errors) => + { + + }); + + Console.ReadLine(); + } + + private static int DisplayHelp(ParserResult result, IEnumerable errs) + { + var helpText = CommandLine.Text.HelpText.AutoBuild(result, h => + { + h.AdditionalNewLineAfterOption = false; + h.AddNewLineBetweenHelpSections = true; + h.AddEnumValuesToHelpText = true; + h.AutoVersion = false; + h.Heading = CommandLine.Text.HeadingInfo.Empty; + h.MaximumDisplayWidth = 110; + // h.AddVerbs(typeof(SyncOptions), typeof(QueryOptions), typeof(TokenOptions)); + return h; // only h + }); + Console.WriteLine(helpText); + return 1; + } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..366b8e28e --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tango.DataStore.CLI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tango.DataStore.CLI")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6189b8c3-7af9-43dd-8a61-a8a05f526f62")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Tango.DataStore.CLI.csproj b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Tango.DataStore.CLI.csproj new file mode 100644 index 000000000..05e4022c4 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/Tango.DataStore.CLI.csproj @@ -0,0 +1,86 @@ + + + + + Debug + AnyCPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62} + Exe + Tango.DataStore.CLI + Tango.DataStore.CLI + v4.6.1 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\CommandLineParser.2.8.0\lib\net461\CommandLine.dll + + + ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + + + + + + + + + + + + + + + + + + + + + {F441FEEE-322A-4943-B566-110E12FD3B72} + Tango.BL + + + {5001990f-977b-48ff-b217-0236a5022ad8} + Tango.Web + + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/packages.config b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/packages.config new file mode 100644 index 000000000..71553e4ac --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.CLI/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreCollection.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreCollection.cs index 0baf5bb19..c42935368 100644 --- a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreCollection.cs +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreCollection.cs @@ -113,11 +113,20 @@ namespace Tango.DataStore.EF { using (var db = ObservablesContext.CreateDefault()) { - var items = db.DataStoreItems.Where(x => x.CollectionName == Name).ToList().Select(x => x.ToDataStoreItem()).ToList(); - var globalItems = db.GlobalDataStoreItems.Where(x => x.CollectionName == Name).ToList().Select(x => x.ToDataStoreItem()).ToList(); + var localItems = db.DataStoreItems.Where(x => x.CollectionName == Name).ToList(); + var globalItems = db.GlobalDataStoreItems.Where(x => x.CollectionName == Name).ToList(); + foreach (var globalItem in globalItems.ToList()) + { + var localItem = localItems.FirstOrDefault(x => x.CollectionName == globalItem.CollectionName && x.Key == globalItem.Key); + + if (localItem != null) + { + globalItems.Remove(globalItem); + } + } - return globalItems.Concat(items).ToList(); + return localItems.Select(x => x.ToDataStoreItem()).Concat(localItems.Select(x => x.ToDataStoreItem())).ToList(); } } diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs index 5aa7c5342..1a9dd324d 100644 --- a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs @@ -1,5 +1,6 @@ using Google.Protobuf; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -17,6 +18,7 @@ namespace Tango.DataStore { public class DataStoreProtoObject { + [JsonConverter(typeof(StringEnumConverter))] public MessageType MessageType { get; set; } public Type Type { get; set; } public byte[] Data { get; set; } diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index 3fe0dea56..9d2bb28c7 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -433,6 +433,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Remote", "D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Editing", "DataStore\Tango.DataStore.Editing\Tango.DataStore.Editing.csproj", "{EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.CLI", "DataStore\Tango.DataStore.CLI\Tango.DataStore.CLI.csproj", "{6189B8C3-7AF9-43DD-8A61-A8A05F526F62}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4080,6 +4082,26 @@ Global {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x64.Build.0 = Release|Any CPU {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x86.ActiveCfg = Release|Any CPU {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C}.Release|x86.Build.0 = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|ARM.Build.0 = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|ARM64.Build.0 = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|x64.ActiveCfg = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|x64.Build.0 = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|x86.ActiveCfg = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Debug|x86.Build.0 = Debug|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|Any CPU.Build.0 = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|ARM.ActiveCfg = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|ARM.Build.0 = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|ARM64.ActiveCfg = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|ARM64.Build.0 = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|x64.ActiveCfg = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|x64.Build.0 = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|x86.ActiveCfg = Release|Any CPU + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4229,14 +4251,15 @@ Global {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4} = {3F723D53-3539-42D1-8570-395BF660928D} {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA} = {3F723D53-3539-42D1-8570-395BF660928D} {EE088FF7-04D1-41FB-9D6A-CEDEEE7A7B9C} = {3F723D53-3539-42D1-8570-395BF660928D} + {6189B8C3-7AF9-43DD-8A61-A8A05F526F62} = {3F723D53-3539-42D1-8570-395BF660928D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - 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} + 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 EndGlobalSection EndGlobal diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs new file mode 100644 index 000000000..3deab9205 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http; +using Tango.BL.Entities; +using Tango.DataStore; +using Tango.DataStore.EF; +using Tango.MachineService.DataStore; +using Tango.Web.Helpers; + +namespace Tango.MachineService.Controllers +{ + public class DataStoreController : ApiController + { + private IDataStoreManager _manager; + + public DataStoreController() + { + _manager = new EFDataStoreManager(); + } + + public List Get(String sn = null, String collection = null, String key = null) + { + try + { + using (var db = ObservablesContextHelper.CreateContext()) + { + if (sn != null) + { + var machineGuid = db.Machines.Where(x => x.SerialNumber == sn).Select(x => x.Guid).FirstOrDefault(); + + if (machineGuid == null) + { + return ThrowException>(new KeyNotFoundException(), HttpStatusCode.NotFound, "The specified machine serial number could not be found."); + } + + var localItems = db.DataStoreItems.Where(x => x.MachineGuid == machineGuid && (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList(); + var globalItems = db.GlobalDataStoreItems.Where(x => (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList(); + + List finalList = new List(); + + foreach (var localItem in localItems) + { + var globalItem = globalItems.FirstOrDefault(x => x.CollectionName == localItem.CollectionName && x.Key == localItem.Key); + finalList.Add(localItem.ToWebItem(globalItem)); + globalItems.Remove(globalItem); + } + + finalList.AddRange(globalItems.Select(x => x.ToWebItem())); + + return finalList; + } + else + { + var globalItems = db.GlobalDataStoreItems.Where(x => (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList(); + + var finalList = globalItems.Select(x => x.ToWebItem()).ToList(); + + return finalList; + } + } + } + catch (Exception ex) + { + return ThrowException>(ex, HttpStatusCode.InternalServerError, ex.FlattenMessage()); + } + } + + public void Post([FromBody]string value) + { + + } + + public void Put(int id, [FromBody]string value) + { + + } + + private T ThrowException(Exception ex, HttpStatusCode code, String message = null) + { + throw new HttpResponseException(new HttpResponseMessage(code) + { + Content = new StringContent(message != null ? message : ex.Message), + ReasonPhrase = ex.FlattenMessage() + }); + } + } + + #region Extension Methods + + public static class IDataStoreExtensions + { + public static DataStoreWebItem ToWebItem(this DataStoreItem item, GlobalDataStoreItem globalItem = null) + { + IDataStoreItem dsItem = item.ToDataStoreItem(); + DataStoreWebItem webItem = new DataStoreWebItem(); + webItem.Collection = item.CollectionName; + webItem.Type = globalItem != null ? DataStoreWebItemType.Overrides : DataStoreWebItemType.Local; + webItem.DataType = dsItem.Type; + webItem.Date = dsItem.Date; + webItem.Key = dsItem.Key; + webItem.LocalValue = dsItem.Value; + + if (webItem.LocalValue is DataStoreProtoObject protoObject) + { + webItem.LocalValue = protoObject.Message; + webItem.ProtoMessageType = protoObject.MessageType; + } + + if (globalItem != null) + { + var dsGlobalItem = globalItem.ToDataStoreItem(); + + webItem.GlobalValue = dsGlobalItem.Value; + + if (webItem.GlobalValue is DataStoreProtoObject protoObjectGlobal) + { + webItem.GlobalValue = protoObjectGlobal.Message; + webItem.ProtoMessageType = protoObjectGlobal.MessageType; + } + } + + return webItem; + } + + public static DataStoreWebItem ToWebItem(this GlobalDataStoreItem item) + { + IDataStoreItem dsItem = item.ToDataStoreItem(); + DataStoreWebItem webItem = new DataStoreWebItem(); + webItem.Collection = item.CollectionName; + webItem.Type = DataStoreWebItemType.Global; + webItem.DataType = dsItem.Type; + webItem.Date = dsItem.Date; + webItem.Key = dsItem.Key; + webItem.GlobalValue = dsItem.Value; + + if (webItem.GlobalValue is DataStoreProtoObject protoObject) + { + webItem.GlobalValue = protoObject.Message; + webItem.ProtoMessageType = protoObject.MessageType; + } + + return webItem; + } + } + + #endregion +} diff --git a/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItem.cs b/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItem.cs new file mode 100644 index 000000000..ed8a8a385 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItem.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Tango.DataStore; +using Tango.PMR.Common; + +namespace Tango.MachineService.DataStore +{ + public class DataStoreWebItem + { + public String Collection { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public DataStoreWebItemType Type { get; set; } + public DateTime Date { get; set; } + public String Key { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public DataType DataType { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public MessageType ProtoMessageType { get; set; } + public Object LocalValue { get; set; } + public Object GlobalValue { get; set; } + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItemType.cs b/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItemType.cs new file mode 100644 index 000000000..0ba8e1a5e --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItemType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Tango.MachineService.DataStore +{ + public enum DataStoreWebItemType + { + Local, + Global, + Overrides + } +} \ 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 c662b1e87..bc60327ba 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -316,11 +316,14 @@ + + + @@ -402,6 +405,14 @@ + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + {d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f} Tango.FSE.Web @@ -490,7 +501,7 @@ False - + -- cgit v1.3.1 From 6f0f2a7908884deab8aca33ec967d03c5e564060 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 16 Nov 2020 18:32:04 +0200 Subject: Working on DataStore WebAPI. Modified data store bytes parsing to Base64. --- .../Tango.DataStore.EF/EFDataStoreHelper.cs | 16 +++- .../Tango.DataStore.EF/ExtensionMethods.cs | 9 ++- .../Tango.DataStore.Web/DataStoreWebHelper.cs | 16 ++++ .../Tango.DataStore.Web/DataStoreWebItem.cs | 26 +++++++ .../Tango.DataStore.Web/DataStoreWebItemType.cs | 14 ++++ .../Tango.DataStore.Web/DataStoreWebPutItem.cs | 28 +++++++ .../Tango.DataStore.Web/ExtensionMethods.cs | 12 +++ .../Tango.DataStore.Web/Properties/AssemblyInfo.cs | 36 +++++++++ .../Tango.DataStore.Web/Tango.DataStore.Web.csproj | 71 ++++++++++++++++++ .../DataStore/Tango.DataStore.Web/packages.config | 5 ++ .../DataStore/Tango.DataStore/DataStoreHelper.cs | 41 ++++------- .../Dialogs/DataStoreItemEditDialogViewVM.cs | 2 +- .../ViewModels/DataStoreViewVM.cs | 24 ++++-- .../ViewModels/SelectionViewVM.cs | 17 ++++- .../Views/SelectionView.xaml | 2 +- .../DataStore/DefaultDataStoreProvider.cs | 27 ++++++- .../DataStore/DefaultDataStoreService.cs | 33 +++++++++ Software/Visual_Studio/Tango.sln | 23 ++++++ .../Controllers/DataStoreController.cs | 85 ++++++++++++++++++++-- .../DataStore/DataStoreWebItem.cs | 26 ------- .../DataStore/DataStoreWebItemType.cs | 14 ---- .../Tango.MachineService.csproj | 6 +- 22 files changed, 441 insertions(+), 92 deletions(-) create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebHelper.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItem.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItemType.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebPutItem.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/ExtensionMethods.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/Tango.DataStore.Web.csproj create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore.Web/packages.config delete mode 100644 Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItem.cs delete mode 100644 Software/Visual_Studio/Web/Tango.MachineService/DataStore/DataStoreWebItemType.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreHelper.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreHelper.cs index 85b3b6731..5e885458b 100644 --- a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreHelper.cs +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/EFDataStoreHelper.cs @@ -89,11 +89,12 @@ namespace Tango.DataStore.EF }; } - public static DataStoreItem CreateDbDataStoreItem(IDataStoreItem item) + public static DataStoreItem CreateLocalDbDataStoreItem(IDataStoreItem item, String collection) { return new DataStoreItem() { Guid = item.Guid, + CollectionName = collection, LastUpdated = item.Date, IsSynchronized = item.IsSynchronized, Key = item.Key, @@ -101,5 +102,18 @@ namespace Tango.DataStore.EF Value = CreateBytes(item.Type, item.Value) }; } + + public static GlobalDataStoreItem CreateGlobalDbDataStoreItem(IDataStoreItem item, String collection) + { + return new GlobalDataStoreItem() + { + Guid = item.Guid, + CollectionName = collection, + LastUpdated = item.Date, + Key = item.Key, + DataType = (int)item.Type, + Value = CreateBytes(item.Type, item.Value) + }; + } } } diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/ExtensionMethods.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/ExtensionMethods.cs index 9f09ae658..6d45a69e7 100644 --- a/Software/Visual_Studio/DataStore/Tango.DataStore.EF/ExtensionMethods.cs +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.EF/ExtensionMethods.cs @@ -19,9 +19,14 @@ public static class ExtensionMethods return EFDataStoreHelper.CreateDataStoreItem(item); } - public static DataStoreItem ToDbDataStoreItem(this IDataStoreItem item) + public static DataStoreItem ToLocalDbDataStoreItem(this IDataStoreItem item, String collection) { - return EFDataStoreHelper.CreateDbDataStoreItem(item); + return EFDataStoreHelper.CreateLocalDbDataStoreItem(item, collection); + } + + public static GlobalDataStoreItem ToGlobalDbDataStoreItem(this IDataStoreItem item, String collection) + { + return EFDataStoreHelper.CreateGlobalDbDataStoreItem(item, collection); } } diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebHelper.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebHelper.cs new file mode 100644 index 000000000..2353a70fe --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebHelper.cs @@ -0,0 +1,16 @@ +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.DataStore.Web +{ + public static class DataStoreWebHelper + { + + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItem.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItem.cs new file mode 100644 index 000000000..a847517b1 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItem.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Tango.DataStore; +using Tango.PMR.Common; + +namespace Tango.DataStore.Web +{ + public class DataStoreWebItem + { + public String Collection { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public DataStoreWebItemType Type { get; set; } + public DateTime Date { get; set; } + public String Key { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public DataType DataType { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public MessageType ProtoMessageType { get; set; } + public Object LocalValue { get; set; } + public Object GlobalValue { get; set; } + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItemType.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItemType.cs new file mode 100644 index 000000000..684997bf4 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebItemType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Tango.DataStore.Web +{ + public enum DataStoreWebItemType + { + Local, + Global, + Overrides + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebPutItem.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebPutItem.cs new file mode 100644 index 000000000..6b897c82a --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/DataStoreWebPutItem.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Common; + +namespace Tango.DataStore.Web +{ + public class DataStoreWebPutItem + { + public String MachineSerialNumber { get; set; } + + public String Collection { get; set; } + + public String Key { get; set; } + + [JsonConverter(typeof(StringEnumConverter))] + public DataType DataType { get; set; } + + [JsonConverter(typeof(StringEnumConverter))] + public MessageType ProtoMessageType { get; set; } + + public Object Value { get; set; } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/ExtensionMethods.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/ExtensionMethods.cs new file mode 100644 index 000000000..a0959ae27 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/ExtensionMethods.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.Web +{ + public class ExtensionMethods + { + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Properties/AssemblyInfo.cs b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..27f57a100 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tango.DataStore.Web")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tango.DataStore.Web")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a9828548-af43-4ce4-8b13-50e99f9c9cf7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Tango.DataStore.Web.csproj b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Tango.DataStore.Web.csproj new file mode 100644 index 000000000..ac4e4a6f8 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/Tango.DataStore.Web.csproj @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + {A9828548-AF43-4CE4-8B13-50E99F9C9CF7} + Library + Properties + Tango.DataStore.Web + Tango.DataStore.Web + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore.Web/packages.config b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/packages.config new file mode 100644 index 000000000..026e719c3 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore.Web/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs index 0ca8e484e..0ceecd81b 100644 --- a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Tango.Core.ExtensionMethods; using Tango.PMR; @@ -84,7 +85,7 @@ namespace Tango.DataStore { if (item.Type == DataType.Bytes) { - return GetByteArrayHexString((byte[])item.Value); + return Convert.ToBase64String((byte[])item.Value); } else if (item.Type == DataType.Proto) { @@ -96,21 +97,6 @@ namespace Tango.DataStore } } - /// - /// Returns a byte array string representation in hex format. - /// - /// The data. - /// - public static String GetByteArrayHexString(byte[] data) - { - StringBuilder hex = new StringBuilder(); - foreach (byte b in data) - { - hex.Append(b.ToString("X2") + " "); - } - return hex.ToString(); - } - /// /// Parses a data store value from a string. /// @@ -141,20 +127,21 @@ namespace Tango.DataStore instance = instance.GetParser().ParseJson(text); return DataStoreProtoObject.FromMessage(instance); case DataType.Bytes: - string[] hexValuesSplit = text.Split(' '); - List bytes = new List(); - foreach (string hex in hexValuesSplit) - { - if (hex.IsNotNullOrEmpty()) - { - byte b = (byte)Convert.ToInt32(hex.Trim(), 16); - bytes.Add(b); - } - } - return bytes.ToArray(); + return Convert.FromBase64String(text); } throw new NotSupportedException("The specified data store type is not supported."); } + + /// + /// Validates the name of the collection or key. + /// + /// The name. + /// + public static bool ValidateCollectionOrKeyName(String name) + { + var regexItem = new Regex("^[a-zA-Z0-9_-]*$"); + return regexItem.IsMatch(name); + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs index 29ec03942..9cde14c6f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs @@ -143,7 +143,7 @@ namespace Tango.FSE.MachineConfiguration.Dialogs var bytes = File.ReadAllBytes(result.SelectedItem); Value = bytes; - _editingValue = DataStoreHelper.GetByteArrayHexString(bytes); + _editingValue = Convert.ToBase64String(bytes); RaisePropertyChanged(nameof(EditingValue)); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs index 7c1fae7ac..ef708afd3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -146,6 +146,11 @@ namespace Tango.FSE.MachineConfiguration.ViewModels return "The specified collection already exists."; } + if (!DataStoreHelper.ValidateCollectionOrKeyName(input)) + { + return "Collection name contains invalid characters."; + } + return null; }); @@ -176,14 +181,19 @@ namespace Tango.FSE.MachineConfiguration.ViewModels } var result = await NotificationProvider.ShowInputBox("Add Item", "Please enter the item key", MaterialDesignThemes.Wpf.PackIconKind.KeyAdd, null, null, 20, null, null, (input) => - { - if (SelectedCollection.Items.ToList().Exists(x => x.Key.ToLower() == input.ToLower())) - { - return "The specified key already exists in the collection."; - } + { + if (SelectedCollection.Items.ToList().Exists(x => x.Key.ToLower() == input.ToLower())) + { + return "The specified key already exists in the collection."; + } - return null; - }); + if (!DataStoreHelper.ValidateCollectionOrKeyName(input)) + { + return "Key name contains invalid characters."; + } + + return null; + }); if (result.Confirmed) { diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs index b65ad7102..39772a4cf 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/SelectionViewVM.cs @@ -19,7 +19,13 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public Machine SelectedMachine { get { return _selectedMachine; } - set { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + set + { + _selectedMachine = value; + RaisePropertyChangedAuto(); + InvalidateRelayCommands(); + OnSelectedMachineChanged(); + } } public RelayCommand ManageMachineCommand { get; set; } @@ -29,6 +35,15 @@ namespace Tango.FSE.MachineConfiguration.ViewModels ManageMachineCommand = new RelayCommand(ManageSelectedMachine, () => SelectedMachine != null); } + private async void OnSelectedMachineChanged() + { + if (SelectedMachine != null) + { + await Task.Delay(100); + this.SetFocus(() => ManageMachineCommand); + } + } + private void ManageSelectedMachine() { if (SelectedMachine == null) diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/SelectionView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/SelectionView.xaml index 69cebf324..51039ca89 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/SelectionView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/SelectionView.xaml @@ -49,7 +49,7 @@ -