NUC-31: Finish working implementation for FirebaseRestTranslator
This commit is contained in:
parent
24e0630421
commit
ff492258a8
4 changed files with 50 additions and 23 deletions
|
@ -16,7 +16,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Cloud.Firestore" Version="1.1.0" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
|
||||
<PackageReference Include="Grpc" Version="2.25.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.25.0" />
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Cloud.Firestore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using NucuCar.Domain.Utilities;
|
||||
|
||||
namespace NucuCar.Domain.Telemetry
|
||||
|
@ -22,8 +24,7 @@ namespace NucuCar.Domain.Telemetry
|
|||
/// </summary>
|
||||
public class TelemetryPublisherFirestore : TelemetryPublisher
|
||||
{
|
||||
private readonly FirestoreDb _database;
|
||||
private readonly string _firestoreCollection;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly int _timeout;
|
||||
|
||||
public TelemetryPublisherFirestore(TelemetryPublisherBuilderOptions opts) : base(opts)
|
||||
|
@ -36,16 +37,19 @@ namespace NucuCar.Domain.Telemetry
|
|||
$"Missing ProjectId!");
|
||||
}
|
||||
|
||||
if (!options.TryGetValue("CollectionName", out _firestoreCollection))
|
||||
if (!options.TryGetValue("CollectionName", out var firestoreCollection))
|
||||
{
|
||||
Logger?.LogCritical(
|
||||
$"Can't start {nameof(TelemetryPublisherFirestore)}! Malformed connection string! " +
|
||||
$"Missing CollectionName!");
|
||||
}
|
||||
|
||||
_timeout = int.Parse(options.GetValueOrDefault("Timeout", "10000"));
|
||||
|
||||
|
||||
_database = FirestoreDb.Create(firestoreProjectId);
|
||||
var requestUrl = $"https://firestore.googleapis.com/v1/projects/{firestoreProjectId}/" +
|
||||
$"databases/(default)/documents/{firestoreCollection}/";
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.BaseAddress = new Uri(requestUrl);
|
||||
Logger?.LogInformation($"Initialized {nameof(TelemetryPublisherFirestore)}");
|
||||
}
|
||||
|
||||
|
@ -56,13 +60,13 @@ namespace NucuCar.Domain.Telemetry
|
|||
return;
|
||||
}
|
||||
|
||||
var docRef = _database.Collection(_firestoreCollection).Document();
|
||||
var data = GetTelemetry();
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(_timeout);
|
||||
try
|
||||
{
|
||||
await docRef.SetAsync(data, cancellationToken: cts.Token);
|
||||
var data = FirebaseRestTranslator.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!");
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -16,7 +16,11 @@ namespace NucuCar.Domain.Utilities
|
|||
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)
|
||||
|
@ -24,6 +28,7 @@ namespace NucuCar.Domain.Utilities
|
|||
var fields = (Dictionary<string, object>) root["fields"];
|
||||
fields[entry.Key] = BuildNode(entry.Value);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -33,10 +38,6 @@ namespace NucuCar.Domain.Utilities
|
|||
{
|
||||
case string v:
|
||||
{
|
||||
if (DateTime.TryParse(v, out _))
|
||||
{
|
||||
return BuildTimestamp(v);
|
||||
}
|
||||
return BuildString(v);
|
||||
}
|
||||
case int v:
|
||||
|
@ -51,16 +52,31 @@ namespace NucuCar.Domain.Utilities
|
|||
{
|
||||
return BuildBool(v);
|
||||
}
|
||||
case DateTime v:
|
||||
{
|
||||
return BuildTimestamp(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}");
|
||||
}
|
||||
|
||||
|
@ -71,26 +87,32 @@ namespace NucuCar.Domain.Utilities
|
|||
[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(string 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> BuildArray(List<Dictionary<string, object>> array)
|
||||
{
|
||||
var values = new List<Dictionary<string, object>>();
|
||||
|
@ -106,6 +128,7 @@ namespace NucuCar.Domain.Utilities
|
|||
{
|
||||
values.Add(BuildNode(entry));
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -123,6 +146,7 @@ namespace NucuCar.Domain.Utilities
|
|||
{
|
||||
fields[entry.Key] = BuildNode(entry.Value);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace NucuCar.UnitTests.NucuCar.Domain.Tests.Utilities
|
|||
public void Test_FireBaseTranslator_Parse()
|
||||
{
|
||||
var expectedJson =
|
||||
"{\"name\":\"Test\",\"fields\":{\"source\":{\"stringValue\":\"NucuCar.Sensors\"},\"timestamp\":{\"timestampValue\":\"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\"}}}}]}}}}";
|
||||
"{\"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);
|
||||
|
|
Loading…
Reference in a new issue