Extract FirebaseRestTranslator into a nugget package

This commit is contained in:
Denis-Cosmin Nutiu 2020-03-07 16:37:14 +02:00
parent ac8f58df9a
commit f465cd4ad9
5 changed files with 3 additions and 486 deletions

View file

@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FirebaseRestTranslator" Version="0.1.1" />
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
<PackageReference Include="Grpc" Version="2.25.0" />
<PackageReference Include="Grpc.Tools" Version="2.25.0" />

View file

@ -64,7 +64,7 @@ namespace NucuCar.Domain.Telemetry
cts.CancelAfter(_timeout);
try
{
var data = FirebaseRestTranslator.Translate(null, GetTelemetry());
var data = FirebaseRestTranslator.Translator.Translate(null, GetTelemetry());
var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
await _httpClient.PostAsync("", content, cts.Token);
Logger?.LogInformation("Published data to Firestore!");

View file

@ -1,228 +0,0 @@
using System;
using System.Collections.Generic;
namespace NucuCar.Domain.Utilities
{
/// <summary>
/// This class is used to translate C# dictionaries into firebase json format.
/// </summary>
public static class FirebaseRestTranslator
{
public class ReferenceValue
{
private readonly string _value;
public ReferenceValue(string value)
{
_value = value;
}
public override string ToString()
{
return _value;
}
}
public class GeoPointValue
{
private readonly double _latitude;
private readonly double _longitude;
public GeoPointValue(double latitude, double longitude)
{
_latitude = latitude;
_longitude = longitude;
}
public Dictionary<string, object> ToValue()
{
return new Dictionary<string, object>
{
["latitude"] = _latitude,
["longitude"] = _longitude
};
}
}
public static Dictionary<string, object> Translate(string name, Dictionary<string, object> dict)
{
return BuildRoot(name, dict);
}
private static Dictionary<string, object> BuildRoot(string name, Dictionary<string, object> dict)
{
var root = new Dictionary<string, object>();
if (name != null)
{
root["name"] = name;
}
root["fields"] = new Dictionary<string, object>();
// iterate through fields and build leaf
foreach (var entry in dict)
{
var fields = (Dictionary<string, object>) root["fields"];
fields[entry.Key] = BuildNode(entry.Value);
}
return root;
}
private static Dictionary<string, object> BuildNode(object value)
{
switch (value)
{
case string v:
{
return BuildString(v);
}
case int v:
{
return BuildInteger(v);
}
case double v:
{
return BuildDouble(v);
}
case bool v:
{
return BuildBool(v);
}
case null:
{
return BuildNull(null);
}
case byte[] v:
{
return BuildBytes(v);
}
case DateTime v:
{
return BuildTimestamp(v);
}
case ReferenceValue v:
{
return BuildReference(v);
}
case GeoPointValue v:
{
return BuildGeoPoint(v);
}
case List<Dictionary<string, object>> v:
{
return BuildArray(v);
}
case Dictionary<string, object>[] v:
{
return BuildArray(new List<Dictionary<string, object>>(v));
}
case Dictionary<string, object> v:
{
return BuildMap(v);
}
default:
{
if (value.GetType().IsEnum)
{
return BuildInteger((int) value);
}
break;
}
}
throw new ArgumentException($"Can't build leaf! Unknown type for: {value}");
}
private static Dictionary<string, object> BuildSimpleValue(string type, object value)
{
return new Dictionary<string, object>()
{
[type] = value
};
}
private static Dictionary<string, object> BuildString(string value)
{
return BuildSimpleValue("stringValue", value);
}
private static Dictionary<string, object> BuildInteger(int value)
{
return BuildSimpleValue("integerValue", value);
}
private static Dictionary<string, object> BuildTimestamp(DateTime value)
{
return BuildSimpleValue("timestampValue", value);
}
private static Dictionary<string, object> BuildDouble(double value)
{
return BuildSimpleValue("doubleValue", value);
}
private static Dictionary<string, object> BuildBool(bool value)
{
return BuildSimpleValue("booleanValue", value);
}
private static Dictionary<string, object> BuildNull(object value)
{
return BuildSimpleValue("nullValue", value);
}
private static Dictionary<string, object> BuildBytes(byte[] value)
{
return BuildSimpleValue("bytesValue", Convert.ToBase64String(value));
}
private static Dictionary<string, object> BuildReference(ReferenceValue value)
{
return BuildSimpleValue("referenceValue", value.ToString());
}
private static Dictionary<string, object> BuildGeoPoint(GeoPointValue value)
{
return BuildSimpleValue("geoPointValue", value.ToValue());
}
private static Dictionary<string, object> BuildArray(List<Dictionary<string, object>> array)
{
var values = new List<Dictionary<string, object>>();
var root = new Dictionary<string, object>
{
["arrayValue"] = new Dictionary<string, object>
{
["values"] = values
}
};
foreach (var entry in array)
{
values.Add(BuildNode(entry));
}
return root;
}
private static Dictionary<string, object> BuildMap(Dictionary<string, object> map)
{
var fields = new Dictionary<string, object>();
var root = new Dictionary<string, object>
{
["mapValue"] = new Dictionary<string, object>
{
["fields"] = fields
}
};
foreach (var entry in map)
{
fields[entry.Key] = BuildNode(entry.Value);
}
return root;
}
}
}

View file

@ -1,257 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NucuCar.Domain.Utilities;
using Xunit;
using Xunit.Abstractions;
namespace NucuCar.UnitTests.NucuCar.Domain.Tests.Utilities
{
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
/*
{
"source":"NucuCar.Sensors",
"timestamp":"2019-12-01T23:26:13.5537227+02:00",
"data":[
{
"sensor_state":2,
"temperature":32.65558333857916,
"humidity":100.0,
"pressure":62228.49565168124,
"voc":0.0,
"_id":"Bme680-Sensor"
},
{
"sensor_state":2,
"cpu_temperature":48.849998474121094,
"_id":"CpuTemperature"
}
]
}
*/
public class FirebaseRestTranslatorTests
{
public FirebaseRestTranslatorTests(ITestOutputHelper testOutputHelper)
{
}
private Dictionary<string, object> getBasicTelemetryData()
{
var basicTelemetryDict = new Dictionary<string, object>
{
["source"] = "NucuCar.Sensors",
["timestamp"] = "2019-12-01T23:26:13.5537227+02:00"
};
var data = new List<Dictionary<string, object>>
{
new Dictionary<string, object>()
{
["sensor_state"] = 2,
["cpu_temperature"] = 48.849998474121094,
["_id"] = "CpuTemperature",
},
new Dictionary<string, object>()
{
["sensor_state"] = 2,
["temperature"] = 32.65,
["humidity"] = 100.0,
["pressure"] = 62228.49,
["voc"] = 0.0,
["_id"] = "Bme680-Sensor"
}
};
basicTelemetryDict["data"] = data;
return basicTelemetryDict;
}
[Fact]
public void Test_FirebaseTranslator_Parse()
{
var expectedJson =
"{\"name\":\"Test\",\"fields\":{\"source\":{\"stringValue\":\"NucuCar.Sensors\"},\"timestamp\":{\"stringValue\":\"2019-12-01T23:26:13.5537227+02:00\"},\"data\":{\"arrayValue\":{\"values\":[{\"mapValue\":{\"fields\":{\"sensor_state\":{\"integerValue\":2},\"cpu_temperature\":{\"doubleValue\":48.849998474121094},\"_id\":{\"stringValue\":\"CpuTemperature\"}}}},{\"mapValue\":{\"fields\":{\"sensor_state\":{\"integerValue\":2},\"temperature\":{\"doubleValue\":32.65},\"humidity\":{\"doubleValue\":100.0},\"pressure\":{\"doubleValue\":62228.49},\"voc\":{\"doubleValue\":0.0},\"_id\":{\"stringValue\":\"Bme680-Sensor\"}}}}]}}}}";
var basicTelemetryData = getBasicTelemetryData();
var result = FirebaseRestTranslator.Translate("Test", basicTelemetryData);
var json = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, json);
}
[Fact]
public void Test_FirebaseTranslator_StringValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = "myValue"
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator_StringValue\",\"fields\":{\"myKey\":{\"stringValue\":\"myValue\"}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator_StringValue", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_IntegerValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = 23
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"integerValue\":23}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_DoubleValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = 11.20
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"doubleValue\":11.2}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_BoolValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = false
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"booleanValue\":false}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_TimestampValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new DateTime(2020, 2, 29, 0, 0, 0, 0)
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"timestampValue\":\"2020-02-29T00:00:00\"}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_EnumValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = Season.Winter
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"integerValue\":3}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_ArrayValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["arrayIndex0"] = 11.20
},
new Dictionary<string, object>
{
["arrayIndex1"] = "test"
}
}
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"arrayValue\":{\"values\":[{\"mapValue\":{\"fields\":{\"arrayIndex0\":{\"doubleValue\":11.2}}}},{\"mapValue\":{\"fields\":{\"arrayIndex1\":{\"stringValue\":\"test\"}}}}]}}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_MapValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new Dictionary<string, object>
{
["stringKey"] = "test",
["boolKey"] = true,
["intKey"] = 99
}
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"mapValue\":{\"fields\":{\"stringKey\":{\"stringValue\":\"test\"},\"boolKey\":{\"booleanValue\":true},\"intKey\":{\"integerValue\":99}}}}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_NullValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = null
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"nullValue\":null}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_BytesValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new byte[] {97, 98, 99, 100, 101, 102, 103, 104, 105 }
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"bytesValue\":\"YWJjZGVmZ2hp\"}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_ReferenceValue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new FirebaseRestTranslator.ReferenceValue("test")
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"referenceValue\":\"test\"}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
[Fact]
public void Test_FirebaseTranslator_GeoPointvalue()
{
var data = new Dictionary<string, object>()
{
["myKey"] = new FirebaseRestTranslator.GeoPointValue(10, 22)
};
var expectedJson = "{\"name\":\"Test_FirebaseTranslator\",\"fields\":{\"myKey\":{\"geoPointValue\":{\"latitude\":10.0,\"longitude\":22.0}}}}";
var result = FirebaseRestTranslator.Translate("Test_FirebaseTranslator", data);
var actualJson = JsonConvert.SerializeObject(result);
Assert.Equal(expectedJson, actualJson);
}
}
}

View file

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;
&lt;Assembly Path="/home/denis/.nuget/packages/iot.device.bindings/1.0.0/lib/netcoreapp2.1/Iot.Device.Bindings.dll" /&gt;
&lt;Assembly Path="/home/denis/.nuget/packages/firebaseresttranslator/0.1.1/lib/netcoreapp3.0/FirebaseRestTranslator.dll" /&gt;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>