Skip to content

Commit

Permalink
Merged PR 469065: Merge master1 to master
Browse files Browse the repository at this point in the history
Remove the master1 branch.

Related work items: #1598129
  • Loading branch information
myagley committed Oct 16, 2017
1 parent 8a019ee commit 370eff0
Show file tree
Hide file tree
Showing 98 changed files with 4,430 additions and 2,264 deletions.
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,21 @@ indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true

dotnet_style_qualification_for_field = true
dotnet_style_qualification_for_property = true
dotnet_style_qualification_for_method = true
dotnet_style_qualification_for_event = true
csharp_style_var_when_type_is_apparent = true
csharp_style_expression_bodied_methods = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_space_after_keywords_in_control_flow_statements = true

dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
dotnet_naming_symbols.any_async_methods.applicable_kinds = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
dotnet_naming_symbols.any_async_methods.required_modifiers = async
dotnet_naming_style.end_in_async.required_suffix = Async
dotnet_naming_style.end_in_async.capitalization = pascal_case
17 changes: 16 additions & 1 deletion edge-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ The application will read the `appsettings.json` for configuration. The format i
"DockerUri": "<docker service uri>",
"DeviceConnectionString": "<Your IoT Hub Device Connection String>",
"ConfigSource": "<iothubconnected|standalone>",
"DockerLoggingDriver": "<json-file|journald|fluentd|etwlogs|none>"
"DockerLoggingDriver": "<json-file|journald|fluentd|etwlogs|none>",
"NetworkId": "<Docker network id>",
"EdgeDeviceHostName": "<Edge device host name>"
}
```

Expand All @@ -32,6 +34,10 @@ environment variables.

`DockerLoggingDriver`

`NetworkId`

`EdgeDeviceHostName`

### DockerURI

This is the URI for the docker service. Typically this is "http://localhost:2375"
Expand Down Expand Up @@ -84,3 +90,12 @@ Logs are not available through the `docker logs` command when using "journald."
The following logging drivers have default options which should work when
assigned: "fluentd", "etwlogs", and "none". No testing or validation was done on
these logging drivers.

### NetworkId

Set to the Docker network you want the modules in the Edge deployment to be a part of.

### EdgeDeviceHostName

Set to the host name of the edge device, which will be used by the modules and
downstream devices to connect to the EdgeHub.
50 changes: 23 additions & 27 deletions edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,36 @@ public Agent(IConfigSource configSource, IEnvironment environment, IPlanner plan

public async Task ReconcileAsync(CancellationToken token)
{
Task<ModuleSet> envTask = this.environment.GetModulesAsync(token);
Task<ModuleSet> configTask = this.configSource.GetModuleSetAsync();

await Task.WhenAll(envTask, configTask);

ModuleSet current = envTask.Result;
ModuleSet desired = configTask.Result;
var (current, agentConfig) = await TaskEx.WhenAll(
this.environment.GetModulesAsync(token),
this.configSource.GetAgentConfigAsync()
);
ModuleSet updated = current;

ImmutableDictionary<string, IModuleIdentity> identities = (await this.moduleIdentityLifecycleManager.UpdateModulesIdentity(desired, current))
.ToImmutableDictionary(p => p.Name);
Plan plan = await this.planner.PlanAsync(desired, current, identities);

if (!plan.IsEmpty)
if (agentConfig != AgentConfig.Empty)
{
try
IImmutableDictionary<string, IModuleIdentity> identities = await this.moduleIdentityLifecycleManager.GetModuleIdentities(agentConfig.ModuleSet, current);
Plan plan = await this.planner.PlanAsync(agentConfig.ModuleSet, current, identities);
if (!plan.IsEmpty)
{
await plan.ExecuteAsync(token);
updated = await this.environment.GetModulesAsync(token);
}
catch (Exception ex)
{
Events.PlanExecutionFailed(ex);
throw;
try
{
await plan.ExecuteAsync(token);
updated = await this.environment.GetModulesAsync(token);
}
catch (Exception ex)
{
Events.PlanExecutionFailed(ex);

updated = await this.environment.GetModulesAsync(token);
await this.reporter.ReportAsync(token, updated, agentConfig, new DeploymentStatus(DeploymentStatusCode.Failed, ex.Message));

throw;
}
}
}

await this.reporter.ReportAsync(updated);
await this.reporter.ReportAsync(token, updated, agentConfig, DeploymentStatus.Success);
}

static class Events
Expand All @@ -67,7 +69,6 @@ static class Events
enum EventIds
{
AgentCreated = IdStart,
UpdateDesiredStateFailed,
PlanExecutionFailed
}

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

public static void UpdateDesiredStateFailed()
{
Log.LogError((int)EventIds.UpdateDesiredStateFailed, "Agent update to desired state failed.");
}

public static void PlanExecutionFailed(Exception ex)
{
Log.LogError((int)EventIds.PlanExecutionFailed, ex, "Agent Plan execution failed.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
using Microsoft.Azure.Devices.Edge.Util;

public class AgentConfig
{
public AgentConfig(long version, IRuntimeInfo runtimeInfo, ModuleSet moduleSet, Option<IEdgeAgentModule> edgeAgent)
{
this.Version = version;
this.Runtime = runtimeInfo;
this.ModuleSet = moduleSet ?? ModuleSet.Empty;
this.EdgeAgent = edgeAgent;
}

public static AgentConfig Empty { get; } = new AgentConfig(0, UnknownRuntimeInfo.Instance, ModuleSet.Empty, Option.None<IEdgeAgentModule>());

public long Version { get; }

public IRuntimeInfo Runtime { get; }

public ModuleSet ModuleSet { get; }

public Option<IEdgeAgentModule> EdgeAgent { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public struct AgentEventIds
public const int IoTHubReporter = EventIdStart + 800;
public const int DockerEnvironment = EventIdStart + 900;
public const int ModuleLifecycleCommandFactory = EventIdStart + 1000;
public const int DeviceClient = EventIdStart + 1100;
public const int EdgeAgentConnection = EventIdStart + 1100;
public const int DeviceClient = EventIdStart + 1200;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class ConfigurationInfo : IEquatable<ConfigurationInfo>
{
[JsonConstructor]
public ConfigurationInfo(string id = "")
{
this.Id = id ?? string.Empty;
}

[JsonProperty(PropertyName = "id")]
public string Id { get; }

public override bool Equals(object obj) => this.Equals(obj as ConfigurationInfo);

public bool Equals(ConfigurationInfo other) => other != null && this.Id == other.Id;

public override int GetHashCode()
{
return 2108858624 + EqualityComparer<string>.Default.GetHashCode(Id);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public static class Constants
// Connection string base for Edge Hub Modules
public const string EdgeHubConnectionStringKey = "EdgeHubConnectionString";

public const string IotHubConnectionStringKey = "IotHubConnectionString";

public const string ModuleIdKey = "ModuleId";

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

public const ModuleStatus DefaultDesiredStatus = ModuleStatus.Running;

public const string EdgeHubModuleName = "edgeHub";

public const string EdgeAgentModuleName = "edgeAgent";

public const string EdgeHubModuleIdentityName = "$edgeHub";

public const string EdgeAgentModuleIdentityName = "$edgeAgent";

public const string EdgeDeviceHostNameKey = "EdgeDeviceHostName";

public static class Labels
{
public const string Version = "net.azure-devices.edge.version";
public const string Owner = "net.azure-devices.edge.owner";
public const string RestartPolicy = "net.azure-devices.edge.restartPolicy";
public const string DesiredStatus = "net.azure-devices.edge.desiredStatus";
public const string NormalizedCreateOptions = "net.azure-devices.edge.normalizedCreateOptions";
public const string ConfigurationId = "net.azure-devices.edge.configurationId";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class DeploymentStatus : IEquatable<DeploymentStatus>
{
public static readonly DeploymentStatus Unknown = new DeploymentStatus(DeploymentStatusCode.Unknown);
public static readonly DeploymentStatus Success = new DeploymentStatus(DeploymentStatusCode.Successful);

public DeploymentStatus(DeploymentStatusCode code):
this(code, string.Empty)
{
}

[JsonConstructor]
public DeploymentStatus(DeploymentStatusCode code, string description)
{
this.Code = code;
this.Description = description ?? string.Empty;
}

[JsonProperty(PropertyName = "code")]
public DeploymentStatusCode Code { get; }

[JsonProperty(PropertyName = "description")]
public string Description { get; }

public override bool Equals(object obj) => this.Equals(obj as DeploymentStatus);

public bool Equals(DeploymentStatus other)
{
return other != null &&
this.Code == other.Code &&
this.Description == other.Description;
}

public override int GetHashCode()
{
var hashCode = 1291371069;
hashCode = hashCode * -1521134295 + this.Code.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(this.Description);
return hashCode;
}

public static bool operator ==(DeploymentStatus status1, DeploymentStatus status2)
{
return EqualityComparer<DeploymentStatus>.Default.Equals(status1, status2);
}

public static bool operator !=(DeploymentStatus status1, DeploymentStatus status2)
{
return !(status1 == status2);
}

public DeploymentStatus Clone() => new DeploymentStatus(this.Code, this.Description);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
public enum DeploymentStatusCode
{
Unknown = 406,
Successful = 200,
Failed = 400
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
Expand All @@ -8,10 +8,7 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core

public interface IConfigSource : IDisposable
{
Task<ModuleSet> GetModuleSetAsync();

event EventHandler<Diff> ModuleSetChanged;
event EventHandler<Exception> ModuleSetFailed;
Task<AgentConfig> GetAgentConfigAsync();

IConfiguration Configuration { get; }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core
{
Expand All @@ -11,10 +11,16 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core
/// </summary>
public interface IEnvironment
{
string OperatingSystem { get; }

string Architecture { get; }

/// <summary>
/// Returns a ModuleSet representing the current state of the system (current reality)
/// </summary>
/// <returns></returns>
Task<ModuleSet> GetModulesAsync(CancellationToken token);

Task<IModule> GetEdgeAgentModuleAsync(CancellationToken token);
}
}
}
16 changes: 14 additions & 2 deletions edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/IModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ public enum RestartPolicy

public interface IModule : IEquatable<IModule>
{
[JsonProperty(PropertyName = "name")]
string Name { get; }
[JsonIgnore]
string Name { get; set; }

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

[JsonProperty(PropertyName = "restartPolicy")]
RestartPolicy RestartPolicy { get; }

[JsonProperty(PropertyName = "configuration")]
ConfigurationInfo ConfigurationInfo { get; }
}

public interface IModule<TConfig> : IModule, IEquatable<IModule<TConfig>>
{
[JsonProperty(PropertyName = "settings")]
TConfig Config { get; }
}

public interface IEdgeHubModule : IModule
{
}

public interface IEdgeAgentModule : IModule
{
}
}
Loading

0 comments on commit 370eff0

Please sign in to comment.