зеркало из https://github.com/Azure/TypeEdge.git
container debugging
This commit is contained in:
Родитель
f4e393c8d2
Коммит
ea95640c2a
|
@ -1 +1 @@
|
|||
DOCKER_REGISTRY=typeedge.azurecr.io/
|
||||
DOCKER_REGISTRY=typeedge.azurecr.io/
|
|
@ -13,7 +13,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" Condition="'$(Configuration)|$(Platform)'!='TemplateDevelopment|AnyCPU'" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Modules
|
|||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
await Startup.DockerEntryPoint(args);
|
||||
await Startup.DockerEntryPoint(args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"profiles": {
|
||||
"NormalizeTemperatureModule": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ModuleName": "normalizetemperaturemodule"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"profiles": {
|
||||
"TemperatureModule": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ModuleName": "Temperature"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" Condition="'$(Configuration)|$(Platform)'!='TemplateDevelopment|AnyCPU'" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -4,7 +4,7 @@ using Microsoft.Azure.IoT.TypeEdge.Host;
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Modules;
|
||||
using ThermostatApplication.Modules;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Host.DovEnv;
|
||||
using Microsoft.Azure.IoT.TypeEdge.DovEnv;
|
||||
|
||||
namespace ThermostatApplication
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.26" Condition="'$(Configuration)|$(Platform)'!='TemplateDevelopment|AnyCPU'" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.48" />
|
||||
<PackageReference Include="rocksdb-native-arm" Version="5.4.6" />
|
||||
<PackageReference Include="RocksDbNative" Version="5.4.6.10" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
"TypeEdgeHost": {
|
||||
"IotHubConnectionString": "HostName=iotedgedev-iothub-7389d7.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=UqshG8knBj9ZG5J8tM9S7rTSQI4Ho1L5eWPz3Subkbo=",
|
||||
"DeviceId": "type-edge-dev8",
|
||||
"PrintDeploymentJson": "true"
|
||||
"PrintDeploymentJson": "true"
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.26" Condition="'$(Configuration)|$(Platform)'!='TemplateDevelopment|AnyCPU'" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" Condition="'$(Configuration)|$(Platform)'!='TemplateDevelopment|AnyCPU'" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
@echo off
|
||||
IF "%1"=="" GOTO HAVE_USERNAME
|
||||
IF "%2"=="" GOTO HAVE_PASSWORD
|
||||
|
||||
|
||||
if exist nuget.exe (
|
||||
echo nuget.exe found
|
||||
) else (
|
||||
echo downloading nuget.exe from https://www.nuget.org/nuget.exe
|
||||
|
||||
Powershell.exe wget -outf nuget.exe https://nuget.org/nuget.exe
|
||||
if not exist .\nuget.exe (
|
||||
echo Error: nuget does not exist.
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
echo Adding the private nuget packages feed "private-typeedge-feed"
|
||||
nuget.exe sources Add -Name "private-typeedge-feed" -Source "https://msblox-03.pkgs.visualstudio.com/_packaging/private-nuget-feed/nuget/v3/index.json" -StorePasswordInClearText -ConfigFile NuGet.Config -UserName "%1" -Password "%2"
|
||||
|
||||
if errorlevel 1 (
|
||||
echo Failed, trying to remove an existing record first ..
|
||||
echo Removing the private "private-typeedge-feed" ..
|
||||
nuget.exe sources Remove -Name "private-typeedge-feed"
|
||||
echo Adding the private nuget packages feed "private-typeedge-feed"
|
||||
nuget.exe sources Add -Name "private-typeedge-feed" -Source "https://msblox-03.pkgs.visualstudio.com/_packaging/private-nuget-feed/nuget/v3/index.json" -StorePasswordInClearText -ConfigFile NuGet.Config -UserName "%1" -Password "%2"
|
||||
if errorlevel 0 (
|
||||
echo Success!
|
||||
)
|
||||
)
|
||||
|
||||
if exist nuget.exe (
|
||||
del nuget.exe /q
|
||||
)
|
||||
|
||||
exit /b 0
|
||||
|
||||
|
||||
:HAVE_USERNAME
|
||||
echo Your Git credentials username is required
|
||||
exit /b 1
|
||||
|
||||
:HAVE_PASSWORD
|
||||
echo Your Git credentials password is required
|
||||
exit /b 1
|
||||
|
||||
:exit
|
||||
echo exiting..
|
|
@ -6,6 +6,7 @@
|
|||
<ProjectGuid>1373dbdc-dc13-429e-8c17-2e4d85cf42ba</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".env" />
|
||||
<None Include="docker-compose.override.yml">
|
||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||
</None>
|
||||
|
|
|
@ -1,22 +1,29 @@
|
|||
version: '3.4'
|
||||
volumes:
|
||||
env:
|
||||
|
||||
services:
|
||||
|
||||
normalizetemperaturemodule:
|
||||
image: ${DOCKER_REGISTRY}normalizetemperature
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/NormalizeTemperatureModule/Dockerfile
|
||||
|
||||
|
||||
temperaturemodule:
|
||||
image: ${DOCKER_REGISTRY}temperature
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/TemperatureModule/Dockerfile
|
||||
|
||||
thermostat.emulator:
|
||||
image: ${DOCKER_REGISTRY}thermostatemulator
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Thermostat.Emulator/Dockerfile
|
||||
volumes:
|
||||
- env:/env
|
||||
|
||||
|
||||
normalizetemperaturemodule:
|
||||
image: ${DOCKER_REGISTRY}normalizetemperaturemodule
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/NormalizeTemperatureModule/Dockerfile
|
||||
volumes:
|
||||
- env:/env
|
||||
|
||||
temperaturemodule:
|
||||
image: ${DOCKER_REGISTRY}temperaturemodule
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/TemperatureModule/Dockerfile
|
||||
volumes:
|
||||
- env:/env
|
||||
|
|
Двоичные данные
Example/nuget.exe
Двоичные данные
Example/nuget.exe
Двоичный файл не отображается.
|
@ -12,18 +12,31 @@ EndProject
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{F2FF1756-9AAF-411B-8B54-3829EAC21515}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TemperatureModule", "Example\Modules\TemperatureModule\TemperatureModule.csproj", "{48302C68-971D-414F-A29D-742F79415D74}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB} = {54587D56-7C22-4084-9321-84D57C2F6ECB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NormalizeTemperatureModule", "Example\Modules\NormalizeTemperatureModule\NormalizeTemperatureModule.csproj", "{30A335A6-47C9-435A-BA23-50988EAF2C33}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB} = {54587D56-7C22-4084-9321-84D57C2F6ECB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thermostat.Shared", "Example\Thermostat.Shared\Thermostat.Shared.csproj", "{45F97F43-7C75-49B8-8525-7F0E9C7B9FB7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB} = {54587D56-7C22-4084-9321-84D57C2F6ECB}
|
||||
{E738845B-4D98-4CB9-BDA4-F83193FE81B5} = {E738845B-4D98-4CB9-BDA4-F83193FE81B5}
|
||||
{6F13F88C-B271-4DA6-9A35-5FD7FEADD3A3} = {6F13F88C-B271-4DA6-9A35-5FD7FEADD3A3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thermostat.Emulator", "Example\Thermostat.Emulator\Thermostat.Emulator.csproj", "{2076DDEF-8EE3-4BC1-BF79-1C1F62A8719D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB} = {54587D56-7C22-4084-9321-84D57C2F6ECB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thermostat.ServiceApp", "Example\Thermostat.ServiceApp\Thermostat.ServiceApp.csproj", "{286CDAA1-5410-4322-AC1C-F35A83CDA63D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{54587D56-7C22-4084-9321-84D57C2F6ECB} = {54587D56-7C22-4084-9321-84D57C2F6ECB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.IoT.TypeEdge.Proxy", "Microsoft.Azure.IoT.TypeEdge.Proxy\Microsoft.Azure.IoT.TypeEdge.Proxy.csproj", "{E738845B-4D98-4CB9-BDA4-F83193FE81B5}"
|
||||
EndProject
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Microsoft.Azure.IoT.TypeEdge.Host</id>
|
||||
<version>0.1.26</version>
|
||||
<version>0.1.48</version>
|
||||
<authors>paloukari</authors>
|
||||
<owners>paloukari</owners>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Package Description</description>
|
||||
<dependencies>
|
||||
<group targetFramework=".NETCoreApp2.1">
|
||||
<dependency id="Microsoft.Azure.IoT.TypeEdge" version="0.1.26" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Azure.IoT.TypeEdge" version="0.1.48" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Azure.Devices.Edge.Agent.Core" version="1.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Azure.Devices.Edge.Hub.Service" version="1.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Castle.DynamicProxy;
|
||||
using Microsoft.Azure.Devices;
|
||||
using Microsoft.Azure.Devices;
|
||||
using Microsoft.Azure.Devices.Common.Exceptions;
|
||||
using Microsoft.Azure.Devices.Edge.Agent.Core;
|
||||
using Microsoft.Azure.Devices.Edge.Storage;
|
||||
|
@ -34,6 +34,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
private readonly EdgeHub _hub;
|
||||
private ModuleCollection _modules;
|
||||
private readonly TypeEdgeHostOptions _options;
|
||||
private readonly bool _inContainer;
|
||||
|
||||
|
||||
public TypeEdgeHost(IConfigurationRoot configuration)
|
||||
|
@ -53,6 +54,8 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
_hub = new EdgeHub();
|
||||
|
||||
Upstream = new Upstream<JsonMessage>(_hub);
|
||||
|
||||
_inContainer = File.Exists(@"/.dockerenv");
|
||||
}
|
||||
|
||||
public Upstream<JsonMessage> Upstream { get; set; }
|
||||
|
@ -74,7 +77,8 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
|
||||
public void Build()
|
||||
{
|
||||
//setup the container
|
||||
CleanUp();
|
||||
|
||||
BuildContainer();
|
||||
|
||||
_modules = CreateModules();
|
||||
|
@ -86,6 +90,14 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
BuildHub(deviceSasKey);
|
||||
}
|
||||
|
||||
private void CleanUp()
|
||||
{
|
||||
if (!_inContainer || !Directory.Exists(TypeEdge.Constants.ComposeConfigurationPath))
|
||||
return;
|
||||
foreach (var file in Directory.EnumerateFiles(TypeEdge.Constants.ComposeConfigurationPath))
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
|
||||
public async Task RunAsync()
|
||||
{
|
||||
|
@ -93,9 +105,11 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
{
|
||||
_hub.RunAsync()
|
||||
};
|
||||
|
||||
//start all modules
|
||||
foreach (var module in _modules)
|
||||
tasks.Add(module.InternalRunAsync());
|
||||
if (!_inContainer)
|
||||
foreach (var module in _modules)
|
||||
tasks.Add(module.InternalRunAsync());
|
||||
|
||||
await Task.WhenAll(tasks.ToArray());
|
||||
}
|
||||
|
@ -164,22 +178,49 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
|
||||
private void ConfigureModules()
|
||||
{
|
||||
var certificatePath = @"Certificates/edge-device-ca/cert/edge-device-ca-root.cert.pem";
|
||||
var currentLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
Environment.SetEnvironmentVariable(Devices.Edge.Agent.Core.Constants.EdgeModuleCaCertificateFileKey,
|
||||
Path.Combine(currentLocation,
|
||||
certificatePath));
|
||||
|
||||
foreach (var module in _modules)
|
||||
{
|
||||
var moduleConnectionString =
|
||||
GetModuleConnectionStringAsync(_options.IotHubConnectionString, _options.DeviceId, module.Name)
|
||||
.Result;
|
||||
Environment.SetEnvironmentVariable(Devices.Edge.Agent.Core.Constants.EdgeHubConnectionStringKey,
|
||||
moduleConnectionString);
|
||||
Environment.SetEnvironmentVariable(Devices.Edge.Agent.Core.Constants.EdgeModuleCaCertificateFileKey,
|
||||
Path.Combine(currentLocation, @"Certificates/edge-device-ca/cert/edge-device-ca-root.cert.pem"));
|
||||
|
||||
var moduleConfiguration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
if (_inContainer)
|
||||
{
|
||||
System.Console.WriteLine("Emulator running in docker-compose mode.");
|
||||
|
||||
module.InternalConfigure(moduleConfiguration);
|
||||
const string envPath = TypeEdge.Constants.ComposeConfigurationPath;
|
||||
var path = Path.Combine(envPath, $"{module.Name}.env");
|
||||
var certPath = Path.Combine(envPath, certificatePath);
|
||||
|
||||
var dotenvData = $"{Devices.Edge.Agent.Core.Constants.EdgeHubConnectionStringKey}={moduleConnectionString}";
|
||||
dotenvData += $"{Environment.NewLine}{Devices.Edge.Agent.Core.Constants.EdgeModuleCaCertificateFileKey}={certPath}";
|
||||
|
||||
if (!Directory.Exists(Path.GetDirectoryName(certPath)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(certPath));
|
||||
|
||||
if (!File.Exists(certPath))
|
||||
File.Copy(Path.Combine(currentLocation, certificatePath), certPath);
|
||||
|
||||
File.WriteAllText(path, dotenvData);
|
||||
}
|
||||
else
|
||||
{
|
||||
Environment.SetEnvironmentVariable(Devices.Edge.Agent.Core.Constants.EdgeHubConnectionStringKey,
|
||||
moduleConnectionString);
|
||||
|
||||
var moduleConfiguration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
module.InternalConfigure(moduleConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,7 +251,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
try
|
||||
{
|
||||
var device = await registryManager.AddDeviceAsync(
|
||||
new Device(_options.DeviceId) {Capabilities = new DeviceCapabilities {IotEdge = true}});
|
||||
new Device(_options.DeviceId) { Capabilities = new DeviceCapabilities { IotEdge = true } });
|
||||
sasKey = device.Authentication.SymmetricKey.PrimaryKey;
|
||||
}
|
||||
catch (DeviceAlreadyExistsException)
|
||||
|
@ -231,7 +272,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
var modulesConfig =
|
||||
configurationContent.ModuleContent["$edgeAgent"].TargetContent["modules"] as JObject;
|
||||
|
||||
var dockerRegistry = Environment.GetEnvironmentVariable("DOCKER_REGISTRY") ?? "";
|
||||
var dockerRegistry = _configuration.GetValue<string>("DOCKER_REGISTRY") ?? "";
|
||||
|
||||
foreach (var module in _modules)
|
||||
{
|
||||
|
@ -265,8 +306,8 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
var routes = new Dictionary<string, string>();
|
||||
|
||||
foreach (var module in _modules)
|
||||
foreach (var route in module.Routes)
|
||||
routes[$"route{routes.Count}"] = route;
|
||||
foreach (var route in module.Routes)
|
||||
routes[$"route{routes.Count}"] = route;
|
||||
|
||||
foreach (var route in _hub.Routes) routes[$"route{routes.Count}"] = route;
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using Serilog.Events;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host
|
||||
{
|
||||
|
@ -7,7 +9,9 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host
|
|||
public string IotHubConnectionString { get; set; }
|
||||
public string DeviceId { get; set; }
|
||||
public LogEventLevel? RuntimeLogLevel { get; set; }
|
||||
|
||||
public bool? PrintDeploymentJson { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public RunningEnvironment? Environment { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<PackageId>Microsoft.Azure.IoT.TypeEdge.Proxy</PackageId>
|
||||
<Version>0.1.26</Version>
|
||||
<Version>0.1.48</Version>
|
||||
<Authors>paloukari</Authors>
|
||||
<Company>Microsoft</Company>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
public const string ConfigFileName = "appsettings_compose.json";
|
||||
public const string EdgeHubConnectionStringKey = "EdgeHubConnectionString";
|
||||
public const string ModuleNameConfigName = "ModuleName";
|
||||
public const string ModuleNameConfigName = "moduleName";
|
||||
public const string ComposeConfigurationPath = "/env";
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv
|
||||
{
|
||||
public class Dotenv
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
using System.IO;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv
|
||||
{
|
||||
public class DotenvConfigurationProvider : FileConfigurationProvider
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv
|
||||
{
|
||||
public class DotenvConfigurationSource : FileConfigurationSource
|
||||
{
|
|
@ -3,8 +3,9 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using PhysicalFileProvider = Microsoft.Azure.IoT.TypeEdge.DovEnv.FileProvider.PhysicalFileProvider;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv
|
||||
{
|
||||
public static class DotenvExtension
|
||||
{
|
||||
|
@ -67,17 +68,18 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
|||
//--
|
||||
// The below is still needed for .NET Core 1.x
|
||||
//--
|
||||
var fileExists = false;
|
||||
foreach (var basePath in basePaths)
|
||||
{
|
||||
var testPath = string.Join("/", new string[] { basePath, path });
|
||||
if (File.Exists(testPath))
|
||||
var fileExists = path.StartsWith('/') && File.Exists(path);
|
||||
if (!fileExists)
|
||||
foreach (var basePath in basePaths)
|
||||
{
|
||||
var testPath = string.Join("/", new string[] { basePath, path });
|
||||
Console.WriteLine($"DotEnv: checking for {testPath}");
|
||||
if (!File.Exists(testPath))
|
||||
continue;
|
||||
fileExists = true;
|
||||
path = testPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fileExists && !optional)
|
||||
{
|
||||
throw new Exception($"The .env configuration file '{path}' was not found");
|
||||
|
@ -86,7 +88,7 @@ namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv
|
|||
{
|
||||
// Real PhysicalFileProvider has a bug that don't allow dot files:
|
||||
// https://github.com/aspnet/FileSystem/issues/232
|
||||
provider = new FileProvider.PhysicalFileProvider(Path.GetDirectoryName(path));
|
||||
provider = new PhysicalFileProvider(Path.GetDirectoryName(path));
|
||||
path = Path.GetFileName(path);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ using System.Diagnostics;
|
|||
using System.Threading;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv.FileProvider
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv.FileProvider
|
||||
{
|
||||
public class CompositeChangeToken : IChangeToken
|
||||
{
|
|
@ -5,8 +5,9 @@ using Microsoft.Extensions.FileProviders;
|
|||
using Microsoft.Extensions.FileProviders.Internal;
|
||||
using Microsoft.Extensions.FileProviders.Physical;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using PhysicalFilesWatcher = Microsoft.Azure.IoT.TypeEdge.DovEnv.FileProvider.PhysicalFilesWatcher;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv.FileProvider
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv.FileProvider
|
||||
{
|
||||
public class PhysicalFileProvider : IFileProvider, IDisposable
|
||||
{
|
|
@ -8,7 +8,7 @@ using Microsoft.Extensions.FileProviders.Physical;
|
|||
using Microsoft.Extensions.FileSystemGlobbing;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.Host.DovEnv.FileProvider
|
||||
namespace Microsoft.Azure.IoT.TypeEdge.DovEnv.FileProvider
|
||||
{
|
||||
public class PhysicalFilesWatcher : IDisposable
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<PackageId>Microsoft.Azure.IoT.TypeEdge</PackageId>
|
||||
<Version>0.1.26</Version>
|
||||
<Version>0.1.48</Version>
|
||||
<Authors>paloukari</Authors>
|
||||
<Company>Microsoft</Company>
|
||||
<PackageOutputPath>../../TypeEdgeNuGets</PackageOutputPath>
|
||||
|
|
|
@ -11,7 +11,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.Azure.Devices.Client;
|
||||
using Microsoft.Azure.Devices.Client.Transport.Mqtt;
|
||||
using Microsoft.Azure.Devices.Shared;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Attributes;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Enums;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules.Endpoints;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules.Enums;
|
||||
|
@ -71,7 +70,6 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
|
||||
internal virtual async Task<T> GetTwinAsync<T>(string name)
|
||||
where T : IModuleTwin, new()
|
||||
|
||||
{
|
||||
var typeTwin = Activator.CreateInstance<T>();
|
||||
typeTwin.SetTwin(name, await _ioTHubModuleClient.GetTwinAsync());
|
||||
|
@ -151,7 +149,11 @@ namespace Microsoft.Azure.IoT.TypeEdge.Modules
|
|||
internal CreationResult InternalConfigure(IConfigurationRoot configuration)
|
||||
{
|
||||
Console.WriteLine($"{Name}:InternalConfigure called");
|
||||
_connectionString = configuration.GetValue<string>(Constants.EdgeHubConnectionStringKey);
|
||||
|
||||
_connectionString = configuration.GetValue<string>($"{Constants.EdgeHubConnectionStringKey}");
|
||||
if (string.IsNullOrEmpty(_connectionString))
|
||||
throw new ArgumentException($"Missing {Constants.EdgeHubConnectionStringKey} in configuration for {Name}");
|
||||
|
||||
|
||||
// Cert verification is not yet fully functional when using Windows OS for the container
|
||||
var bypassCertVerification = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
|
@ -8,10 +9,12 @@ using Autofac;
|
|||
using Autofac.Extensions.DependencyInjection;
|
||||
using Castle.DynamicProxy;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Attributes;
|
||||
using Microsoft.Azure.IoT.TypeEdge.DovEnv;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Modules;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Proxy;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using static System.String;
|
||||
|
||||
namespace Microsoft.Azure.IoT.TypeEdge
|
||||
{
|
||||
|
@ -31,22 +34,65 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
.AddCommandLine(args)
|
||||
.Build();
|
||||
|
||||
|
||||
var moduleName = configuration.GetValue<string>(Constants.ModuleNameConfigName);
|
||||
|
||||
//todo: throw or warn here?
|
||||
if (string.IsNullOrEmpty(moduleName))
|
||||
if (IsNullOrEmpty(moduleName))
|
||||
{
|
||||
Console.WriteLine($"WARN:No {Constants.ModuleNameConfigName} in configuration. ");
|
||||
Console.WriteLine("Exiting...");
|
||||
return;
|
||||
//throw new ArgumentException($"No moduleName in arguments");
|
||||
|
||||
moduleName = DiscoverModuleName();
|
||||
if (IsNullOrEmpty(moduleName))
|
||||
{
|
||||
Console.WriteLine("Exiting...");
|
||||
return;
|
||||
//throw new ArgumentException($"No moduleName in arguments");
|
||||
}
|
||||
}
|
||||
|
||||
var (moduleType, _) = GetModuleTypes(moduleName);
|
||||
|
||||
if (moduleType == null)
|
||||
throw new ArgumentException($"No module callled {moduleName} in calling assembly");
|
||||
throw new ArgumentException($"No module called {moduleName} in calling assembly");
|
||||
|
||||
var connectionString = configuration.GetValue<string>($"{Constants.EdgeHubConnectionStringKey}");
|
||||
|
||||
if (IsNullOrEmpty(connectionString))
|
||||
{
|
||||
|
||||
//check the file system, we are in docker-compose mode
|
||||
var fileName = Path.Combine(Constants.ComposeConfigurationPath, $"{moduleName}.env");
|
||||
var remainingSeconds = 30;
|
||||
while (remainingSeconds-- > 0)
|
||||
{
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
configuration = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.AddCommandLine(args)
|
||||
.AddDotenvFile(fileName)
|
||||
.Build();
|
||||
File.Delete(fileName);
|
||||
break;
|
||||
}
|
||||
|
||||
var directory = Path.GetDirectoryName(fileName);
|
||||
foreach (var file in Directory.EnumerateFiles(directory))
|
||||
{
|
||||
Console.WriteLine(file);
|
||||
}
|
||||
|
||||
Console.WriteLine($"{moduleName}:{fileName} does not exist. Retrying in 1 sec.");
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
if (remainingSeconds < 0)
|
||||
{
|
||||
Console.WriteLine($"{moduleName}:No {moduleName}.env found.");
|
||||
Console.WriteLine($"{moduleName}:Exiting...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
containerBuilder.RegisterType(moduleType);
|
||||
|
||||
|
@ -81,6 +127,20 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
await WhenCancelled(cts.Token);
|
||||
}
|
||||
|
||||
private static string DiscoverModuleName()
|
||||
{
|
||||
var assembly = Assembly.GetEntryAssembly();
|
||||
var moduleType = assembly.GetTypes().SingleOrDefault(t =>
|
||||
t.GetInterfaces().SingleOrDefault(i =>
|
||||
i.GetCustomAttribute(typeof(TypeModuleAttribute), true) != null) != null);
|
||||
|
||||
if (moduleType == null)
|
||||
return null;
|
||||
|
||||
var moduleInterfaceType = moduleType.GetProxyInterface();
|
||||
return moduleInterfaceType.Name.Substring(1).ToLower();
|
||||
}
|
||||
|
||||
public static Task WhenCancelled(CancellationToken cancellationToken)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
@ -105,7 +165,7 @@ namespace Microsoft.Azure.IoT.TypeEdge
|
|||
var moduleType = assembly.GetTypes().SingleOrDefault(t =>
|
||||
t.GetInterfaces().SingleOrDefault(i =>
|
||||
i.GetCustomAttribute(typeof(TypeModuleAttribute), true) != null &&
|
||||
string.Equals(i.Name.Substring(1), moduleName, StringComparison.CurrentCultureIgnoreCase)) != null);
|
||||
String.Equals(i.Name.Substring(1), moduleName, StringComparison.CurrentCultureIgnoreCase)) != null);
|
||||
|
||||
if (moduleType == null)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<packageSources>
|
||||
<add key="RocksDB ARM" value="https://www.myget.org/F/rocksdb-native-arm/api/v3/index.json" />
|
||||
<add key="https://www.nuget.org/api/v2/" value="https://www.nuget.org/api/v2/" />
|
||||
<add key="localSource" value="../TypeEdgeNuGets" />
|
||||
</packageSources>
|
||||
<disabledPackageSources>
|
||||
<add key="https://www.nuget.org/api/v2/" value="true" />
|
||||
|
|
170
README.md
170
README.md
|
@ -1,111 +1,137 @@
|
|||
# Azure IoT TypeEdge
|
||||
|
||||
The **Azure IoT TypeEdge** introduces a strongly typed flavor of the inherently loosely coupled vanilla [Azure IoT Edge](https:/azure.microsoft.com/en-us/services/iot-edge/).
|
||||
The **Azure IoT TypeEdge** introduces a strongly-typed flavor of the inherently loosely coupled vanilla [Azure IoT Edge](https:/azure.microsoft.com/en-us/services/iot-edge/).
|
||||
|
||||
Specifically:
|
||||
Specifically, **TypeEdge**:
|
||||
|
||||
- It removes all configuration burden from an IoT Edge application, because configuration can be now automatically generated by code reflection.
|
||||
- Introduces compile time types checking across all modules
|
||||
- It adds the ability to **emulate an IoT Edge device on the development environment**, by running all components in memory, no containers involved
|
||||
- It simplifies the IoT Edge development down to an single F5 experience
|
||||
- Removes all configuration burden from an IoT Edge application, because configuration can be now automatically generated.
|
||||
- Introduces compile-time types checking across all modules
|
||||
- Adds the ability to **emulate an IoT Edge device in-memory** with no containers involved
|
||||
- Simplifies the IoT Edge development, down to an single F5 experience
|
||||
|
||||
## Initial Setup
|
||||
## Prerequisites
|
||||
|
||||
The minimum requirements to get started with **TypeEdge** are:
|
||||
- The latest [.NET Core SDK](https://github.com/dotnet/core/blob/master/release-notes/download-archives/2.1.0-download.md) (version 2.1.300). To find your current version, run
|
||||
`dotnet --version`
|
||||
- An [Azure IoT Hub](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-create-through-portal)
|
||||
|
||||
To be able to publish your application, you will also need:
|
||||
- [Docker](https://docs.docker.com/engine/installation/)
|
||||
- An [Azure Container Registry](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal), or any other secure container registry.
|
||||
- Temporarily, you'll need your git credentials to login [to the private packages feed.](https://msblox-03.visualstudio.com/csetypeedge)
|
||||
|
||||
|
||||
Make sure you have [Docker](https://docs.docker.com/engine/installation/), the latest [.NET Core SDK](https://github.com/dotnet/core/blob/master/release-notes/download-archives/2.1.0-download.md) (version 2.1.300) and your git credentials to login [here](https://msblox-03.visualstudio.com/csetypeedge)
|
||||
|
||||
|
||||
> Note: To get your git credentials, navigate to the [VSTS repo](https://msblox-03.visualstudio.com/csetypeedge) and under **"clone to your computer"** section, click **"Generate Git Credentials"**.
|
||||
|
||||
|
||||
You will need also an [Azure IoT Hub](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-create-through-portal) and an [Azure Container Registry](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal), or any other secure container registry.
|
||||
|
||||
## QuickStart
|
||||
Here is the quickest way to get started with **TypeEdge**. In this quick start you will create an IoT Edge application with two modules and run it in the IoT Edge emulator:
|
||||
## Create a new **TypeEdge** application
|
||||
Here is the quickest way to get started with **TypeEdge**. In this quick start you will create an IoT Edge application with two modules and run it in the emulator:
|
||||
|
||||
1. Install the TypeEdge .NET Core solution template. Just type:
|
||||
```
|
||||
dotnet new -i TypeEdge.Application
|
||||
```
|
||||
|
||||
>**Note:** If you already installed the template and you want to **upgrade to a newer template version**, you need to clear the dotnet http and template cache
|
||||
>**Note:** to **upgrade to a newer template version**, you need to clear the dotnet http and template cache first
|
||||
```
|
||||
dotnet nuget locals http-cache --clear
|
||||
dotnet new --debug:reinit
|
||||
```
|
||||
2. Copy the **iothubowner connection string** from your development Azure **IoT Hub**.
|
||||
1. Copy the **iothubowner** connection string from your Azure **IoT Hub**.
|
||||
> The **iothubowner** is required because TypeEdge needs to provision a new device with the generated deployment configuration.
|
||||
|
||||
1. Create a new IoT TypeEdge application:
|
||||
> You can choose the TypeEdge application and modules names of this template. In the example below, the application is called **Thermostat**, and the two modules are called **SensorModule** and **PreprocessorModule**. These names will be used as class names, so **Pascal casing** is suggested.
|
||||
> You can choose the TypeEdge application and modules names. In the example below, the application is called **Thermostat**, and the two modules are called **SensorModule** and **PreprocessorModule**. These names will be used as class names, so **Pascal casing** is suggested.
|
||||
```
|
||||
dotnet new typeedgeapp -n Thermostat -m1 SensorModule -m2 PreprocessorModule -cs "YOUR_IOTHUBOWNER_CONNECTION" -cr YOUR_CONTAINER_REGISTRY
|
||||
```
|
||||
>Note: a localhost registry will not work in this version.
|
||||
|
||||
1. Temporary step:
|
||||
|
||||
Navigate inside the root folder to add the private packages source. Then, **add your git credentials to the command below** and run it. This will download nuget.exe and add the private packages source in your solution.
|
||||
```
|
||||
cd Thermostat
|
||||
addPrivateSource.bat USERNAME PASSWORD
|
||||
```
|
||||
3. Open in VS Code/Visual Studio 2017 and hit F5:
|
||||
|
||||
```
|
||||
code .
|
||||
```
|
||||
..or run it in the command line:
|
||||
```
|
||||
dotnet build Thermostat.sln
|
||||
cd Thermostat.Emulator
|
||||
dotnet run
|
||||
```
|
||||
>Note: a localhost registry is not supported at the moment.
|
||||
|
||||
|
||||
> Note: You should see now the Edge Hub starting up..
|
||||
![](images/IoTEdge.png) .. and the messages flowing in .. ![](images/messages.png)
|
||||
## Build and debug the application
|
||||
|
||||
1. Navigate in the application folder:
|
||||
|
||||
cd Thermostat
|
||||
|
||||
1. Open in VS Code/Visual Studio 2017 and hit F5:
|
||||
|
||||
- For VS Code run
|
||||
|
||||
code .
|
||||
|
||||
- For VS 2017 run
|
||||
|
||||
Thermostat.sln
|
||||
|
||||
- To run the application in the command line (no IDE):
|
||||
```
|
||||
dotnet build Thermostat.sln
|
||||
cd Thermostat.Emulator
|
||||
dotnet run
|
||||
```
|
||||
|
||||
>Note: In all three cases, your application is being emulated in-memory without any containers involved. This is very useful for quick develop and test iterations.
|
||||
|
||||
|
||||
You should see now the Edge Hub starting up..
|
||||
|
||||
![](images/IoTEdge.png)
|
||||
|
||||
.. and the messages flowing in ..
|
||||
![](images/messages.png)
|
||||
|
||||
## Containers debugging
|
||||
|
||||
If your modules have system dependencies and you want to debug inside the containers, you can leverage the docker support feature of VS 2017. Simply start the docker-compose project from VS 2017 to **debug your application inside the docker containers**.
|
||||
|
||||
|
||||
Alternatively, you can run your application inside the containers in command line:
|
||||
|
||||
docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.vs.debug.yml up
|
||||
|
||||
> Note: To build the docker containers, temporarily you need to [add the private NuGet feed](#feed) first.
|
||||
|
||||
![](images/incontainer.png)
|
||||
|
||||
**Congratulations!**
|
||||
|
||||
You just created your first **TypeEdge** application. Continue reading below to learn how to deploy this application to an IoT Device, or take the time to understand [how it works](#how).
|
||||
You just created your first **TypeEdge** application. Continue reading to learn how to deploy this application to an IoT Device, or take the time to understand [how it works](#how).
|
||||
|
||||
## Publish the Application
|
||||
|
||||
##
|
||||
1. ***Temporary step* <a name="feed">Private packages feed:</a>** To build the containers, you have to add the private packages source first. **Add your git credentials to the private repo** and run the below command. This will download nuget.exe and add the private packages source in your solution.
|
||||
|
||||
addPrivateSource.bat USERNAME PASSWORD
|
||||
|
||||
1. Now, you can build the container images:
|
||||
|
||||
docker-compose build
|
||||
|
||||
|
||||
1. The final step is to push these images to your docker registry. Make sure Docker can access your registry:
|
||||
|
||||
docker login YOUR_REGISTRY -u YOUR_USERNAME -p YOUR_PASSWORD
|
||||
|
||||
Push the images to your registry
|
||||
|
||||
docker-compose push
|
||||
|
||||
>Note: The registry is configured in the .env file inside the root folder. **If you edit the .env file, make sure you run the the emulator afterwards** to update the cloud IoT Edge Device deployment configuration.
|
||||
|
||||
## Device Deployment
|
||||
1. **Get the device connection string from Azure portal**, and on the device host run:
|
||||
|
||||
In the application root folder, type:
|
||||
iotedgectl setup --connection-string "THE_DEVICE_CONNECTION_STRING" --auto-cert-gen-force-no-passwords
|
||||
|
||||
docker-compose build
|
||||
>Note: The device name is configured in the appsettings.json of the emulator project. **Make sure you run the emulator and rebuilt the containers if you change that name**. The emulator will provision a new device if the device does not exist.
|
||||
|
||||
|
||||
This will build your docker images for the device deployment. Final step is to push the images to the docker registry.
|
||||
|
||||
|
||||
|
||||
>Note: You need to provide the registry credentials to docker before you can push there:
|
||||
|
||||
docker login YOUR_REGISTRY -u YOUR_USERNAME -p YOUR_PASSWORD
|
||||
|
||||
Push the images to your registry
|
||||
|
||||
docker-compose push
|
||||
|
||||
>Note: The registry is configured in the .env file inside the root folder. **Make sure you run the the emulator if you edit the .env file**, to update the cloud IoT Device deployment configuration.
|
||||
|
||||
This was the final step. All IoT Edge containers are ready to be deployed to the device.
|
||||
|
||||
On the device host, **get the device connection string from Azure portal**, and run:
|
||||
|
||||
iotedgectl setup --connection-string "THE_DEVICE_CONNECTION_STRING" --auto-cert-gen-force-no-passwords
|
||||
|
||||
>Note: The device name is configured in the appsettings.json of the emulator project. **Make sure you run the emulator and rebuilt the containers if you change that name**. The emulator will provision a new device if the device does not exist.
|
||||
|
||||
if your registry requires authentication, you need to run
|
||||
1. If your registry requires authentication, you need to run
|
||||
|
||||
iotedgectl login --address YOUR_REGISTRY_ADDRESS --username YOUR_REGISTRY_USERNAME --password YOUR_REGISTRY_PASSWORD
|
||||
iotedgectl login --address YOUR_REGISTRY_ADDRESS --username YOUR_REGISTRY_USERNAME --password YOUR_REGISTRY_PASSWORD
|
||||
|
||||
Finally, start the runtime:
|
||||
1. Finally, start the runtime:
|
||||
|
||||
iotedgectl start
|
||||
iotedgectl start
|
||||
|
||||
Read more [here](https://docs.microsoft.com/en-us/azure/iot-edge/quickstart#configure-the-iot-edge-runtime) about the IoT Edge device deployment.
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.IoT.TypeEdge.DovEnv;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Host;
|
||||
using Microsoft.Azure.IoT.TypeEdge.Host.DovEnv;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using TypeEdgeApplication.Shared;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\.env" Link=".env">
|
||||
<None Include="..\.env" Link=".env" Visible="false">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
@ -15,7 +15,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="rocksdb-native-arm" Version="5.4.6" />
|
||||
<PackageReference Include="RocksDbNative" Version="5.4.6.10" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -5,4 +5,6 @@ services:
|
|||
image: ${DOCKER_REGISTRY}TypeEdgeApplicationEmulatorImageName
|
||||
build:
|
||||
context: .
|
||||
dockerfile: TypeEdgeApplication.Emulator/Dockerfile
|
||||
dockerfile: TypeEdgeApplication.Emulator/Dockerfile
|
||||
volumes:
|
||||
- env:/env
|
|
@ -1,4 +1,6 @@
|
|||
version: '3.4'
|
||||
volumes:
|
||||
env:
|
||||
|
||||
services:
|
||||
TypeEdgeApplication.Emulator:
|
||||
|
@ -6,17 +8,22 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: TypeEdgeApplication.Emulator/DockerfileEmpty
|
||||
volumes:
|
||||
- env:/env
|
||||
|
||||
TypeEdgeModule1:
|
||||
image: ${DOCKER_REGISTRY}TypeEdgeModule1ImageName
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/TypeEdgeModule1/Dockerfile
|
||||
volumes:
|
||||
- env:/env
|
||||
|
||||
TypeEdgeModule2:
|
||||
image: ${DOCKER_REGISTRY}TypeEdgeModule2ImageName
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Modules/TypeEdgeModule2/Dockerfile
|
||||
|
||||
volumes:
|
||||
- env:/env
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Host" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.26" />
|
||||
<PackageReference Include="Microsoft.Azure.IoT.TypeEdge.Proxy" Version="0.1.48" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -55,7 +55,7 @@ nuget.exe pack build\TypeEdgeApplication -Version %version%
|
|||
|
||||
move /Y *.nupkg ..\..\TypeEdgeNuGets
|
||||
|
||||
rem nuget.exe push ..\..\TypeEdgeNuGets\*%version%.nupkg -ApiKey VSTS
|
||||
nuget.exe push ..\..\TypeEdgeNuGets\*%version%.nupkg -ApiKey VSTS
|
||||
|
||||
dotnet nuget locals http-cache --clear
|
||||
dotnet new --debug:reinit
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 489 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 50 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 123 KiB |
Загрузка…
Ссылка в новой задаче