Implement TelemetryPublisherFactory

This commit is contained in:
Denis-Cosmin Nutiu 2019-12-28 17:09:17 +02:00
parent 095da1faf2
commit 2d4d0b494a
8 changed files with 119 additions and 51 deletions

View file

@ -27,50 +27,6 @@ namespace NucuCar.Domain.Telemetry
Logger?.LogDebug("Initialized the AzureTelemetryPublisher!");
}
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">The device connection string for Microsoft Azure IoT hub device.</param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
return new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{ConnectionString = connectionString, TelemetrySource = "TelemetryPublisherAzure"});
}
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">Device connection string for Microsoft Azure IoT hub device.</param>
/// <param name="telemetrySource">String that is used to identify the source of the telemetry data.</param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString,
string telemetrySource)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
Guard.ArgumentNotNullOrWhiteSpace(nameof(telemetrySource), telemetrySource);
return new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{ConnectionString = connectionString, TelemetrySource = telemetrySource});
}
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">Device connection string for Microsoft Azure IoT hub device.</param>
/// <param name="telemetrySource">String that is used to identify the source of the telemetry data.</param>
/// <param name="logger">An <see cref="ILogger"/> logger instance. </param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString,
string telemetrySource, ILogger logger)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
Guard.ArgumentNotNullOrWhiteSpace(nameof(telemetrySource), telemetrySource);
Guard.ArgumentNotNull(nameof(logger), logger);
return new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{ConnectionString = connectionString, TelemetrySource = telemetrySource, Logger = logger});
}
public override async Task PublishAsync(CancellationToken cancellationToken)
{
var data = GetTelemetry();

View file

@ -0,0 +1,54 @@
using System;
using Microsoft.Extensions.Logging;
namespace NucuCar.Domain.Telemetry
{
/// <summary>
/// The TelemetryPublisherFactory is used instantiate TelemetryPublishers.
/// </summary>
public static class TelemetryPublisherFactory
{
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/>. See <see cref="TelemetryPublisherType"/>
/// </summary>
/// <param name="type">The type of the publisher. <see cref="TelemetryPublisherType"/> </param>
/// <param name="connectionString">Device connection string for Microsoft Azure IoT hub device.</param>
/// <param name="telemetrySource">String that is used to identify the source of the telemetry data.</param>
/// <param name="logger">An <see cref="ILogger"/> logger instance. </param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher Create(string type, string connectionString,
string telemetrySource, ILogger logger)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
Guard.ArgumentNotNullOrWhiteSpace(nameof(telemetrySource), telemetrySource);
Guard.ArgumentNotNull(nameof(logger), logger);
var opts = new TelemetryPublisherBuilderOptions()
{ConnectionString = connectionString, TelemetrySource = telemetrySource, Logger = logger};
return SpawnPublisher(type, opts);
}
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/>.
/// </summary>
/// <param name="type">The type of the publisher. See <see cref="TelemetryPublisherType"/> </param>
/// <param name="connectionString">The device connection string for the selected publisher.</param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string type, string connectionString)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
var opts = new TelemetryPublisherBuilderOptions()
{ConnectionString = connectionString, TelemetrySource = "TelemetryPublisherAzure"};
return SpawnPublisher(type, opts);
}
private static TelemetryPublisher SpawnPublisher(string type, TelemetryPublisherBuilderOptions opts)
{
return type switch
{
TelemetryPublisherType.Azure => (TelemetryPublisher) new TelemetryPublisherAzure(opts),
TelemetryPublisherType.Disk => new TelemetryPublisherDisk(opts),
_ => throw new ArgumentException($"Invalid TelemetryPublisher type: {type}.")
};
}
}
}

View file

@ -0,0 +1,12 @@
namespace NucuCar.Domain.Telemetry
{
/// <summary>
/// TelemetryPublisherType holds constants for instantiating <see cref="TelemetryPublisher"/>,
/// see <see cref="TelemetryPublisherFactory"/>.
/// </summary>
public static class TelemetryPublisherType
{
public const string Azure = "Azure";
public const string Disk = "Disk";
}
}

View file

@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NucuCar.Domain.Telemetry;
// ReSharper disable ClassWithVirtualMembersNeverInherited.Global
namespace NucuCar.Sensors.Telemetry
@ -11,14 +12,13 @@ namespace NucuCar.Sensors.Telemetry
public SensorTelemetry()
{
}
public SensorTelemetry(ILogger<SensorTelemetry> logger, IOptions<TelemetryConfig> options)
{
if (options.Value.ServiceEnabled)
{
Publisher = TelemetryPublisherAzure.CreateFromConnectionString(options.Value.ConnectionString,
Publisher = TelemetryPublisherFactory.Create(options.Value.Publisher, options.Value.ConnectionString,
"NucuCar.Sensors", logger);
}
else

View file

@ -1,9 +1,17 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
using NucuCar.Domain.Telemetry;
namespace NucuCar.Sensors.Telemetry
{
public class TelemetryConfig
{
/// <summary>
/// The Publisher is used by <see cref="TelemetryPublisherFactory"/> to instantiate
/// the correct <see cref="TelemetryPublisher"/>. For available types see <see cref="TelemetryPublisherType"/>
/// </summary>
public string Publisher { get; set; }
public bool ServiceEnabled { get; set; }
public int PublishInterval { get; set; }
public string ConnectionString { get; set; }

View file

@ -1,5 +1,6 @@
{
"Telemetry": {
"Publisher": "Azure",
"ServiceEnabled": true,
"PublishInterval": 3000,
"ConnectionString": "YOUR_CONNECTION_STRING"

View file

@ -48,10 +48,9 @@ namespace NucuCar.TestClient.Telemetry
var logger = LoggerFactory.Create(builder => { builder.AddConsole(); })
.CreateLogger<AzureTelemetryPublishCmd>();
var telemetryPublisher =
TelemetryPublisherAzure.CreateFromConnectionString(opts.PublisherConnectionString,
"NucuCar.TestClient", logger);
var telemetryPublisher = TelemetryPublisherFactory.Create(TelemetryPublisherType.Azure,
opts.PublisherConnectionString, "NucuCar.TestClient", logger);
var anonymousTelemeter =
new DummyTelemeter(
JsonConvert.DeserializeObject<Dictionary<string, object>>(opts.PublisherJsonMessage));

View file

@ -0,0 +1,38 @@
using System;
using NucuCar.Domain.Telemetry;
using Xunit;
namespace NucuCar.UnitTests.NucuCar.Domain.Tests.Telemetry
{
public class TelemetryPublisherFactoryTest
{
[Fact]
private void Test_Build_TelemetryPublisherAzure()
{
const string connectionString =
"HostName=something.azure-devices.net;DeviceId=something;SharedAccessKey=test";
var telemetryPublisher =
TelemetryPublisherFactory.CreateFromConnectionString(TelemetryPublisherType.Azure, connectionString);
Assert.IsType<TelemetryPublisherAzure>(telemetryPublisher);
}
[Fact]
private void Test_Build_TelemetryPublisherDisk()
{
const string connectionString =
"Filename=test;BufferSize=4096";
var telemetryPublisher =
TelemetryPublisherFactory.CreateFromConnectionString(TelemetryPublisherType.Disk, connectionString);
Assert.IsType<TelemetryPublisherDisk>(telemetryPublisher);
}
[Fact]
private void Test_Build_ThrowsOnInvalidType()
{
Assert.Throws<ArgumentException>(() =>
{
TelemetryPublisherFactory.CreateFromConnectionString("_1", "a=b");
});
}
}
}