aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-10-24 06:40:07 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-10-24 06:40:07 +0300
commitadaddad79352c156303e9178a6f172a18af50cd2 (patch)
tree0ff2a59c3007bc9c40b7b543a9a2afe32dbc3d45
parent2d803e9410cd383d8e66c300f86fe0f7374c81ea (diff)
downloadTango-adaddad79352c156303e9178a6f172a18af50cd2.tar.gz
Tango-adaddad79352c156303e9178a6f172a18af50cd2.zip
Refactored DataStore Proto.
-rw-r--r--Software/PMR/Messages/DataStore/DataStoreItem.proto4
-rw-r--r--Software/PMR/Messages/DataStore/DataType.proto1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs27
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs14
-rw-r--r--Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs44
-rw-r--r--Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs14
-rw-r--r--Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj7
-rw-r--r--Software/Visual_Studio/Tango.DataStore.EF/packages.config1
-rw-r--r--Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreGetResponse.cs24
-rw-r--r--Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStoreItem.cs22
-rw-r--r--Software/Visual_Studio/Tango.DataStore.Remote/RemoteDataStorePutRequest.cs23
-rw-r--r--Software/Visual_Studio/Tango.DataStore.Remote/Tango.DataStore.Remote.csproj10
-rw-r--r--Software/Visual_Studio/Tango.DataStore.Remote/packages.config5
-rw-r--r--Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs70
-rw-r--r--Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs71
-rw-r--r--Software/Visual_Studio/Tango.DataStore/DataType.cs3
-rw-r--r--Software/Visual_Studio/Tango.DataStore/Tango.DataStore.csproj21
-rw-r--r--Software/Visual_Studio/Tango.DataStore/packages.config5
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs42
-rw-r--r--Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItem.cs48
-rw-r--r--Software/Visual_Studio/Tango.PMR/DataStore/DataType.cs7
-rw-r--r--Software/Visual_Studio/Tango.PMR/MessageFactory.cs32
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/DataStore/DataStore_TST.cs34
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj6
24 files changed, 484 insertions, 51 deletions
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<RemoteDataStorePutRequest, RemoteDataStorePutResponse>(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<RemoteDataStoreGetRequest, RemoteDataStoreGetResponse>(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>(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<T>(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 @@
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@@ -77,6 +80,10 @@
<Project>{e0364dfa-0721-4637-9d32-9d22aac109d6}</Project>
<Name>Tango.DataStore</Name>
</ProjectReference>
+ <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ 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 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.2.0" targetFramework="net461" />
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
</packages> \ 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<DataStoreProtoObject>());
+ }
+ 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 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -69,5 +75,9 @@
<Name>Tango.DataStore</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net461" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+</packages> \ 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
/// <param name="type">The type.</param>
/// <returns></returns>
/// <exception cref="System.NotSupportedException">The specified data type is not supported.</exception>
- 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.");
+ //}
/// <summary>
/// Formats the data store item as a string.
@@ -91,11 +107,7 @@ namespace Tango.DataStore
/// <returns></returns>
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<DataStoreProtoObject>(this);
+ }
+
+ public static DataStoreProtoObject FromBytes(byte[] data)
+ {
+ var instance = BsonConvert.Deserialize<DataStoreProtoObject>(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 @@
<DocumentationFile>bin\Release\Tango.DataStore.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -47,11 +53,26 @@
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="DataStoreHelper.cs" />
+ <Compile Include="DataStoreProtoObject.cs" />
<Compile Include="IDataStoreItem.cs" />
<Compile Include="DataType.cs" />
<Compile Include="IDataStoreCollection.cs" />
<Compile Include="IDataStoreManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{A34EE0F0-649D-41C8-8489-B6F1CC6924EE}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net461" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+</packages> \ 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<PutDataStoreItemRequest, PutDataStoreItemResponse>(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<GetDataStoreItemRequest, GetDataStoreItemResponse>(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 {
}
}
+ /// <summary>Field number for the "ProtoType" field.</summary>
+ public const int ProtoTypeFieldNumber = 20;
+ private global::Tango.PMR.Common.MessageType protoType_ = 0;
+ /// <summary>
+ ///Use only when DataType = Proto.
+ /// </summary>
+ [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;
@@ -37,6 +38,16 @@ namespace Tango.PMR
}
/// <summary>
+ /// Returns the matching PMR type from the PMR message type.
+ /// </summary>
+ /// <param name="messageType">Type of the message.</param>
+ /// <returns></returns>
+ public static Type GetPMRTypeFromMessageType(MessageType messageType)
+ {
+ return _pmrTypes[messageType];
+ }
+
+ /// <summary>
/// Creates a new <see cref="TangoMessage{T}"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
@@ -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();
}
+
+ /// <summary>
+ /// Parses the proto message from the specified bytes. Requires the message type.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ /// <param name="type">The type.</param>
+ /// <returns></returns>
+ 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<RemoteDataStoreGetResponse>(response, PMR.Integration.GenericMessageProtocol.Bson);
+
+ RemoteDataStoreGetResponse des = GenericMessageSerializer.Deserialize<RemoteDataStoreGetResponse>(data, PMR.Integration.GenericMessageProtocol.Bson);
+
+ CalculateRequest cc = des.ProtoObject.Message as CalculateRequest;
+
+ Assert.AreEqual<CalculateRequest>(calc, cc);
+ }
+
private void Run_Test(IDataStoreManager manager)
{
IDataStoreCollection collection = manager.GetCollection("TEST");
@@ -72,7 +96,13 @@ namespace Tango.UnitTesting.DataStore
Assert.AreEqual<byte>(value[0], 255);
}
- Assert.IsTrue(collection.Count() == 6);
+ {
+ collection.Put<CalculateRequest>("calc", new CalculateRequest() { A = 10, B = 15 });
+ CalculateRequest value = collection.Get<CalculateRequest>("calc");
+ Assert.AreEqual<CalculateRequest>(value, new CalculateRequest() { A = 10, B = 15 });
+ }
+
+ Assert.IsTrue(collection.Count() == 7);
Assert.ThrowsException<NotSupportedException>(() => collection.Put<DataStore_TST>("somekey", this));
@@ -82,7 +112,7 @@ namespace Tango.UnitTesting.DataStore
collection.Delete("float");
Assert.ThrowsException<KeyNotFoundException>(() => collection.Get<float>("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 @@
<Project>{fa96bc0c-4055-475c-9dcc-70a5a9436b10}</Project>
<Name>Tango.DataStore.Lite</Name>
</ProjectReference>
+ <ProjectReference Include="..\Tango.DataStore.Remote\Tango.DataStore.Remote.csproj">
+ <Project>{29448f3c-9b3e-4da6-8555-46a8b9a6b3aa}</Project>
+ <Name>Tango.DataStore.Remote</Name>
+ </ProjectReference>
<ProjectReference Include="..\Tango.DataStore\Tango.DataStore.csproj">
<Project>{e0364dfa-0721-4637-9d32-9d22aac109d6}</Project>
<Name>Tango.DataStore</Name>
@@ -319,7 +323,7 @@
<Import Project="..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets')" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file