Skip to content

Commit 370eff0

Browse files
committed
Merged PR 469065: Merge master1 to master
Remove the master1 branch. Related work items: #1598129
1 parent 8a019ee commit 370eff0

File tree

98 files changed

+4430
-2264
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+4430
-2264
lines changed

.editorconfig

+18
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,21 @@ indent_style = space
66
indent_size = 4
77
charset = utf-8
88
trim_trailing_whitespace = true
9+
10+
dotnet_style_qualification_for_field = true
11+
dotnet_style_qualification_for_property = true
12+
dotnet_style_qualification_for_method = true
13+
dotnet_style_qualification_for_event = true
14+
csharp_style_var_when_type_is_apparent = true
15+
csharp_style_expression_bodied_methods = true:suggestion
16+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
17+
csharp_space_after_keywords_in_control_flow_statements = true
18+
19+
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
20+
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
21+
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
22+
dotnet_naming_symbols.any_async_methods.applicable_kinds = method
23+
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
24+
dotnet_naming_symbols.any_async_methods.required_modifiers = async
25+
dotnet_naming_style.end_in_async.required_suffix = Async
26+
dotnet_naming_style.end_in_async.capitalization = pascal_case

edge-agent/README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ The application will read the `appsettings.json` for configuration. The format i
1515
"DockerUri": "<docker service uri>",
1616
"DeviceConnectionString": "<Your IoT Hub Device Connection String>",
1717
"ConfigSource": "<iothubconnected|standalone>",
18-
"DockerLoggingDriver": "<json-file|journald|fluentd|etwlogs|none>"
18+
"DockerLoggingDriver": "<json-file|journald|fluentd|etwlogs|none>",
19+
"NetworkId": "<Docker network id>",
20+
"EdgeDeviceHostName": "<Edge device host name>"
1921
}
2022
```
2123

@@ -32,6 +34,10 @@ environment variables.
3234

3335
`DockerLoggingDriver`
3436

37+
`NetworkId`
38+
39+
`EdgeDeviceHostName`
40+
3541
### DockerURI
3642

3743
This is the URI for the docker service. Typically this is "http://localhost:2375"
@@ -84,3 +90,12 @@ Logs are not available through the `docker logs` command when using "journald."
8490
The following logging drivers have default options which should work when
8591
assigned: "fluentd", "etwlogs", and "none". No testing or validation was done on
8692
these logging drivers.
93+
94+
### NetworkId
95+
96+
Set to the Docker network you want the modules in the Edge deployment to be a part of.
97+
98+
### EdgeDeviceHostName
99+
100+
Set to the host name of the edge device, which will be used by the modules and
101+
downstream devices to connect to the EdgeHub.

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/Agent.cs

+23-27
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,36 @@ public Agent(IConfigSource configSource, IEnvironment environment, IPlanner plan
2929

3030
public async Task ReconcileAsync(CancellationToken token)
3131
{
32-
Task<ModuleSet> envTask = this.environment.GetModulesAsync(token);
33-
Task<ModuleSet> configTask = this.configSource.GetModuleSetAsync();
34-
35-
await Task.WhenAll(envTask, configTask);
36-
37-
ModuleSet current = envTask.Result;
38-
ModuleSet desired = configTask.Result;
32+
var (current, agentConfig) = await TaskEx.WhenAll(
33+
this.environment.GetModulesAsync(token),
34+
this.configSource.GetAgentConfigAsync()
35+
);
3936
ModuleSet updated = current;
40-
41-
ImmutableDictionary<string, IModuleIdentity> identities = (await this.moduleIdentityLifecycleManager.UpdateModulesIdentity(desired, current))
42-
.ToImmutableDictionary(p => p.Name);
43-
Plan plan = await this.planner.PlanAsync(desired, current, identities);
4437

45-
if (!plan.IsEmpty)
38+
if (agentConfig != AgentConfig.Empty)
4639
{
47-
try
40+
IImmutableDictionary<string, IModuleIdentity> identities = await this.moduleIdentityLifecycleManager.GetModuleIdentities(agentConfig.ModuleSet, current);
41+
Plan plan = await this.planner.PlanAsync(agentConfig.ModuleSet, current, identities);
42+
if (!plan.IsEmpty)
4843
{
49-
await plan.ExecuteAsync(token);
50-
updated = await this.environment.GetModulesAsync(token);
51-
}
52-
catch (Exception ex)
53-
{
54-
Events.PlanExecutionFailed(ex);
55-
throw;
44+
try
45+
{
46+
await plan.ExecuteAsync(token);
47+
updated = await this.environment.GetModulesAsync(token);
48+
}
49+
catch (Exception ex)
50+
{
51+
Events.PlanExecutionFailed(ex);
52+
53+
updated = await this.environment.GetModulesAsync(token);
54+
await this.reporter.ReportAsync(token, updated, agentConfig, new DeploymentStatus(DeploymentStatusCode.Failed, ex.Message));
55+
56+
throw;
57+
}
5658
}
5759
}
5860

59-
await this.reporter.ReportAsync(updated);
61+
await this.reporter.ReportAsync(token, updated, agentConfig, DeploymentStatus.Success);
6062
}
6163

6264
static class Events
@@ -67,7 +69,6 @@ static class Events
6769
enum EventIds
6870
{
6971
AgentCreated = IdStart,
70-
UpdateDesiredStateFailed,
7172
PlanExecutionFailed
7273
}
7374

@@ -76,11 +77,6 @@ public static void AgentCreated()
7677
Log.LogDebug((int)EventIds.AgentCreated, "Agent Created.");
7778
}
7879

79-
public static void UpdateDesiredStateFailed()
80-
{
81-
Log.LogError((int)EventIds.UpdateDesiredStateFailed, "Agent update to desired state failed.");
82-
}
83-
8480
public static void PlanExecutionFailed(Exception ex)
8581
{
8682
Log.LogError((int)EventIds.PlanExecutionFailed, ex, "Agent Plan execution failed.");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
namespace Microsoft.Azure.Devices.Edge.Agent.Core
4+
{
5+
using Microsoft.Azure.Devices.Edge.Util;
6+
7+
public class AgentConfig
8+
{
9+
public AgentConfig(long version, IRuntimeInfo runtimeInfo, ModuleSet moduleSet, Option<IEdgeAgentModule> edgeAgent)
10+
{
11+
this.Version = version;
12+
this.Runtime = runtimeInfo;
13+
this.ModuleSet = moduleSet ?? ModuleSet.Empty;
14+
this.EdgeAgent = edgeAgent;
15+
}
16+
17+
public static AgentConfig Empty { get; } = new AgentConfig(0, UnknownRuntimeInfo.Instance, ModuleSet.Empty, Option.None<IEdgeAgentModule>());
18+
19+
public long Version { get; }
20+
21+
public IRuntimeInfo Runtime { get; }
22+
23+
public ModuleSet ModuleSet { get; }
24+
25+
public Option<IEdgeAgentModule> EdgeAgent { get; }
26+
}
27+
}

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/AgentEventIds.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ public struct AgentEventIds
1515
public const int IoTHubReporter = EventIdStart + 800;
1616
public const int DockerEnvironment = EventIdStart + 900;
1717
public const int ModuleLifecycleCommandFactory = EventIdStart + 1000;
18-
public const int DeviceClient = EventIdStart + 1100;
18+
public const int EdgeAgentConnection = EventIdStart + 1100;
19+
public const int DeviceClient = EventIdStart + 1200;
1920

2021
}
2122
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
namespace Microsoft.Azure.Devices.Edge.Agent.Core
3+
{
4+
using System;
5+
using System.Collections.Generic;
6+
using Newtonsoft.Json;
7+
8+
public class ConfigurationInfo : IEquatable<ConfigurationInfo>
9+
{
10+
[JsonConstructor]
11+
public ConfigurationInfo(string id = "")
12+
{
13+
this.Id = id ?? string.Empty;
14+
}
15+
16+
[JsonProperty(PropertyName = "id")]
17+
public string Id { get; }
18+
19+
public override bool Equals(object obj) => this.Equals(obj as ConfigurationInfo);
20+
21+
public bool Equals(ConfigurationInfo other) => other != null && this.Id == other.Id;
22+
23+
public override int GetHashCode()
24+
{
25+
return 2108858624 + EqualityComparer<string>.Default.GetHashCode(Id);
26+
}
27+
}
28+
}

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/Constants.cs

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public static class Constants
1212
// Connection string base for Edge Hub Modules
1313
public const string EdgeHubConnectionStringKey = "EdgeHubConnectionString";
1414

15+
public const string IotHubConnectionStringKey = "IotHubConnectionString";
16+
1517
public const string ModuleIdKey = "ModuleId";
1618

1719
public const string MMAStorePartitionKey = "mma";
@@ -20,13 +22,24 @@ public static class Constants
2022

2123
public const ModuleStatus DefaultDesiredStatus = ModuleStatus.Running;
2224

25+
public const string EdgeHubModuleName = "edgeHub";
26+
27+
public const string EdgeAgentModuleName = "edgeAgent";
28+
29+
public const string EdgeHubModuleIdentityName = "$edgeHub";
30+
31+
public const string EdgeAgentModuleIdentityName = "$edgeAgent";
32+
33+
public const string EdgeDeviceHostNameKey = "EdgeDeviceHostName";
34+
2335
public static class Labels
2436
{
2537
public const string Version = "net.azure-devices.edge.version";
2638
public const string Owner = "net.azure-devices.edge.owner";
2739
public const string RestartPolicy = "net.azure-devices.edge.restartPolicy";
2840
public const string DesiredStatus = "net.azure-devices.edge.desiredStatus";
2941
public const string NormalizedCreateOptions = "net.azure-devices.edge.normalizedCreateOptions";
42+
public const string ConfigurationId = "net.azure-devices.edge.configurationId";
3043
}
3144
}
3245
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
namespace Microsoft.Azure.Devices.Edge.Agent.Core
4+
{
5+
using System;
6+
using System.Collections.Generic;
7+
using Newtonsoft.Json;
8+
9+
public class DeploymentStatus : IEquatable<DeploymentStatus>
10+
{
11+
public static readonly DeploymentStatus Unknown = new DeploymentStatus(DeploymentStatusCode.Unknown);
12+
public static readonly DeploymentStatus Success = new DeploymentStatus(DeploymentStatusCode.Successful);
13+
14+
public DeploymentStatus(DeploymentStatusCode code):
15+
this(code, string.Empty)
16+
{
17+
}
18+
19+
[JsonConstructor]
20+
public DeploymentStatus(DeploymentStatusCode code, string description)
21+
{
22+
this.Code = code;
23+
this.Description = description ?? string.Empty;
24+
}
25+
26+
[JsonProperty(PropertyName = "code")]
27+
public DeploymentStatusCode Code { get; }
28+
29+
[JsonProperty(PropertyName = "description")]
30+
public string Description { get; }
31+
32+
public override bool Equals(object obj) => this.Equals(obj as DeploymentStatus);
33+
34+
public bool Equals(DeploymentStatus other)
35+
{
36+
return other != null &&
37+
this.Code == other.Code &&
38+
this.Description == other.Description;
39+
}
40+
41+
public override int GetHashCode()
42+
{
43+
var hashCode = 1291371069;
44+
hashCode = hashCode * -1521134295 + this.Code.GetHashCode();
45+
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(this.Description);
46+
return hashCode;
47+
}
48+
49+
public static bool operator ==(DeploymentStatus status1, DeploymentStatus status2)
50+
{
51+
return EqualityComparer<DeploymentStatus>.Default.Equals(status1, status2);
52+
}
53+
54+
public static bool operator !=(DeploymentStatus status1, DeploymentStatus status2)
55+
{
56+
return !(status1 == status2);
57+
}
58+
59+
public DeploymentStatus Clone() => new DeploymentStatus(this.Code, this.Description);
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
namespace Microsoft.Azure.Devices.Edge.Agent.Core
4+
{
5+
public enum DeploymentStatusCode
6+
{
7+
Unknown = 406,
8+
Successful = 200,
9+
Failed = 400
10+
}
11+
}

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/IConfigSource.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft. All rights reserved.
1+
// Copyright (c) Microsoft. All rights reserved.
22

33
namespace Microsoft.Azure.Devices.Edge.Agent.Core
44
{
@@ -8,10 +8,7 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core
88

99
public interface IConfigSource : IDisposable
1010
{
11-
Task<ModuleSet> GetModuleSetAsync();
12-
13-
event EventHandler<Diff> ModuleSetChanged;
14-
event EventHandler<Exception> ModuleSetFailed;
11+
Task<AgentConfig> GetAgentConfigAsync();
1512

1613
IConfiguration Configuration { get; }
1714
}

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/IEnvironment.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft. All rights reserved.
1+
// Copyright (c) Microsoft. All rights reserved.
22

33
namespace Microsoft.Azure.Devices.Edge.Agent.Core
44
{
@@ -11,10 +11,16 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core
1111
/// </summary>
1212
public interface IEnvironment
1313
{
14+
string OperatingSystem { get; }
15+
16+
string Architecture { get; }
17+
1418
/// <summary>
1519
/// Returns a ModuleSet representing the current state of the system (current reality)
1620
/// </summary>
1721
/// <returns></returns>
1822
Task<ModuleSet> GetModulesAsync(CancellationToken token);
23+
24+
Task<IModule> GetEdgeAgentModuleAsync(CancellationToken token);
1925
}
20-
}
26+
}

edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/IModule.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public enum RestartPolicy
8181

8282
public interface IModule : IEquatable<IModule>
8383
{
84-
[JsonProperty(PropertyName = "name")]
85-
string Name { get; }
84+
[JsonIgnore]
85+
string Name { get; set; }
8686

8787
[JsonProperty(PropertyName = "version")]
8888
string Version { get; }
@@ -95,10 +95,22 @@ public interface IModule : IEquatable<IModule>
9595

9696
[JsonProperty(PropertyName = "restartPolicy")]
9797
RestartPolicy RestartPolicy { get; }
98+
99+
[JsonProperty(PropertyName = "configuration")]
100+
ConfigurationInfo ConfigurationInfo { get; }
98101
}
99102

100103
public interface IModule<TConfig> : IModule, IEquatable<IModule<TConfig>>
101104
{
105+
[JsonProperty(PropertyName = "settings")]
102106
TConfig Config { get; }
107+
}
108+
109+
public interface IEdgeHubModule : IModule
110+
{
111+
}
112+
113+
public interface IEdgeAgentModule : IModule
114+
{
103115
}
104116
}

0 commit comments

Comments
 (0)