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!"); 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) public override async Task PublishAsync(CancellationToken cancellationToken)
{ {
var data = GetTelemetry(); 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.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NucuCar.Domain.Telemetry; using NucuCar.Domain.Telemetry;
// ReSharper disable ClassWithVirtualMembersNeverInherited.Global // ReSharper disable ClassWithVirtualMembersNeverInherited.Global
namespace NucuCar.Sensors.Telemetry namespace NucuCar.Sensors.Telemetry
@ -11,14 +12,13 @@ namespace NucuCar.Sensors.Telemetry
public SensorTelemetry() public SensorTelemetry()
{ {
} }
public SensorTelemetry(ILogger<SensorTelemetry> logger, IOptions<TelemetryConfig> options) public SensorTelemetry(ILogger<SensorTelemetry> logger, IOptions<TelemetryConfig> options)
{ {
if (options.Value.ServiceEnabled) if (options.Value.ServiceEnabled)
{ {
Publisher = TelemetryPublisherAzure.CreateFromConnectionString(options.Value.ConnectionString, Publisher = TelemetryPublisherFactory.Create(options.Value.Publisher, options.Value.ConnectionString,
"NucuCar.Sensors", logger); "NucuCar.Sensors", logger);
} }
else else

View file

@ -1,9 +1,17 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
using NucuCar.Domain.Telemetry;
namespace NucuCar.Sensors.Telemetry namespace NucuCar.Sensors.Telemetry
{ {
public class TelemetryConfig 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 bool ServiceEnabled { get; set; }
public int PublishInterval { get; set; } public int PublishInterval { get; set; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }

View file

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

View file

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

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");
});
}
}
}