-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add compSettings to pi-sense sample * upd trx in ci (#76) * upd trx in ci * upd trx to 2.2.1 * fix aws connect test * Feat/aws (#75) * add aws samples, and retries * get update shadow * revisit AWS impl * review aws sample * upd aws readme Co-authored-by: ridomin <[email protected]> * init WP from shadow * shadow versioning * rev v5 * clean warning Co-authored-by: rido-min <[email protected]>
- Loading branch information
Showing
31 changed files
with
442 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Connecting to AWS IoT Core | ||
|
||
AWS IoT Core requires X509 client certificates to connecto to the MQTT endpoint. | ||
|
||
These certificates can be self-signed or CA signed. | ||
|
||
Additionally you might need to create a Thing identity, or use a Provisioning template. | ||
|
||
https://docs.aws.amazon.com/iot/latest/developerguide/single-thing-provisioning.html | ||
|
||
https://docs.aws.amazon.com/iot/latest/developerguide/auto-register-device-cert.html | ||
|
||
https://aws.amazon.com/blogs/iot/just-in-time-registration-of-device-certificates-on-aws-iot/ | ||
|
||
As with any other MQTT broker, you can use WithConnectionSettings including the X509Key | ||
|
||
To support JIT, the first connection always fails and a retry is needed, in that case you can use the AwsClientFactory | ||
|
||
|
||
## Shadows | ||
|
||
To use shadows, you must configure a "thing", associate to a ceritifcate, and enable a classic shadow. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using MQTTnet.Extensions.MultiCloud; | ||
using MQTTnet.Extensions.MultiCloud.AwsIoTClient; | ||
using MQTTnet.Extensions.MultiCloud.Connections; | ||
|
||
namespace aws_sample | ||
{ | ||
public class Device : BackgroundService | ||
{ | ||
private readonly ILogger<Device> _logger; | ||
private readonly IConfiguration _configuration; | ||
|
||
public Device(ILogger<Device> logger, IConfiguration configuration) | ||
{ | ||
_logger = logger; | ||
_configuration = configuration; | ||
} | ||
|
||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) | ||
{ | ||
ConnectionSettings cs = new (_configuration.GetConnectionString("cs")); | ||
var mqtt = await AwsClientFactory.CreateFromConnectionSettingsAsync(cs, false, stoppingToken); | ||
Console.WriteLine(mqtt.IsConnected); | ||
Console.WriteLine(AwsClientFactory.ComputedSettings); | ||
var client = new AwsMqttClient(mqtt); | ||
var shadow = await client.GetShadowAsync(stoppingToken); | ||
Console.WriteLine(shadow); | ||
|
||
var res = await client.UpdateShadowAsync(new { myProp = "hello 123" }, stoppingToken); | ||
Console.WriteLine(res); | ||
shadow = await client.GetShadowAsync(stoppingToken); | ||
Console.WriteLine(shadow.Contains("myProp")); | ||
|
||
WritableProperty<string> wp = new(mqtt, "myWProp") | ||
{ | ||
OnMessage = async m => | ||
{ | ||
Console.WriteLine(m); | ||
return await Task.FromResult(new Ack<string> { Value = m }); | ||
} | ||
}; | ||
|
||
|
||
await wp.InitPropertyAsync(shadow, "my default val", stoppingToken); | ||
|
||
|
||
while (!stoppingToken.IsCancellationRequested) | ||
{ | ||
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); | ||
await Task.Delay(1000, stoppingToken); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using aws_sample; | ||
|
||
IHost host = Host.CreateDefaultBuilder(args) | ||
.ConfigureServices(services => | ||
{ | ||
services.AddHostedService<Device>(); | ||
}) | ||
.Build(); | ||
|
||
await host.RunAsync(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Worker"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<UserSecretsId>dotnet-aws_sample-7C0BD790-EA55-4969-A22F-6B86B301A627</UserSecretsId> | ||
<RootNamespace>aws_sample</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\MQTTnet.Extensions.MultiCloud.AwsIoTClient\MQTTnet.Extensions.MultiCloud.AwsIoTClient.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
58 changes: 47 additions & 11 deletions
58
src/MQTTnet.Extensions.MultiCloud.AwsIoTClient/AwsClientFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,64 @@ | ||
using MQTTnet.Client; | ||
using MQTTnet.Adapter; | ||
using MQTTnet.Client; | ||
using MQTTnet.Extensions.MultiCloud.Connections; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace MQTTnet.Extensions.MultiCloud.AwsIoTClient | ||
namespace MQTTnet.Extensions.MultiCloud.AwsIoTClient; | ||
|
||
public static class AwsClientFactory | ||
{ | ||
public static class AwsClientFactory | ||
{ | ||
public static string NuGetPackageVersion => $"{ThisAssembly.AssemblyName} {ThisAssembly.NuGetPackageVersion}"; | ||
public static ConnectionSettings? ComputedSettings { get; private set; } | ||
public static async Task<IMqttClient> CreateFromConnectionSettingsAsync(string connectinString, CancellationToken cancellationToken = default) => | ||
await CreateFromConnectionSettingsAsync(new ConnectionSettings(connectinString), cancellationToken); | ||
public static string NuGetPackageVersion => $"{ThisAssembly.AssemblyName} {ThisAssembly.NuGetPackageVersion}"; | ||
public static ConnectionSettings? ComputedSettings { get; private set; } | ||
|
||
public static async Task<IMqttClient> CreateFromConnectionSettingsAsync(ConnectionSettings cs, CancellationToken cancellationToken = default) | ||
public static async Task<IMqttClient> CreateFromConnectionSettingsAsync(string connectinString, bool withBirth = false, CancellationToken cancellationToken = default) => | ||
await CreateFromConnectionSettingsAsync(new ConnectionSettings(connectinString), withBirth, cancellationToken); | ||
|
||
public static async Task<IMqttClient> CreateFromConnectionSettingsAsync(ConnectionSettings cs, bool withBirth = false, CancellationToken cancellationToken = default) | ||
{ | ||
MqttClient? mqtt = new MqttFactory().CreateMqttClient(MqttNetTraceLogger.CreateTraceLogger()) as MqttClient; | ||
try | ||
{ | ||
MqttClient? mqtt = new MqttFactory().CreateMqttClient(MqttNetTraceLogger.CreateTraceLogger()) as MqttClient; | ||
var connAck = await mqtt!.ConnectAsync(new MqttClientOptionsBuilder().WithConnectionSettings(cs).Build(), cancellationToken); | ||
if (connAck.ResultCode != MqttClientConnectResultCode.Success) | ||
{ | ||
throw new ApplicationException($"Cannot connect to {cs}"); | ||
} | ||
ComputedSettings = cs; | ||
return mqtt; | ||
} | ||
catch (MqttConnectingFailedException ex) | ||
{ | ||
if (ex.ResultCode == MqttClientConnectResultCode.UnspecifiedError | ||
&& ex.InnerException!.Message == "The operation has timed out.") | ||
{ | ||
var connAck = await mqtt!.ConnectAsync(new MqttClientOptionsBuilder().WithConnectionSettings(cs).Build(), cancellationToken); | ||
if (connAck.ResultCode != MqttClientConnectResultCode.Success) | ||
{ | ||
throw new ApplicationException($"Cannot connect to {cs}"); | ||
} | ||
ComputedSettings = cs; | ||
} | ||
} | ||
|
||
if (withBirth) | ||
{ | ||
var birthPayload = new ShadowSerializer().ToBytes( | ||
new BirthConvention.BirthMessage(BirthConvention.ConnectionStatus.online) | ||
{ | ||
ModelId = cs.ModelId | ||
}); | ||
|
||
var pubAck = await mqtt.PublishBinaryAsync( | ||
BirthConvention.BirthTopic(mqtt!.Options.ClientId), | ||
birthPayload, | ||
Protocol.MqttQualityOfServiceLevel.AtLeastOnce, true, cancellationToken); | ||
if (pubAck.ReasonCode != MqttClientPublishReasonCode.Success) | ||
{ | ||
throw new ApplicationException($"Error publishing Birth {cs}"); | ||
} | ||
} | ||
|
||
return mqtt!; | ||
} | ||
} |
41 changes: 14 additions & 27 deletions
41
src/MQTTnet.Extensions.MultiCloud.AwsIoTClient/AwsMqttClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,25 @@ | ||
using MQTTnet.Client; | ||
using MQTTnet.Extensions.MultiCloud.AwsIoTClient.TopicBindings; | ||
using MQTTnet.Extensions.MultiCloud.Connections; | ||
using MQTTnet.Extensions.MultiCloud.Serializers; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace MQTTnet.Extensions.MultiCloud.AwsIoTClient | ||
{ | ||
public class AwsMqttClient | ||
{ | ||
public IMqttClient Connection { get; private set; } | ||
private readonly ShadowRequestResponseBinder getShadowBinder; | ||
|
||
namespace MQTTnet.Extensions.MultiCloud.AwsIoTClient; | ||
|
||
public AwsMqttClient(IMqttClient c, string modelId = "") //: base(c) | ||
{ | ||
Connection = c; | ||
var birthMsg = | ||
new UTF8JsonSerializer().ToBytes( | ||
new BirthConvention.BirthMessage(BirthConvention.ConnectionStatus.online) | ||
{ | ||
ModelId = modelId | ||
}); | ||
_ = Connection.PublishBinaryAsync( | ||
BirthConvention.BirthTopic(Connection.Options.ClientId), | ||
birthMsg, | ||
Protocol.MqttQualityOfServiceLevel.AtLeastOnce, true); | ||
public class AwsMqttClient | ||
{ | ||
public IMqttClient Connection { get; private set; } | ||
private readonly ShadowRequestResponseBinder getShadowBinder; | ||
|
||
getShadowBinder = new ShadowRequestResponseBinder(c); | ||
} | ||
|
||
public Task<string> GetShadowAsync(CancellationToken cancellationToken = default) => | ||
getShadowBinder.GetShadowAsync(cancellationToken); | ||
public Task<string> UpdateShadowAsync(object payload, CancellationToken cancellationToken = default) => | ||
getShadowBinder.UpdateShadowAsync(payload, cancellationToken); | ||
public AwsMqttClient(IMqttClient c) //: base(c) | ||
{ | ||
Connection = c; | ||
getShadowBinder = new ShadowRequestResponseBinder(c); | ||
} | ||
|
||
public Task<string> GetShadowAsync(CancellationToken cancellationToken = default) => | ||
getShadowBinder.GetShadowAsync(cancellationToken); | ||
public Task<string> UpdateShadowAsync(object payload, CancellationToken cancellationToken = default) => | ||
getShadowBinder.UpdateShadowAsync(payload, cancellationToken); | ||
} |
Oops, something went wrong.