зеркало из https://github.com/Azure/TypeEdge.git
heavy refactoring abstracting modules
This commit is contained in:
Родитель
943c37a471
Коммит
5ef31acf4a
|
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27428.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThermpostatEdgeApplication", "ThermpostatEdgeApplication\ThermpostatEdgeApplication.csproj", "{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hub", "hub", "{34DAEE1A-E6E8-4059-9142-BF0170F3EAA8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.Devices.Edge.Hub.Amqp", "..\..\..\internal\Azure-IoT-Edge-Core\edge-hub\src\Microsoft.Azure.Devices.Edge.Hub.Amqp\Microsoft.Azure.Devices.Edge.Hub.Amqp.csproj", "{123E0E0F-3CAC-4095-B008-848F32A59C38}"
|
||||
|
@ -31,6 +29,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.Devices.Edg
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.IoT.TypeEdge", "Microsoft.Azure.IoT.TypeEdge\Microsoft.Azure.IoT.TypeEdge.csproj", "{54587D56-7C22-4084-9321-84D57C2F6ECB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ThermostatApplication", "ThermostatApplication", "{2E4AF4B3-04D0-4950-979B-B04052B8E20A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThermostatApplication.EdgeHost", "ThermostatApplication.EdgeHost\ThermostatApplication.EdgeHost.csproj", "{2C06F377-0612-431F-BA91-A2F5A561E789}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThermostatApplication.Shared", "ThermostatApplication.Shared\ThermostatApplication.Shared.csproj", "{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{40D0EFBC-3D80-42C8-9623-B9CAD4B96EFF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemperatureModule", "TemperatureModule\TemperatureModule.csproj", "{2B79BE65-8725-42FE-9F63-BC1797080E70}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NormalizeTemperatureModule", "NormalizeTemperatureModule\NormalizeTemperatureModule.csproj", "{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
|
@ -38,12 +48,6 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E41A1D9-FD4D-43BD-932A-D88459C7F4E5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{123E0E0F-3CAC-4095-B008-848F32A59C38}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{123E0E0F-3CAC-4095-B008-848F32A59C38}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{123E0E0F-3CAC-4095-B008-848F32A59C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -116,6 +120,30 @@ Global
|
|||
{54587D56-7C22-4084-9321-84D57C2F6ECB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -132,6 +160,11 @@ Global
|
|||
{FADB4DA5-7927-4505-AE23-09481B221FED} = {34DAEE1A-E6E8-4059-9142-BF0170F3EAA8}
|
||||
{6AF2C7B5-C749-47B0-BDE7-55F57C70E961} = {34DAEE1A-E6E8-4059-9142-BF0170F3EAA8}
|
||||
{4765DE78-0E50-4F41-9603-8B598A56D4C4} = {34DAEE1A-E6E8-4059-9142-BF0170F3EAA8}
|
||||
{2C06F377-0612-431F-BA91-A2F5A561E789} = {2E4AF4B3-04D0-4950-979B-B04052B8E20A}
|
||||
{CB2C4940-747F-4C45-9EA8-4C98F7F3AD41} = {2E4AF4B3-04D0-4950-979B-B04052B8E20A}
|
||||
{40D0EFBC-3D80-42C8-9623-B9CAD4B96EFF} = {2E4AF4B3-04D0-4950-979B-B04052B8E20A}
|
||||
{2B79BE65-8725-42FE-9F63-BC1797080E70} = {40D0EFBC-3D80-42C8-9623-B9CAD4B96EFF}
|
||||
{A55A00B6-BABA-414D-A38F-C4CAB4B9331B} = {40D0EFBC-3D80-42C8-9623-B9CAD4B96EFF}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {114E5850-267D-4B44-ACD5-91ACA382DDBC}
|
||||
|
|
|
@ -10,16 +10,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Hubs
|
|||
{
|
||||
public class EdgeHub : EdgeModule
|
||||
{
|
||||
public EdgeHub()
|
||||
{
|
||||
Upstream = new Upstream<JsonMessage>(this);
|
||||
Downstream = new Downstream<JsonMessage>(this);
|
||||
}
|
||||
public override string Name => Agent.Constants.EdgeHubModuleIdentityName;
|
||||
|
||||
public Upstream<JsonMessage> Upstream { get; set; }
|
||||
public Downstream<JsonMessage> Downstream { get; set; }
|
||||
|
||||
private IConfigurationRoot HubServiceConfiguration { get; set; }
|
||||
|
||||
public override CreationResult Configure(IConfigurationRoot configuration)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="4.8.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.2" />
|
||||
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="4.4.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Devices" Version="1.16.0-preview-003" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.1" />
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
using Castle.DynamicProxy;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge
|
||||
{
|
||||
internal class ModuleProxy: IInterceptor
|
||||
{
|
||||
public void Intercept(IInvocation invocation)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
||||
{
|
||||
public class EdgeMethodAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -29,11 +29,13 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
private ITransportSettings[] TransportSettings { get; set; }
|
||||
|
||||
private Dictionary<string, MessageCallback> Subscriptions { get; set; }
|
||||
public Upstream<JsonMessage> Upstream { get; set; }
|
||||
|
||||
public EdgeModule()
|
||||
{
|
||||
Subscriptions = new Dictionary<string, MessageCallback>();
|
||||
Routes = new List<string>();
|
||||
Upstream = new Upstream<JsonMessage>(this);
|
||||
|
||||
var props = GetType().GetProperties();
|
||||
|
||||
|
@ -56,6 +58,9 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
}
|
||||
public virtual string Name { get { return this.GetType().Name; } }
|
||||
|
||||
public virtual void ConfigureSubscriptions()
|
||||
{
|
||||
}
|
||||
public virtual CreationResult Configure(IConfigurationRoot configuration)
|
||||
{
|
||||
return CreationResult.OK;
|
||||
|
@ -155,7 +160,6 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
|
||||
public Output<DiagnosticsMessage> DiagnosticsOutput { get; set; }
|
||||
|
||||
|
||||
public void DependsOn(EdgeModule module)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
||||
{
|
||||
public class EdgeModuleProxy<T>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
{
|
||||
public string Name { get; set; }
|
||||
public abstract string RouteName { get; }
|
||||
public EdgeModule Module { get; set; }
|
||||
internal EdgeModule Module { get; set; }
|
||||
|
||||
public Endpoint(string name, EdgeModule module)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
||||
{
|
||||
public class MethodArgument
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
||||
{
|
||||
public enum MethodResult
|
||||
{
|
||||
OK,
|
||||
Error
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
}
|
||||
public override string RouteName => $"/messages/modules/{this.Module.Name}/outputs/{Name}";
|
||||
|
||||
public string ModuleName { get { return Module.Name; } }
|
||||
|
||||
public async Task<PublishResult> PublishAsync(T message)
|
||||
{
|
||||
|
|
|
@ -19,65 +19,91 @@ using Microsoft.Azure.Devices.Common.Exceptions;
|
|||
using Newtonsoft.Json;
|
||||
using Microsoft.Azure.Devices.Shared;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Linq;
|
||||
using Autofac.Extras.DynamicProxy;
|
||||
using Castle.DynamicProxy;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge
|
||||
{
|
||||
public abstract class TypeEdgeApplication
|
||||
public class TypeEdgeApplication
|
||||
{
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
public IContainer Container { get; private set; }
|
||||
IConfigurationRoot configuration;
|
||||
IContainer container;
|
||||
ContainerBuilder containerBuilder;
|
||||
ModuleCollection modules;
|
||||
EdgeHub hub;
|
||||
|
||||
public void RegisterModule<_IModule, _TModule>()
|
||||
where _IModule : class
|
||||
where _TModule : class
|
||||
{
|
||||
//containerBuilder.RegisterType<_TModule>();
|
||||
//containerBuilder.RegisterInstance(new ProxyGenerator().CreateInterfaceProxyWithoutTarget<_IModule>(new ModuleProxy()) as _IModule);
|
||||
containerBuilder.RegisterType<_TModule>().AsSelf().As<_IModule>();
|
||||
}
|
||||
|
||||
public EdgeHub Hub { get; set; }
|
||||
public ModuleCollection Modules { get; private set; }
|
||||
|
||||
public TypeEdgeApplication(IConfigurationRoot configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
this.configuration = configuration;
|
||||
this.containerBuilder = new ContainerBuilder();
|
||||
hub = new EdgeHub();
|
||||
|
||||
// add the framework services
|
||||
var services = new ServiceCollection().AddLogging();
|
||||
}
|
||||
public void Build()
|
||||
{
|
||||
//read the configuration first
|
||||
var (iotHubConnectionString, deviceId) = ReadConfiguration();
|
||||
|
||||
Modules = new ModuleCollection();
|
||||
//setup the container
|
||||
BuildContainer();
|
||||
|
||||
Hub = new EdgeHub();
|
||||
this.modules = CreateModules();
|
||||
|
||||
Compose();
|
||||
var deviceSasKey = ProvisionDeviceAsync(iotHubConnectionString, deviceId, this.modules).Result;
|
||||
|
||||
Container = BuildContainer(services);
|
||||
ConfigureModules(iotHubConnectionString, deviceId);
|
||||
|
||||
BuildHub(iotHubConnectionString, deviceId, deviceSasKey);
|
||||
}
|
||||
|
||||
IContainer BuildContainer(IServiceCollection services)
|
||||
#region Build
|
||||
private void BuildContainer()
|
||||
{
|
||||
var builder = new ContainerBuilder();
|
||||
builder.Populate(services);
|
||||
builder.RegisterBuildCallback(c => { });
|
||||
var services = new ServiceCollection().AddLogging();
|
||||
containerBuilder.Populate(services);
|
||||
containerBuilder.RegisterBuildCallback(c => { });
|
||||
|
||||
var iotHubConnectionString = Configuration.GetValue<string>(Agent.Constants.IotHubConnectionStringKey);
|
||||
container = containerBuilder.Build();
|
||||
}
|
||||
|
||||
private (string iotHubConnectionString, string deviceId) ReadConfiguration()
|
||||
{
|
||||
var iotHubConnectionString = configuration.GetValue<string>(Agent.Constants.IotHubConnectionStringKey);
|
||||
if (String.IsNullOrEmpty(iotHubConnectionString))
|
||||
throw new Exception($"Missing {Agent.Constants.IotHubConnectionStringKey} value in configuration");
|
||||
|
||||
var deviceId = Configuration.GetValue<string>("DeviceId");
|
||||
var deviceId = configuration.GetValue<string>("DeviceId");
|
||||
if (String.IsNullOrEmpty(deviceId))
|
||||
throw new Exception($"Missing DeviceId value in configuration");
|
||||
|
||||
#region edge hub config
|
||||
return (iotHubConnectionString, deviceId);
|
||||
}
|
||||
|
||||
//configure the edge hub
|
||||
private void BuildHub(string iotHubConnectionString, string deviceId, string deviceSasKey)
|
||||
{
|
||||
//Calculate the Hub Enviroment Varialbes
|
||||
var currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
Environment.SetEnvironmentVariable(HubService.Constants.SslCertEnvName,
|
||||
"edge-hub-server.cert.pfx");
|
||||
Environment.SetEnvironmentVariable(HubService.Constants.SslCertPathEnvName,
|
||||
Path.Combine(currentLocation, @"Certificates\edge-hub-server\cert\"));
|
||||
|
||||
Environment.SetEnvironmentVariable(HubService.Constants.SslCertEnvName, "edge-hub-server.cert.pfx");
|
||||
Environment.SetEnvironmentVariable(HubService.Constants.SslCertPathEnvName, Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
|
||||
@"Certificates\edge-hub-server\cert\"));
|
||||
|
||||
Environment.SetEnvironmentVariable("EdgeModuleHubServerCAChainCertificateFile", Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
|
||||
@"Certificates\edge-chain-ca\cert\edge-chain-ca.cert.pem"));
|
||||
|
||||
var storageFolder = Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
|
||||
@"Storage");
|
||||
Environment.SetEnvironmentVariable("EdgeModuleHubServerCAChainCertificateFile",
|
||||
Path.Combine(currentLocation, @"Certificates\edge-chain-ca\cert\edge-chain-ca.cert.pem"));
|
||||
|
||||
var storageFolder = Path.Combine(currentLocation, @"Storage");
|
||||
|
||||
var hubStorageFolder = Path.Combine(storageFolder, HubService.Constants.EdgeHubStorageFolder);
|
||||
|
||||
|
@ -85,23 +111,6 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
Directory.CreateDirectory(hubStorageFolder);
|
||||
|
||||
Environment.SetEnvironmentVariable("storageFolder", storageFolder);
|
||||
#endregion
|
||||
|
||||
|
||||
var deviceSasKey = ProvisionDeviceAsync(iotHubConnectionString, deviceId, Modules).Result;
|
||||
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
var moduleConnectionString = GetModuleConnectionStringAsync(iotHubConnectionString, deviceId, module.Name).Result;
|
||||
|
||||
Environment.SetEnvironmentVariable(Agent.Constants.EdgeHubConnectionStringKey, moduleConnectionString);
|
||||
|
||||
var moduleConfiguration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
module.InternalConfigure(moduleConfiguration);
|
||||
}
|
||||
|
||||
var csBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString);
|
||||
var edgeConnectionString = new Agent.ModuleConnectionString.ModuleConnectionStringBuilder(csBuilder.HostName, deviceId)
|
||||
|
@ -116,12 +125,43 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
Hub.InternalConfigure(edgeHubConfiguration);
|
||||
|
||||
|
||||
IContainer container = builder.Build();
|
||||
return container;
|
||||
hub.InternalConfigure(edgeHubConfiguration);
|
||||
}
|
||||
|
||||
private void ConfigureModules(string iotHubConnectionString, string deviceId)
|
||||
{
|
||||
foreach (var module in this.modules)
|
||||
{
|
||||
var moduleConnectionString = GetModuleConnectionStringAsync(iotHubConnectionString, deviceId, module.Name).Result;
|
||||
|
||||
Environment.SetEnvironmentVariable(Agent.Constants.EdgeHubConnectionStringKey, moduleConnectionString);
|
||||
|
||||
var moduleConfiguration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
module.InternalConfigure(moduleConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleCollection CreateModules()
|
||||
{
|
||||
var modules = new ModuleCollection();
|
||||
using (var scope = container.BeginLifetimeScope())
|
||||
{
|
||||
foreach (var moduleType in container.ComponentRegistry.Registrations.Where(r => typeof(EdgeModule).IsAssignableFrom(r.Activator.LimitType)).Select(r => r.Activator.LimitType).Distinct())
|
||||
{
|
||||
var module = scope.Resolve(moduleType) as EdgeModule;
|
||||
|
||||
module.ConfigureSubscriptions();
|
||||
modules.Add(module);
|
||||
}
|
||||
}
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
|
||||
private async Task<string> ProvisionDeviceAsync(string iotHubConnectionString, string deviceId, ModuleCollection modules)
|
||||
{
|
||||
var csBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString);
|
||||
|
@ -157,19 +197,26 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
createOptions = $" -e __MODULE_NAME='{module.Name}' "
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await registryManager.AddModuleAsync(new Devices.Module(deviceId, module.Name));
|
||||
}
|
||||
catch (ModuleAlreadyExistsException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
var twinContent = new TwinContent();
|
||||
config.ModuleContent["$edgeHub"] = twinContent;
|
||||
|
||||
|
||||
var routes = new Dictionary<string, string>();
|
||||
foreach (var route in Hub.Routes)
|
||||
foreach (var route in hub.Routes)
|
||||
{
|
||||
routes[$"route{routes.Count}"] = route;
|
||||
}
|
||||
foreach (var module in Modules)
|
||||
foreach (var module in this.modules)
|
||||
{
|
||||
foreach (var route in module.Routes)
|
||||
{
|
||||
|
@ -219,43 +266,18 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
.WithSharedAccessKey(sasKey)
|
||||
.Build();
|
||||
}
|
||||
|
||||
//private async Task<string> ProvisionModuleAsync(string iotHubConnectionString, string deviceId, string moduleName)
|
||||
//{
|
||||
// var csBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString);
|
||||
// RegistryManager registryManager = RegistryManager.CreateFromConnectionString(iotHubConnectionString);
|
||||
// string sasKey = null;
|
||||
// try
|
||||
// {
|
||||
// var module = await registryManager.AddModuleAsync(new Devices.Module(deviceId, moduleName));
|
||||
// sasKey = module.Authentication.SymmetricKey.PrimaryKey;
|
||||
// }
|
||||
// catch (ModuleAlreadyExistsException)
|
||||
// {
|
||||
// var module = await registryManager.GetModuleAsync(deviceId, moduleName);
|
||||
// sasKey = module.Authentication.SymmetricKey.PrimaryKey;
|
||||
// }
|
||||
// return new Agent.ModuleConnectionString.ModuleConnectionStringBuilder(csBuilder.IotHubName, deviceId)
|
||||
// .WithGatewayHostName(Environment.MachineName)
|
||||
// .WithModuleId(moduleName)
|
||||
// .WithSharedAccessKey(sasKey)
|
||||
// .Build();
|
||||
//}
|
||||
public abstract CompositionResult Compose();
|
||||
#endregion
|
||||
|
||||
public async Task RunAsync()
|
||||
{
|
||||
List<Task> tasks = new List<Task>();
|
||||
|
||||
tasks.Add(Hub.RunAsync());
|
||||
tasks.Add(hub.RunAsync());
|
||||
//start all modules
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
foreach (var module in modules)
|
||||
tasks.Add(module.InternalRunAsync());
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks.ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using ThermostatApplication;
|
||||
using ThermostatApplication.Messages;
|
||||
using ThermostatApplication.Modules;
|
||||
|
||||
namespace Modules
|
||||
{
|
||||
public class NormalizeTemperatureModule : EdgeModule, INormalizeTemperatureModule
|
||||
{
|
||||
ITemperatureModule temperatureModuleProxy;
|
||||
|
||||
public Input<TemperatureModuleOutput> Temperature { get; set; }
|
||||
public Output<TemperatureModuleOutput> NormalizedTemperature { get; set; }
|
||||
|
||||
public NormalizeTemperatureModule(ITemperatureModule proxy)
|
||||
{
|
||||
temperatureModuleProxy = proxy;
|
||||
}
|
||||
|
||||
public override void ConfigureSubscriptions() {
|
||||
|
||||
Temperature.Subscribe(temperatureModuleProxy.Temperature, async (temp) =>
|
||||
{
|
||||
if (temp.Scale == TemperatureScale.Celsius)
|
||||
temp.Temperature = temp.Temperature * 9 / 5 + 32;
|
||||
|
||||
await NormalizedTemperature.PublishAsync(temp);
|
||||
|
||||
return MessageResult.OK;
|
||||
});
|
||||
|
||||
Upstream.Subscribe(NormalizedTemperature);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Azure.IoT.TypeEdge\Microsoft.Azure.IoT.TypeEdge.csproj" />
|
||||
<ProjectReference Include="..\ThermostatApplication.Shared\ThermostatApplication.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,15 +1,15 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ThermostatApplication;
|
||||
using ThermostatApplication.Messages;
|
||||
using ThermostatApplication.Modules;
|
||||
|
||||
namespace ThermpostatEdgeApplication.Modules
|
||||
namespace Modules
|
||||
{
|
||||
public class TemperatureModule : EdgeModule
|
||||
public class TemperatureModule : EdgeModule, ITemperatureModule
|
||||
{
|
||||
public Output<TemperatureModuleOutput> Temperature { get; set; }
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Azure.IoT.TypeEdge\Microsoft.Azure.IoT.TypeEdge.csproj" />
|
||||
<ProjectReference Include="..\ThermostatApplication.Shared\ThermostatApplication.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,30 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Modules;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ThermostatApplication.Modules;
|
||||
|
||||
namespace ThermostatApplication.EdgeHost
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings_thermostat.json")
|
||||
.Build();
|
||||
|
||||
var edgeApp = new TypeEdgeApplication(configuration);
|
||||
|
||||
edgeApp.RegisterModule<ITemperatureModule, TemperatureModule>();
|
||||
edgeApp.RegisterModule<INormalizeTemperatureModule, NormalizeTemperatureModule>();
|
||||
edgeApp.Build();
|
||||
|
||||
await edgeApp.RunAsync();
|
||||
|
||||
Console.WriteLine("Press <ENTER> to exit..");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0-rc1-final" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Azure.IoT.TypeEdge\Microsoft.Azure.IoT.TypeEdge.csproj" />
|
||||
<ProjectReference Include="..\NormalizeTemperatureModule\NormalizeTemperatureModule.csproj" />
|
||||
<ProjectReference Include="..\TemperatureModule\TemperatureModule.csproj" />
|
||||
<ProjectReference Include="..\ThermostatApplication.Shared\ThermostatApplication.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings_thermostat.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -2,6 +2,6 @@
|
|||
"appSettings": {
|
||||
},
|
||||
"iotHubConnectionString": "HostName=iotedgedev-iothub-7389d7.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=68K3zvI8CKbN7NM5s46N9rlP+zvPHPJKg7shy1rwMRU=",
|
||||
"deviceId": "iotedgedev-edgedevice-new",
|
||||
"deviceId": "type-edge-dev-device",
|
||||
"RuntimeLogLevel": "info"
|
||||
}
|
|
@ -5,7 +5,7 @@ using Microsoft.Azure.IoT.TypeEdge.Hubs;
|
|||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
namespace ThermostatApplication.Messages
|
||||
{
|
||||
public class TemperatureModuleInput : IEdgeMessage
|
||||
{
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
namespace ThermostatApplication.Messages
|
||||
{
|
||||
public class TemperatureModuleOutput : IEdgeMessage
|
||||
{
|
|
@ -0,0 +1,10 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using ThermostatApplication.Messages;
|
||||
|
||||
namespace ThermostatApplication.Modules
|
||||
{
|
||||
public interface INormalizeTemperatureModule
|
||||
{
|
||||
Output<TemperatureModuleOutput> NormalizedTemperature { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.IoT.TypeEdge;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Hubs;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using ThermostatApplication.Messages;
|
||||
|
||||
namespace ThermostatApplication.Modules
|
||||
{
|
||||
public interface ITemperatureModule
|
||||
{
|
||||
Output<TemperatureModuleOutput> Temperature { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace ThermpostatEdgeApplication
|
||||
namespace ThermostatApplication
|
||||
{
|
||||
public enum TemperatureScale
|
||||
{
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -14,10 +12,4 @@
|
|||
<ProjectReference Include="..\Microsoft.Azure.IoT.TypeEdge\Microsoft.Azure.IoT.TypeEdge.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings_thermostat.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,19 +0,0 @@
|
|||
using Autofac;
|
||||
using Microsoft.Azure.IoT.TypeEdge;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ThermpostatEdgeApplication.Modules
|
||||
{
|
||||
public class NormalizeTemperatureModule : EdgeModule
|
||||
{
|
||||
|
||||
public Input<TemperatureModuleOutput> Temperature { get; set; }
|
||||
public Output<TemperatureModuleOutput> NormalizedTemperature { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
{
|
||||
public class NormalizeTemperatureOptions : IModuleOptions
|
||||
{
|
||||
public string DeviceConnectionString { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
{
|
||||
public class ReadTemperatureOptions : IModuleOptions
|
||||
{
|
||||
public string DeviceConnectionString { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings_thermostat.json")
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
var edgeApp = new ThermostatApplication(configuration);
|
||||
|
||||
await edgeApp.RunAsync();
|
||||
|
||||
Console.WriteLine("Press <ENTER> to exit..");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
using Microsoft.Azure.IoT.TypeEdge;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Hubs;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using ThermpostatEdgeApplication.Modules;
|
||||
|
||||
namespace ThermpostatEdgeApplication
|
||||
{
|
||||
public class ThermostatApplication : TypeEdgeApplication
|
||||
{
|
||||
public ThermostatApplication(IConfigurationRoot configuration)
|
||||
: base(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
public override CompositionResult Compose()
|
||||
{
|
||||
//setup modules
|
||||
var temperatureModule = new TemperatureModule();
|
||||
var normalizeTemperatureModule = new NormalizeTemperatureModule();
|
||||
|
||||
Modules.Add(temperatureModule);
|
||||
Modules.Add(normalizeTemperatureModule);
|
||||
|
||||
//setup the modules pub/sub
|
||||
temperatureModule.DefaultInput.Subscribe(Hub.Downstream, async (msg) => { return MessageResult.OK; });
|
||||
|
||||
normalizeTemperatureModule.Temperature.Subscribe(temperatureModule.Temperature, async (temp) =>
|
||||
{
|
||||
if (temp.Scale == TemperatureScale.Celsius)
|
||||
temp.Temperature = temp.Temperature * 9 / 5 + 32;
|
||||
|
||||
await normalizeTemperatureModule.NormalizedTemperature.PublishAsync(temp);
|
||||
|
||||
return MessageResult.OK;
|
||||
});
|
||||
|
||||
Hub.Upstream.Subscribe(normalizeTemperatureModule.NormalizedTemperature);
|
||||
|
||||
//setup module startup depedencies
|
||||
normalizeTemperatureModule.DependsOn(temperatureModule);
|
||||
|
||||
return CompositionResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче