Skip to content

Commit

Permalink
Release 0.0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Ehrlich committed Jul 29, 2019
1 parent 4b22aa7 commit ee80afc
Show file tree
Hide file tree
Showing 122 changed files with 2,994 additions and 428 deletions.
29 changes: 29 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Use text conventions for commonly used text extensions.
*.csv text
*.ini text
*.json text
*.txt text
*.xml text

# Force linux files to be with linux new line style (i.e \n)
src/Agent/Linux/BaselineExecutables/*.xml text eol=lf
src/Agent/Linux/Install/* text eol=lf
src/Agent/Linux/DevScripts/* text eol=lf
src/Modules/Security/Linux/Install/* text eol=lf
src/Modules/Security/Linux/DevScripts/* text eol=lf

# Denote all files that are truly binary and should not be modified.
*.dll binary
*.exe binary
*.gz binary
*.ico binary
*.jpg binary
*.lib binary
*.pdb binary
*.pdf binary
*.png binary
*.wim binary
*.zip binary
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "Azure-IoT-Security"]
path = Azure-IoT-Security
url = https://github.com/Azure/Azure-IoT-Security.git
branch = master
2 changes: 1 addition & 1 deletion src/Agent/AgentAssemblySharedInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

//Agent versioning
//Version is {Major}.{Minor}.[Minorer].{seconds from midnight / 2}
[assembly: AssemblyVersion("0.0.3.*")]
[assembly: AssemblyVersion("0.0.4.*")]
3 changes: 3 additions & 0 deletions src/Agent/Core/Agent.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp2.0\Agent.Core.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand All @@ -27,6 +29,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.21.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.0" />
</ItemGroup>

Expand Down
32 changes: 21 additions & 11 deletions src/Agent/Core/AgentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Threading;
using System.Linq;
using Microsoft.Azure.IoT.Contracts.Events;
using System.Collections.Generic;

namespace Microsoft.Azure.IoT.Agent.Core
{
Expand All @@ -31,12 +32,16 @@ public abstract class AgentBase : IDisposable
/// </summary>
protected volatile bool IsDisposed;

/// <summary>
/// List of the event generators to be used by the agent;
/// </summary>
protected List<IEventGenerator> EventGenerators;

/// <summary>
/// Ctor - creates a new agent harness object
/// </summary>
protected AgentBase()
{
SimpleLogger.Information("Agent is initializing...", sendAsDiagnostic: true);
//Does not trigger on Windows due to bug https://github.com/dotnet/coreclr/issues/8565
AppDomain.CurrentDomain.ProcessExit += Stop;
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
Expand All @@ -51,16 +56,22 @@ public void Start()
//Load the agent configurations
try
{
SimpleLogger.Information("Agent is initializing...", sendAsDiagnostic: true);
AgentConfiguration.Init();
var eventGeneratorsProvider = new AppConfigEventGeneratorsProvider();
EventGenerators = eventGeneratorsProvider.GetAll();
SimpleLogger.Information("Agent is initialized!");
//Call derived class to perform their initializations/start
DoOnStart();
}
catch (Exception ex)
catch (AgentException ex)
{
throw new AgentFailedToStartException("The agent can not be started", ex);
SimpleLogger.Fatal($"ASC for IoT agent encountered an error! {ex.Message}");
}
catch (TypeInitializationException ex) when (ex.InnerException is AgentException)
{
SimpleLogger.Fatal($"ASC for IoT agent encountered an error! {ex.InnerException.Message}");
}

//Call derived class to perform their initializations/start
DoOnStart();

}

/// <summary>
Expand All @@ -69,12 +80,10 @@ public void Start()
/// <param name="scheduler">The scheduler to setup the event generators in</param>
protected void SetupEventGenerators(TaskScheduler scheduler)
{
var eventGeneratorsProvider = new AppConfigEventGeneratorsProvider();
var generators = eventGeneratorsProvider.GetAll();
DateTime timeToStartTask = DateTime.UtcNow;
TimeSpan timeSpanBetweenGeneratorInvocation = new TimeSpan(LocalConfiguration.General.ProducerInterval.Ticks / generators.Count());
TimeSpan timeSpanBetweenGeneratorInvocation = new TimeSpan(LocalConfiguration.General.ProducerInterval.Ticks / EventGenerators.Count());

foreach (var generator in generators)
foreach (var generator in EventGenerators)
{
EventProducer producer = new EventProducer(generator);
scheduler.AddTask(producer, LocalConfiguration.General.ProducerInterval, timeToStartTask);
Expand Down Expand Up @@ -122,6 +131,7 @@ protected virtual void Dispose(bool disposing)
if (disposing && !IsDisposed)
{
IsDisposed = true;
EventGenerators?.ForEach(eg => eg.Dispose());
AppDomain.CurrentDomain.ProcessExit -= Stop;
AppDomain.CurrentDomain.UnhandledException -= UnhandledExceptionHandler;
ExternalInterfaceFacade.DisposeInstance();
Expand Down
27 changes: 13 additions & 14 deletions src/Agent/Core/Configuration/AgentConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Microsoft.Azure.IoT.Agent.Core.MessageWorker.Clients;
using Microsoft.Azure.IoT.Contracts.Events;
using System;
using System.Collections.Generic;

namespace Microsoft.Azure.IoT.Agent.Core.Configuration
{
Expand Down Expand Up @@ -73,11 +72,7 @@ public static RemoteConfiguration RemoteConfiguration
{
get
{
//If init() was not called - throw exception
if (!_isInitialized)
{
throw new InvalidOperationException($"{nameof(RemoteConfiguration)} was called before AgentConfiguration initialization");
}
EnsureInitialized();
return _remoteConfiguration;
}
set
Expand All @@ -94,21 +89,17 @@ public static RemoteConfiguration RemoteConfiguration
/// </summary>
/// <typeparam name="TEvent">The name of the event</typeparam>
/// <returns>EventPriority</returns>
/// <exception cref="MisconfigurationException">In case the event name is not defined in EventPrioritiesConfiguration</exception>
/// <exception cref="ArgumentOutOfRangeException">In case the event name is not defined in EventPrioritiesConfiguration</exception>
/// <exception cref="InvalidOperationException">In case the method was called before Init() was called - should not happen in a normal flow of the agent</exception>
public static EventPriority GetEventPriority<TEvent>() where TEvent : IEvent
{
//If init() was not called - throw exception
if (!_isInitialized)
{
throw new InvalidOperationException("GetEventPriority was called before AgentConfiguration initialization");
}

EnsureInitialized();
//Get the event property
var eventType = _remoteConfiguration.GetType().GetProperty(typeof(TEvent).Name);
if (eventType == null)
{
throw new MisconfigurationException($"TwinConfiguration error: Couldn't find priority configuration for: {typeof(TEvent).Name}");
throw new ArgumentOutOfRangeException(paramName: $"{nameof(EventPriority)}",
message: $"TwinConfiguration error: Couldn't find priority configuration for: {typeof(TEvent).Name}");
}

EventPriority eventPriority = (EventPriority)eventType.GetValue(_remoteConfiguration);
Expand All @@ -117,6 +108,14 @@ public static EventPriority GetEventPriority<TEvent>() where TEvent : IEvent
return eventPriority;
}

private static void EnsureInitialized()
{
if (!_isInitialized)
{
throw new InvalidOperationException($"{nameof(RemoteConfiguration)} was called before AgentConfiguration initialization");
}
}

private static void OnAgentConfigurationChanged(RemoteConfiguration remoteConfiguration)
{
AgentConfigurationChanged?.Invoke(remoteConfiguration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

using System;
using System.Collections.Specialized;
using System.Reflection;

namespace Microsoft.Azure.IoT.Agent.Core.Configuration.ConfigurationSectionHandlers
{
/// <summary>
/// Configuration related to the agent's external interface
/// </summary>
public class ExternalInterfaceConfig
{
/// <summary>
Expand All @@ -20,6 +22,9 @@ public class ExternalInterfaceConfig
/// </summary>
public Type FacadeType { get; }

/// <summary>
/// Ctor
/// </summary>
public ExternalInterfaceConfig(NameValueCollection nameValueCollection)
{
string facadeTypeName = nameValueCollection[FacadeTypeKey];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Microsoft.Azure.IoT.Contracts.Events;
using System;
using System.Collections.Specialized;
using System.Reflection;
using Microsoft.Azure.IoT.Agent.Core.Utils;

namespace Microsoft.Azure.IoT.Agent.Core.Configuration.ConfigurationSectionHandlers
{
Expand Down Expand Up @@ -136,17 +136,17 @@ public class GeneralConfig
/// <param name="nameValueCollection">nameValueCollection represents the user configuration</param>
public GeneralConfig(NameValueCollection nameValueCollection)
{
FileLogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), nameValueCollection[FileLogLevelKey]);
ReadRemoteConfigurationTimeout = TimeSpan.Parse(nameValueCollection[ReadRemoteConfigurationTimeoutKey]);
SchedulerInterval = TimeSpan.Parse(nameValueCollection[SchedulerIntervalKey]);
ProducerInterval = TimeSpan.Parse(nameValueCollection[ProducerIntervalKey]);
ConsumerInterval = TimeSpan.Parse(nameValueCollection[ConsumerIntervalKey]);
HighPriorityQueueSizePercentage = double.Parse(nameValueCollection[HighPriorityQueueSizePercentageKey]);
AgentId = Guid.Parse(nameValueCollection[AgentIdKey]);
LogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), nameValueCollection[LogLevelKey]);
DiagnosticVerbosityLevel = (DiagnosticVerbosity)Enum.Parse(typeof(DiagnosticVerbosity), nameValueCollection[DiagnosticVerbosityLevelKey]);
LogFilePath = nameValueCollection[LogFilePathKey];
DefaultEventPriority = (EventPriority)Enum.Parse(typeof(EventPriority), nameValueCollection[DefaultEventPriorityKey]);
FileLogLevel = nameValueCollection.GetEnumValueThrowOnFail<LogLevel>(FileLogLevelKey);
ReadRemoteConfigurationTimeout = nameValueCollection.GetTimeSpanValueThrowOnFail(ReadRemoteConfigurationTimeoutKey);
SchedulerInterval = nameValueCollection.GetTimeSpanValueThrowOnFail(SchedulerIntervalKey);
ProducerInterval = nameValueCollection.GetTimeSpanValueThrowOnFail(ProducerIntervalKey);
ConsumerInterval = nameValueCollection.GetTimeSpanValueThrowOnFail(ConsumerIntervalKey);
HighPriorityQueueSizePercentage = nameValueCollection.GetDoubleValueThrowOnFail(HighPriorityQueueSizePercentageKey);
AgentId = nameValueCollection.GetGuidValueThrowOnFail(AgentIdKey);
LogLevel = nameValueCollection.GetEnumValueThrowOnFail<LogLevel>(LogLevelKey);
DiagnosticVerbosityLevel = nameValueCollection.GetEnumValueThrowOnFail<DiagnosticVerbosity>(DiagnosticVerbosityLevelKey);
LogFilePath = nameValueCollection.GetStringValueThrowOnFail(LogFilePathKey);
DefaultEventPriority = nameValueCollection.GetEnumValueThrowOnFail<EventPriority>(DefaultEventPriorityKey);
}
}
}
36 changes: 26 additions & 10 deletions src/Agent/Core/Configuration/LocalConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>

using System;
using Microsoft.Azure.IoT.Agent.Core.Configuration.ConfigurationSectionHandlers;
using Microsoft.Azure.IoT.Agent.Core.Logging;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Reflection;
using Microsoft.Azure.IoT.Agent.Core.Exceptions;

namespace Microsoft.Azure.IoT.Agent.Core.Configuration
{
Expand All @@ -20,28 +21,43 @@ public static class LocalConfiguration
/// <summary>
/// Gets the agent version
/// </summary>
public static string AgentVersion => GetAgentVersion();
public static string AgentVersion { get; }

/// <summary>
/// Gets the event generators configurations
/// </summary>
public static List<EventGeneratorsConfig> EventGenerators =>
EventGeneratorsConfigurationSection.Configuration.ConfigurationElements.ToList();
public static List<EventGeneratorsConfig> EventGenerators { get; }

/// <summary>
/// Agent related configuration
/// </summary>
public static GeneralConfig General => new GeneralConfig(ConfigurationManager.GetSection("General") as NameValueCollection);
public static GeneralConfig General { get; }

public static ExternalInterfaceConfig ExternalInterface => new ExternalInterfaceConfig(ConfigurationManager.GetSection("ExternalInterface") as NameValueCollection);
/// <summary>
/// External interface related configuration
/// </summary>
public static ExternalInterfaceConfig ExternalInterface { get; }

/// <summary>
/// Gets the assembly version of the agent
/// Initiate fields
/// </summary>
/// <returns>agent version</returns>
private static string GetAgentVersion()
static LocalConfiguration()
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
try
{
General = new GeneralConfig(ConfigurationManager.GetSection("General") as NameValueCollection);
ExternalInterface = new ExternalInterfaceConfig(ConfigurationManager.GetSection("ExternalInterface") as NameValueCollection);
EventGenerators = EventGeneratorsConfigurationSection.Configuration.ConfigurationElements.ToList();
AgentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
catch (ArgumentNullException ex)
{
throw new AgentException(ExceptionCodes.LocalConfiguration, ExceptionSubCodes.MissingConfiguration, $"Key: {ex.ParamName}");
}
catch (ArgumentOutOfRangeException ex)
{
throw new AgentException(ExceptionCodes.LocalConfiguration, ExceptionSubCodes.CantParseConfiguration, $"Key: {ex.ParamName}");
}
}
}
}
Loading

0 comments on commit ee80afc

Please sign in to comment.