diff --git a/src/Promitor.Core.Scraping/Configuration/Providers/MetricsDeclarationProvider.cs b/src/Promitor.Core.Scraping/Configuration/Providers/MetricsDeclarationProvider.cs index e47ef2c66..03f2d7ab9 100644 --- a/src/Promitor.Core.Scraping/Configuration/Providers/MetricsDeclarationProvider.cs +++ b/src/Promitor.Core.Scraping/Configuration/Providers/MetricsDeclarationProvider.cs @@ -7,6 +7,7 @@ using Promitor.Core.Scraping.Configuration.Model; using Promitor.Core.Scraping.Configuration.Providers.Interfaces; using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; namespace Promitor.Core.Scraping.Configuration.Providers { @@ -15,9 +16,9 @@ public class MetricsDeclarationProvider : IMetricsDeclarationProvider private readonly ConfigurationSerializer _configurationSerializer; private readonly IConfiguration _configuration; - public MetricsDeclarationProvider(IConfiguration configuration, ILogger logger, IMapper mapper) + public MetricsDeclarationProvider(IConfiguration configuration, ILogger logger, IMapper mapper, IDeserializer v1Deserializer) { - _configurationSerializer = new ConfigurationSerializer(logger, mapper); + _configurationSerializer = new ConfigurationSerializer(logger, mapper, v1Deserializer); _configuration = configuration; } @@ -42,7 +43,7 @@ public virtual MetricsDeclaration Get(bool applyDefaults = false) } if (metric.AzureMetricConfiguration?.Aggregation.Interval == null) { - metric.AzureMetricConfiguration.Aggregation.Interval = config.MetricDefaults.Aggregation.Interval; + metric.AzureMetricConfiguration.Aggregation.Interval = config.MetricDefaults.Aggregation?.Interval; } // Apply the default scraping interval if none is specified diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/ConfigurationSerializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/ConfigurationSerializer.cs index e399c2ea4..c47c5367c 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/ConfigurationSerializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/ConfigurationSerializer.cs @@ -17,11 +17,13 @@ public class ConfigurationSerializer { private readonly ILogger _logger; private readonly IMapper _mapper; + private readonly IDeserializer _v1Deserializer; - public ConfigurationSerializer(ILogger logger, IMapper mapper) + public ConfigurationSerializer(ILogger logger, IMapper mapper, IDeserializer v1Deserializer) { _logger = logger; _mapper = mapper; + _v1Deserializer = v1Deserializer; } public MetricsDeclaration Deserialize(string rawMetricsDeclaration) @@ -55,8 +57,7 @@ private MetricsDeclaration InterpretYamlStream(YamlStream metricsDeclarationYaml switch (specVersion) { case SpecVersion.v1: - var v1Serializer = new v1.Core.ConfigurationSerializer(_logger); - var v1Config = v1Serializer.InterpretYamlStream(rootNode); + var v1Config = _v1Deserializer.Deserialize(rootNode); return _mapper.Map(v1Config); default: @@ -81,21 +82,7 @@ private SpecVersion DetermineDeclarationSpecVersion(YamlMappingNode mappingNode) return (SpecVersion)specVersion; } - public string Serialize(MetricsDeclaration metricsDeclaration) - { - Guard.NotNull(metricsDeclaration, nameof(metricsDeclaration)); - - var serializer = YamlSerialization.CreateSerializer(); - var rawMetricsDeclaration = serializer.Serialize(metricsDeclaration); - return rawMetricsDeclaration; - } - - /// - /// Allows a v1 version of the config to be serialized. - /// - /// A v1 version of the config. - /// The serialized yaml. - public string Serialize(MetricsDeclarationV1 metricsDeclaration) + public string Serialize(object metricsDeclaration) { Guard.NotNull(metricsDeclaration, nameof(metricsDeclaration)); diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/Deserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/Deserializer.cs index 212a716bd..c48bb0c52 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/Deserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/Deserializer.cs @@ -6,20 +6,20 @@ namespace Promitor.Core.Scraping.Configuration.Serialization { - internal abstract class Deserializer + public abstract class Deserializer : IDeserializer { protected ILogger Logger { get; } - internal Deserializer(ILogger logger) + protected Deserializer(ILogger logger) { Guard.NotNull(logger, nameof(logger)); Logger = logger; } - internal abstract TObject Deserialize(YamlMappingNode node); + public abstract TObject Deserialize(YamlMappingNode node); - internal List Deserialize(YamlSequenceNode nodes) + public List Deserialize(YamlSequenceNode nodes) { Guard.NotNull(nodes, nameof(nodes)); diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/IDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/IDeserializer.cs new file mode 100644 index 000000000..cb51130e4 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/IDeserializer.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization +{ + /// + /// An object that can deserialize a yaml node into an object. + /// + /// The type of object that can be deserialized. + public interface IDeserializer + { + /// + /// Deserializes the specified node. + /// + /// The node to deserialize. + /// The deserialized object. + TObject Deserialize(YamlMappingNode node); + + /// + /// Deserializes an array of elements. + /// + /// The node to deserialize. + /// The deserialized objects. + List Deserialize(YamlSequenceNode node); + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/YamlMappingNodeExtensions.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/YamlMappingNodeExtensions.cs new file mode 100644 index 000000000..f9a2e1c67 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/YamlMappingNodeExtensions.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization +{ + public static class YamlMappingNodeExtensions + { + /// + /// Gets the string value of the specified yaml property. + /// + /// The node containing the property. + /// The name of the property. + /// The string value of the property. + public static string GetString(this YamlMappingNode node, string propertyName) + { + if (node.Children.TryGetValue(propertyName, out var propertyNode)) + { + return propertyNode.ToString(); + } + + return null; + } + + /// + /// Gets the value of the specified yaml property converted to an enum. + /// + /// The type of enum to return. + /// The node containing the property. + /// The property name. + /// The enum value, or null if the property doesn't exist. + public static TEnum? GetEnum(this YamlMappingNode node, string propertyName) + where TEnum: struct + { + if (node.Children.TryGetValue(propertyName, out var propertyNode)) + { + return System.Enum.Parse(propertyNode.ToString()); + } + + return null; + } + + /// + /// Gets the contents of the specified property as a dictionary. + /// + /// The node containing the property. + /// The name of the property. + /// The child items of the property as a dictionary. + public static Dictionary GetDictionary(this YamlMappingNode node, string propertyName) + { + if (node.Children.TryGetValue(propertyName, out var propertyNode)) + { + var result = new Dictionary(); + + foreach (var (key, value) in ((YamlMappingNode) propertyNode).Children) + { + result[key.ToString()] = value.ToString(); + } + + return result; + } + + return null; + } + + /// + /// Gets the value of the specified yaml property converted to a . + /// + /// The node containing the property. + /// The name of the property. + /// The value converted to a timespan, or null if the property doesn't exist. + public static TimeSpan? GetTimeSpan(this YamlMappingNode node, string propertyName) + { + if (node.Children.TryGetValue(propertyName, out var propertyNode)) + { + return TimeSpan.Parse(propertyNode.ToString()); + } + + return null; + } + + /// + /// Deserializes a child object using the specified deserializer. + /// + /// The type of object to deserialize. + /// The yaml node. + /// The name of the property to deserialize. + /// The deserializer to use. + /// The deserialized property, or null if the property does not exist. + public static TObject DeserializeChild( + this YamlMappingNode node, string propertyName, IDeserializer deserializer) + where TObject: class + { + if (node.Children.TryGetValue(propertyName, out var propertyNode)) + { + return deserializer.Deserialize((YamlMappingNode)propertyNode); + } + + return null; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AggregationDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AggregationDeserializer.cs index f0f336b07..01b8f74bb 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AggregationDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AggregationDeserializer.cs @@ -5,30 +5,31 @@ namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class AggregationDeserializer : Deserializer + public class AggregationDeserializer : Deserializer { - internal AggregationDeserializer(ILogger logger) : base(logger) + private const string IntervalTag = "interval"; + + private readonly TimeSpan _defaultAggregationInterval = TimeSpan.FromMinutes(5); + + public AggregationDeserializer(ILogger logger) : base(logger) { } - internal override AggregationV1 Deserialize(YamlMappingNode node) + public override AggregationV1 Deserialize(YamlMappingNode node) { - var aggregation = new AggregationV1(); + var interval = node.GetTimeSpan(IntervalTag); - var interval = TimeSpan.FromMinutes(5); - if (node.Children.ContainsKey("interval")) - { - var rawIntervalNode = node.Children[new YamlScalarNode("interval")]; - interval = TimeSpan.Parse(rawIntervalNode.ToString()); - } - else + var aggregation = new AggregationV1 {Interval = interval}; + + if (aggregation.Interval == null) { - Logger.LogWarning("No default aggregation was configured, falling back to {AggregationInterval}", interval.ToString("g")); + aggregation.Interval = _defaultAggregationInterval; + Logger.LogWarning( + "No default aggregation was configured, falling back to {AggregationInterval}", + aggregation.Interval?.ToString("g")); } - aggregation.Interval = interval; - return aggregation; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetadataDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetadataDeserializer.cs index 89a985eff..3f92bc019 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetadataDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetadataDeserializer.cs @@ -1,32 +1,28 @@ -using GuardNet; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class AzureMetadataDeserializer : Deserializer + public class AzureMetadataDeserializer : Deserializer { - internal AzureMetadataDeserializer(ILogger logger) : base(logger) + private const string TenantIdTag = "tenantId"; + private const string SubscriptionIdTag = "subscriptionId"; + private const string ResourceGroupNameTag = "resourceGroupName"; + + public AzureMetadataDeserializer(ILogger logger) : base(logger) { } - internal override AzureMetadataV1 Deserialize(YamlMappingNode node) + public override AzureMetadataV1 Deserialize(YamlMappingNode node) { - Guard.NotNull(node, nameof(node)); - - var tenantId = node.Children[new YamlScalarNode("tenantId")]; - var subscriptionId = node.Children[new YamlScalarNode("subscriptionId")]; - var resourceGroupName = node.Children[new YamlScalarNode("resourceGroupName")]; - - var azureMetadata = new AzureMetadataV1 - { - TenantId = tenantId?.ToString(), - SubscriptionId = subscriptionId?.ToString(), - ResourceGroupName = resourceGroupName?.ToString() - }; + var metadata = new AzureMetadataV1(); - return azureMetadata; + metadata.TenantId = node.GetString(TenantIdTag); + metadata.SubscriptionId = node.GetString(SubscriptionIdTag); + metadata.ResourceGroupName = node.GetString(ResourceGroupNameTag); + + return metadata; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetricConfigurationDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetricConfigurationDeserializer.cs index 0ff0a180c..3f963b36b 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetricConfigurationDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureMetricConfigurationDeserializer.cs @@ -1,41 +1,38 @@ -using GuardNet; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class AzureMetricConfigurationDeserializer : Deserializer + public class AzureMetricConfigurationDeserializer : Deserializer { - private readonly MetricAggregationDeserializer _metricAggregationDeserializer; - private readonly YamlScalarNode _metricNode = new YamlScalarNode("metricName"); - private readonly YamlScalarNode _aggregationNode = new YamlScalarNode("aggregation"); + private const string MetricNameTag = "metricName"; + private const string AggregationTag = "aggregation"; + private readonly IDeserializer _aggregationDeserializer; - internal AzureMetricConfigurationDeserializer(ILogger logger) : base(logger) + public AzureMetricConfigurationDeserializer(IDeserializer aggregationDeserializer, ILogger logger) + : base(logger) { - _metricAggregationDeserializer = new MetricAggregationDeserializer(logger); + _aggregationDeserializer = aggregationDeserializer; } - internal override AzureMetricConfigurationV1 Deserialize(YamlMappingNode node) + public override AzureMetricConfigurationV1 Deserialize(YamlMappingNode node) { - Guard.NotNull(node, nameof(node)); - - var metricName = node.Children[_metricNode]; - - MetricAggregationV1 metricAggregation = null; - if (node.Children.ContainsKey(_aggregationNode)) + return new AzureMetricConfigurationV1 { - var aggregationNode = (YamlMappingNode) node.Children[_aggregationNode]; - metricAggregation = _metricAggregationDeserializer.Deserialize(aggregationNode); - } + MetricName = node.GetString(MetricNameTag), + Aggregation = DeserializeAggregation(node) + }; + } - var azureMetricConfiguration = new AzureMetricConfigurationV1 + private MetricAggregationV1 DeserializeAggregation(YamlMappingNode node) + { + if (node.Children.TryGetValue(AggregationTag, out var aggregationNode)) { - MetricName = metricName?.ToString(), - Aggregation = metricAggregation - }; + return _aggregationDeserializer.Deserialize((YamlMappingNode) aggregationNode); + } - return azureMetricConfiguration; + return null; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureResourceDeserializerFactory.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureResourceDeserializerFactory.cs new file mode 100644 index 000000000..f292cfc97 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/AzureResourceDeserializerFactory.cs @@ -0,0 +1,49 @@ +using System; +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core +{ + public class AzureResourceDeserializerFactory : IAzureResourceDeserializerFactory + { + private readonly IDeserializer _secretDeserializer; + private readonly ILogger _logger; + + public AzureResourceDeserializerFactory(IDeserializer secretDeserializer, ILogger logger) + { + _secretDeserializer = secretDeserializer; + _logger = logger; + } + + public IDeserializer GetDeserializerFor(ResourceType resourceType) + { + switch (resourceType) + { + case ResourceType.ServiceBusQueue: + return new ServiceBusQueueDeserializer(_logger); + case ResourceType.Generic: + return new GenericResourceDeserializer(_logger); + case ResourceType.StorageQueue: + return new StorageQueueDeserializer(_secretDeserializer, _logger); + case ResourceType.ContainerInstance: + return new ContainerInstanceDeserializer(_logger); + case ResourceType.VirtualMachine: + return new VirtualMachineDeserializer(_logger); + case ResourceType.ContainerRegistry: + return new ContainerRegistryDeserializer(_logger); + case ResourceType.NetworkInterface: + return new NetworkInterfaceDeserializer(_logger); + case ResourceType.CosmosDb: + return new CosmosDbDeserializer(_logger); + case ResourceType.RedisCache: + return new RedisCacheDeserializer(_logger); + case ResourceType.PostgreSql: + return new PostgreSqlDeserializer(_logger); + default: + throw new ArgumentOutOfRangeException($"Resource Type {resourceType} not supported."); + } + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ConfigurationSerializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ConfigurationSerializer.cs deleted file mode 100644 index 0a63206a2..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ConfigurationSerializer.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using Microsoft.Extensions.Logging; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core -{ - public class ConfigurationSerializer - { - public ConfigurationSerializer(ILogger logger) - { - Logger = logger; - } - - public ILogger Logger { get; } - - public MetricsDeclarationV1 InterpretYamlStream(YamlMappingNode rootNode) - { - AzureMetadataV1 azureMetadata = null; - if (rootNode.Children.ContainsKey("azureMetadata")) - { - var azureMetadataNode = (YamlMappingNode) rootNode.Children[new YamlScalarNode("azureMetadata")]; - var azureMetadataSerializer = new AzureMetadataDeserializer(Logger); - azureMetadata = azureMetadataSerializer.Deserialize(azureMetadataNode); - } - - MetricDefaultsV1 metricDefaults = null; - if (rootNode.Children.ContainsKey("metricDefaults")) - { - var metricDefaultsNode = (YamlMappingNode) rootNode.Children[new YamlScalarNode("metricDefaults")]; - var metricDefaultsSerializer = new MetricDefaultsDeserializer(Logger); - metricDefaults = metricDefaultsSerializer.Deserialize(metricDefaultsNode); - } - - List metrics = null; - if (rootNode.Children.ContainsKey("metrics")) - { - var metricsNode = (YamlSequenceNode) rootNode.Children[new YamlScalarNode("metrics")]; - var metricsDeserializer = new MetricsDeserializer(Logger); - metrics = metricsDeserializer.Deserialize(metricsNode); - } - - var metricsDeclaration = new MetricsDeclarationV1 - { - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = metrics - }; - - return metricsDeclaration; - } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/IAzureResourceDeserializerFactory.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/IAzureResourceDeserializerFactory.cs new file mode 100644 index 000000000..dcc9b2e44 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/IAzureResourceDeserializerFactory.cs @@ -0,0 +1,19 @@ +using Promitor.Core.Scraping.Configuration.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core +{ + /// + /// A factory for creating deserializers that can create + /// objects. + /// + public interface IAzureResourceDeserializerFactory + { + /// + /// Gets a deserializer that can deserializer the specified type of resource. + /// + /// The type of resource. + /// The deserializer. + IDeserializer GetDeserializerFor(ResourceType resourceType); + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricAggregationDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricAggregationDeserializer.cs index 306ecca14..189ad607b 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricAggregationDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricAggregationDeserializer.cs @@ -1,40 +1,30 @@ -using System; -using Microsoft.Azure.Management.Monitor.Fluent.Models; +using Microsoft.Azure.Management.Monitor.Fluent.Models; using Microsoft.Extensions.Logging; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class MetricAggregationDeserializer : Deserializer + public class MetricAggregationDeserializer : Deserializer { - private readonly YamlScalarNode _typeNode = new YamlScalarNode("type"); - private readonly YamlScalarNode _intervalNode = new YamlScalarNode("interval"); + private const string TypeTag = "type"; + private const string IntervalTag = "interval"; - internal MetricAggregationDeserializer(ILogger logger) : base(logger) + public MetricAggregationDeserializer(ILogger logger) : base(logger) { } - internal override MetricAggregationV1 Deserialize(YamlMappingNode node) + public override MetricAggregationV1 Deserialize(YamlMappingNode node) { - var aggregation = new MetricAggregationV1(); + var aggregationType = node.GetEnum(TypeTag); - if (node.Children.ContainsKey(_intervalNode.Value)) - { - var rawIntervalNode = node.Children[_intervalNode.Value]; - aggregation.Interval = TimeSpan.Parse(rawIntervalNode.ToString()); - } + var interval = node.GetTimeSpan(IntervalTag); - if (node.Children.ContainsKey(_typeNode.Value)) + return new MetricAggregationV1 { - var rawTypeNode = node.Children[_typeNode]; - if (System.Enum.TryParse(rawTypeNode?.ToString(), out AggregationType aggregationType)) - { - aggregation.Type = aggregationType; - } - } - - return aggregation; + Type = aggregationType, + Interval = interval + }; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefaultsDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefaultsDeserializer.cs index 56bdd0943..7c2ff47f4 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefaultsDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefaultsDeserializer.cs @@ -1,39 +1,34 @@ -using GuardNet; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class MetricDefaultsDeserializer : Deserializer + public class MetricDefaultsDeserializer : Deserializer { - internal MetricDefaultsDeserializer(ILogger logger) : base(logger) + private const string AggregationTag = "aggregation"; + private const string ScrapingTag = "scraping"; + + private readonly IDeserializer _aggregationDeserializer; + private readonly IDeserializer _scrapingDeserializer; + + public MetricDefaultsDeserializer( + IDeserializer aggregationDeserializer, + IDeserializer scrapingDeserializer, + ILogger logger) : base(logger) { + _aggregationDeserializer = aggregationDeserializer; + _scrapingDeserializer = scrapingDeserializer; } - internal override MetricDefaultsV1 Deserialize(YamlMappingNode node) + public override MetricDefaultsV1 Deserialize(YamlMappingNode node) { - Guard.NotNull(node, nameof(node)); - - var metricDefaults = new MetricDefaultsV1(); - - if (node.Children.ContainsKey("aggregation")) - { - var metricDefaultsNode = (YamlMappingNode)node.Children[new YamlScalarNode("aggregation")]; - var metricDefaultsSerializer = new AggregationDeserializer(Logger); - var aggregationBuilder = metricDefaultsSerializer.Deserialize(metricDefaultsNode); - metricDefaults.Aggregation = aggregationBuilder; - } + var defaults = new MetricDefaultsV1(); - if (node.Children.ContainsKey(@"scraping")) - { - var scrapingNode = (YamlMappingNode)node.Children[new YamlScalarNode("scraping")]; - var scrapingDeserializer = new ScrapingDeserializer(Logger); - var scrapingBuilder = scrapingDeserializer.Deserialize(scrapingNode); - metricDefaults.Scraping = scrapingBuilder; - } + defaults.Aggregation = node.DeserializeChild(AggregationTag, _aggregationDeserializer); + defaults.Scraping = node.DeserializeChild(ScrapingTag, _scrapingDeserializer); - return metricDefaults; + return defaults; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefinitionDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefinitionDeserializer.cs new file mode 100644 index 000000000..cd794e6a2 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDefinitionDeserializer.cs @@ -0,0 +1,82 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core +{ + public class MetricDefinitionDeserializer : Deserializer + { + private const string NameTag = "name"; + private const string DescriptionTag = "description"; + private const string ResourceTypeTag = "resourceType"; + private const string LabelsTag = "labels"; + private const string AzureMetricConfigurationTag = "azureMetricConfiguration"; + private const string ScrapingTag = "scraping"; + private const string ResourcesTag = "resources"; + + private readonly IDeserializer _azureMetricConfigurationDeserializer; + private readonly IDeserializer _scrapingDeserializer; + private readonly IAzureResourceDeserializerFactory _azureResourceDeserializerFactory; + + public MetricDefinitionDeserializer(IDeserializer azureMetricConfigurationDeserializer, + IDeserializer scrapingDeserializer, + IAzureResourceDeserializerFactory azureResourceDeserializerFactory, + ILogger logger) : base(logger) + { + _azureMetricConfigurationDeserializer = azureMetricConfigurationDeserializer; + _scrapingDeserializer = scrapingDeserializer; + _azureResourceDeserializerFactory = azureResourceDeserializerFactory; + } + + public override MetricDefinitionV1 Deserialize(YamlMappingNode node) + { + var name = node.GetString(NameTag); + var description = node.GetString(DescriptionTag); + var resourceType = node.GetEnum(ResourceTypeTag); + var labels = node.GetDictionary(LabelsTag); + + var metricDefinition = new MetricDefinitionV1 + { + Name = name, + Description = description, + ResourceType = resourceType, + Labels = labels + }; + + DeserializeAzureMetricConfiguration(node, metricDefinition); + DeserializeScraping(node, metricDefinition); + DeserializeMetrics(node, metricDefinition); + + return metricDefinition; + } + + private void DeserializeAzureMetricConfiguration(YamlMappingNode node, MetricDefinitionV1 metricDefinition) + { + if (node.Children.TryGetValue(AzureMetricConfigurationTag, out var configurationNode)) + { + metricDefinition.AzureMetricConfiguration = + _azureMetricConfigurationDeserializer.Deserialize((YamlMappingNode) configurationNode); + } + } + + private void DeserializeScraping(YamlMappingNode node, MetricDefinitionV1 metricDefinition) + { + if (node.Children.TryGetValue(ScrapingTag, out var scrapingNode)) + { + metricDefinition.Scraping = _scrapingDeserializer.Deserialize((YamlMappingNode)scrapingNode); + } + } + + private void DeserializeMetrics(YamlMappingNode node, MetricDefinitionV1 metricDefinition) + { + if (metricDefinition.ResourceType != null && + metricDefinition.ResourceType != ResourceType.NotSpecified && + node.Children.TryGetValue(ResourcesTag, out var metricsNode)) + { + var resourceDeserializer = _azureResourceDeserializerFactory.GetDeserializerFor(metricDefinition.ResourceType.Value); + metricDefinition.Resources = resourceDeserializer.Deserialize((YamlSequenceNode)metricsNode); + } + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDeserializer.cs deleted file mode 100644 index 6e07ae48b..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricDeserializer.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using GuardNet; -using Microsoft.Extensions.Logging; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core -{ - internal abstract class MetricDeserializer - { - protected ILogger Logger { get; private set; } - - internal MetricDeserializer WithLogger(ILogger logger) - { - Guard.NotNull(logger, nameof(logger)); - - Logger = logger; - return this; - } - - internal abstract MetricDefinitionV1 Deserialize(YamlMappingNode metricNode); - - protected virtual TMetricDefinition DeserializeMetricDefinition(YamlMappingNode metricNode) - where TMetricDefinition : MetricDefinitionV1, new() - { - Guard.NotNull(metricNode, nameof(metricNode)); - - var name = metricNode.Children[new YamlScalarNode("name")]; - var description = metricNode.Children[new YamlScalarNode("description")]; - - var azureMetricConfigurationNode = (YamlMappingNode)metricNode.Children[new YamlScalarNode("azureMetricConfiguration")]; - - var azureMetricConfigurationDeserializer = new AzureMetricConfigurationDeserializer(Logger); - var azureMetricConfiguration = azureMetricConfigurationDeserializer.Deserialize(azureMetricConfigurationNode); - var metricDefinition = new TMetricDefinition - { - Name = name?.ToString(), - Description = description?.ToString(), - AzureMetricConfiguration = azureMetricConfiguration, - ResourceGroupName = GetResourceGroupName(metricNode) - }; - - DeserializeScraping(metricNode, metricDefinition); - DeserializeCustomLabels(metricNode, metricDefinition); - - return metricDefinition; - } - - private static string GetResourceGroupName(YamlMappingNode metricNode) - { - if (metricNode.Children.TryGetValue("resourceGroupName", out var resourceGroupNode)) - { - return resourceGroupNode.ToString(); - } - - return null; - } - - private static void DeserializeScraping(YamlMappingNode metricNode, TMetricDefinition metricDefinition) where TMetricDefinition : MetricDefinitionV1, new() - { - if (metricNode.Children.ContainsKey(@"scraping") == false) - { - return; - } - - var scrapingNode = (YamlMappingNode)metricNode.Children[new YamlScalarNode(@"scraping")]; - try - { - var scrapingIntervalNode = scrapingNode?.Children[new YamlScalarNode(@"schedule")]; - - if (scrapingIntervalNode != null) - { - metricDefinition.Scraping.Schedule = scrapingIntervalNode.ToString(); - } - } - catch (KeyNotFoundException) - { - // happens when the YAML doesn't have the properties in it which is fine because the object - // will get a default interval of 'null' - } - } - - private static void DeserializeCustomLabels(YamlMappingNode metricNode, TMetricDefinition metricDefinition) where TMetricDefinition : MetricDefinitionV1, new() - { - if (metricNode.Children.ContainsKey(@"labels") == false) - { - return; - } - - var labelNode = (YamlMappingNode)metricNode.Children[new YamlScalarNode(@"labels")]; - foreach (KeyValuePair customLabel in labelNode.Children) - { - var labelName = customLabel.Key.ToString(); - var labelValue = customLabel.Value.ToString(); - - if (metricDefinition.Labels.ContainsKey(labelName)) - { - if (metricDefinition.Labels[labelName] == labelValue) - { - continue; - } - - throw new Exception($"Label '{labelName}' is already defined with value '{metricDefinition.Labels[labelName]}' instead of '{labelValue}'"); - } - - metricDefinition.Labels.Add(labelName, labelValue); - } - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricsDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricsDeserializer.cs deleted file mode 100644 index 8505cfc3e..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/MetricsDeserializer.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Factories; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core -{ - internal class MetricsDeserializer : Deserializer - { - internal MetricsDeserializer(ILogger logger) : base(logger) - { - } - - internal override MetricDefinitionV1 Deserialize(YamlMappingNode node) - { - var rawResourceType = node.Children[new YamlScalarNode("resourceType")]; - - if (!System.Enum.TryParse(rawResourceType.ToString(), out var resourceType)) - { - throw new ArgumentException($@"Unknown 'resourceType' value in metric configuration: {rawResourceType}"); - } - - return MetricDeserializerFactory - .GetDeserializerFor(resourceType) - .WithLogger(Logger) - .Deserialize(node); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ScrapingDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ScrapingDeserializer.cs index 98b8538dc..6f46a6cf9 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ScrapingDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/ScrapingDeserializer.cs @@ -1,24 +1,24 @@ using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class ScrapingDeserializer : Deserializer + public class ScrapingDeserializer : Deserializer { - internal ScrapingDeserializer(ILogger logger) : base(logger) + private const string ScheduleTag = "schedule"; + + public ScrapingDeserializer(ILogger logger) : base(logger) { } - internal override Model.ScrapingV1 Deserialize(YamlMappingNode node) + public override ScrapingV1 Deserialize(YamlMappingNode node) { - var scraping = new Model.ScrapingV1(); + var scraping = new ScrapingV1(); - if (node.Children.ContainsKey("schedule")) - { - var rawScheduleNode = node.Children[new YamlScalarNode("schedule")]; - scraping.Schedule = rawScheduleNode.ToString(); - } - else + scraping.Schedule = node.GetString(ScheduleTag); + + if (scraping.Schedule == null) { Logger.LogError("No default metric scraping schedule was configured!"); } diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/SecretDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/SecretDeserializer.cs index 19bda9eb6..70d4b3500 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/SecretDeserializer.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/SecretDeserializer.cs @@ -1,29 +1,32 @@ using Microsoft.Extensions.Logging; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using YamlDotNet.RepresentationModel; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core { - internal class SecretDeserializer : Deserializer + public class SecretDeserializer : Deserializer { - internal SecretDeserializer(ILogger logger) : base(logger) + private const string RawValueTag = "rawValue"; + private const string EnvironmentVariableTag = "environmentVariable"; + + public SecretDeserializer(ILogger logger) : base(logger) { } - internal override SecretV1 Deserialize(YamlMappingNode node) + public override SecretV1 Deserialize(YamlMappingNode node) { - var secret = new SecretV1(); + var rawValue = node.GetString(RawValueTag); + var environmentVariable = node.GetString(EnvironmentVariableTag); - if (node.Children.ContainsKey("rawValue")) + var secret = new SecretV1 { - var rawValueNode = node.Children[new YamlScalarNode("rawValue")]; - secret.RawValue = rawValueNode.ToString(); - } + RawValue = rawValue, + EnvironmentVariable = environmentVariable + }; - if (node.Children.ContainsKey("environmentVariable")) + if (!string.IsNullOrEmpty(secret.RawValue) && !string.IsNullOrEmpty(secret.EnvironmentVariable)) { - var rawEnvironmentVariable = node.Children[new YamlScalarNode("environmentVariable")]; - secret.EnvironmentVariable = rawEnvironmentVariable.ToString(); + Logger.LogWarning("Secret with environment variable '{EnvironmentVariable}' also has a rawValue provided.", secret.EnvironmentVariable); } return secret; diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/V1Deserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/V1Deserializer.cs new file mode 100644 index 000000000..a8905837c --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Core/V1Deserializer.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.Enum; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Core +{ + public class V1Deserializer : Deserializer + { + private readonly IDeserializer _azureMetadataDeserializer; + private readonly IDeserializer _defaultsDeserializer; + private readonly IDeserializer _metricsDeserializer; + + public V1Deserializer(IDeserializer azureMetadataDeserializer, + IDeserializer defaultsDeserializer, + IDeserializer metricsDeserializer, + ILogger logger) : base(logger) + { + _azureMetadataDeserializer = azureMetadataDeserializer; + _defaultsDeserializer = defaultsDeserializer; + _metricsDeserializer = metricsDeserializer; + } + + public override MetricsDeclarationV1 Deserialize(YamlMappingNode rootNode) + { + ValidateVersion(rootNode); + + var azureMetadata = DeserializeAzureMetadata(rootNode); + var metricDefaults = DeserializeMetricDefaults(rootNode); + var metrics = DeserializeMetrics(rootNode); + + return new MetricsDeclarationV1 + { + Version = SpecVersion.v1.ToString(), + AzureMetadata = azureMetadata, + MetricDefaults = metricDefaults, + Metrics = metrics + }; + } + + private static void ValidateVersion(YamlMappingNode rootNode) + { + var versionFound = rootNode.Children.TryGetValue("version", out var versionNode); + if (!versionFound) + { + throw new System.Exception("No 'version' element was found in the metrics config"); + } + + if (versionNode.ToString() != SpecVersion.v1.ToString()) + { + throw new System.Exception($"A 'version' element with a value of '{SpecVersion.v1}' was expected but the value '{versionNode}' was found"); + } + } + + private AzureMetadataV1 DeserializeAzureMetadata(YamlMappingNode rootNode) + { + if (rootNode.Children.TryGetValue("azureMetadata", out var azureMetadataNode)) + { + return _azureMetadataDeserializer.Deserialize((YamlMappingNode)azureMetadataNode); + } + + return null; + } + + private MetricDefaultsV1 DeserializeMetricDefaults(YamlMappingNode rootNode) + { + if (rootNode.Children.TryGetValue("metricDefaults", out var defaultsNode)) + { + return _defaultsDeserializer.Deserialize((YamlMappingNode)defaultsNode); + } + + return null; + } + + private List DeserializeMetrics(YamlMappingNode rootNode) + { + if (rootNode.Children.TryGetValue("metrics", out var metricsNode)) + { + return _metricsDeserializer.Deserialize((YamlSequenceNode)metricsNode); + } + + return null; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Mapping/V1MappingProfile.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Mapping/V1MappingProfile.cs index e28e4afe2..39d151281 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Mapping/V1MappingProfile.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Mapping/V1MappingProfile.cs @@ -1,11 +1,9 @@ -using System.Collections.Generic; -using AutoMapper; +using AutoMapper; using Promitor.Core.Scraping.Configuration.Model; using Promitor.Core.Scraping.Configuration.Model.Metrics; using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping { @@ -22,37 +20,34 @@ public V1MappingProfile() CreateMap(); CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap() + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap() .ForCtorParam("ns", o => o.MapFrom(s => s.Namespace)); - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap(); CreateMap(); - - // MetricDefinitionV1 gets expanded into several properties on MetricDefinition + CreateMap() - .ForMember(m => m.PrometheusMetricDefinition, o => o.MapFrom(v1 => v1)) - .ForMember(m => m.ResourceType, o => o.MapFrom(v1 => v1.ResourceType)) - .ForMember(m => m.Resources, o => o.MapFrom(v1 => new List {v1})); + .ForMember(m => m.PrometheusMetricDefinition, o => o.MapFrom(v1 => v1)); - CreateMap() - .Include() - .Include() - .Include() - .Include() - .Include() - .Include() - .Include() - .Include() - .Include() - .Include(); + CreateMap() + .Include() + .Include() + .Include() + .Include() + .Include() + .Include() + .Include() + .Include() + .Include() + .Include(); } } } diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AggregationV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AggregationV1.cs index 2cfcfaeb6..ce557a046 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AggregationV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AggregationV1.cs @@ -2,11 +2,14 @@ namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model { + /// + /// Contains aggregation settings used when querying Azure metrics. + /// public class AggregationV1 { /// - /// The time period the metric should be aggregated over. + /// The interval to use for aggregating the metric data when querying Azure metrics. /// public TimeSpan? Interval { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetadataV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetadataV1.cs index 6431a7788..cdaf01c9f 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetadataV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetadataV1.cs @@ -2,8 +2,8 @@ { public class AzureMetadataV1 { - public string ResourceGroupName { get; set; } - public string SubscriptionId { get; set; } public string TenantId { get; set; } + public string SubscriptionId { get; set; } + public string ResourceGroupName { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetricConfigurationV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetricConfigurationV1.cs index 52de2e704..02154aaf2 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetricConfigurationV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureMetricConfigurationV1.cs @@ -3,13 +3,13 @@ public class AzureMetricConfigurationV1 { /// - /// Name of the Azure Monitor metric to query + /// The name of the Azure metric to scrape. /// public string MetricName { get; set; } /// - /// Configuration on how to aggregate the metric + /// The settings for how the metric should be aggregated before being returned from Azure. /// public MetricAggregationV1 Aggregation { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureResourceDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureResourceDefinitionV1.cs new file mode 100644 index 000000000..f744c0495 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/AzureResourceDefinitionV1.cs @@ -0,0 +1,10 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model +{ + /// + /// Represents an Azure resource that can be scraped. + /// + public class AzureResourceDefinitionV1 + { + public string ResourceGroupName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricAggregationV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricAggregationV1.cs index 553d0f4b9..78e2d3c75 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricAggregationV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricAggregationV1.cs @@ -3,6 +3,9 @@ namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model { + /// + /// Contains aggregation settings for a single metric (vs the global aggregation settings). + /// public class MetricAggregationV1 { /// @@ -11,8 +14,8 @@ public class MetricAggregationV1 public TimeSpan? Interval { get; set; } /// - /// Type of aggregation to query the Azure Monitor metric + /// Type of aggregation to query the Azure Monitor metric. /// - public AggregationType Type { get; set; } + public AggregationType? Type { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefaultsV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefaultsV1.cs index 972a82af4..df12d2c66 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefaultsV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefaultsV1.cs @@ -1,9 +1,18 @@ namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model { + /// + /// Contains default settings that apply to all metrics. + /// public class MetricDefaultsV1 { - public AggregationV1 Aggregation { get; set; } = new AggregationV1(); - - public ScrapingV1 Scraping { get; set; } = new ScrapingV1(); + /// + /// The default aggregation settings to use when querying metrics from Azure. + /// + public AggregationV1 Aggregation { get; set; } + + /// + /// The default scraping settings. + /// + public ScrapingV1 Scraping { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefinitionV1.cs new file mode 100644 index 000000000..87f3eecf3 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricDefinitionV1.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using Promitor.Core.Scraping.Configuration.Model; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model +{ + /// + /// Contains the definition for a prometheus metric, along with the resources + /// that should be scraped to supply the metric. + /// + public class MetricDefinitionV1 + { + /// + /// The name of the prometheus metric. + /// + public string Name { get; set; } + + /// + /// The description of the prometheus metric. + /// + public string Description { get; set; } + + /// + /// The type of resources that are scraped to populate this metric. + /// + public ResourceType? ResourceType { get; set; } + + /// + /// Any prometheus labels that should be added to the metric. + /// + public Dictionary Labels { get; set; } + + /// + /// Contains the configuration used when querying Azure metrics. + /// + public AzureMetricConfigurationV1 AzureMetricConfiguration { get; set; } + + /// + /// Allows a custom scraping schedule to be specified for the metric. + /// + public ScrapingV1 Scraping { get; set; } + + /// + /// The resources to be scraped. + /// + public List Resources { get; set; } + } +} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/MetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/MetricDefinitionV1.cs deleted file mode 100644 index aa59ac63a..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/MetricDefinitionV1.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics -{ - public abstract class MetricDefinitionV1 - { - /// - /// Configuration about the Azure Monitor metric to scrape - /// - public AzureMetricConfigurationV1 AzureMetricConfiguration { get; set; } = new AzureMetricConfigurationV1(); - - /// - /// Description concerning metric that will be made available in the scraping endpoint - /// - public string Description { get; set; } - - /// - /// Name of the metric to use when exposing in the scraping endpoint - /// - public string Name { get; set; } - - /// - /// Specify a resource group to scrape that defers from the default resource group. - /// This enables you to do multi-resource group scraping with one configuration file. - /// - public string ResourceGroupName { get; set; } - - /// - /// Type of resource that is configured - /// - public abstract ResourceType ResourceType { get; } - - /// - /// Collection of custom labels to add to every metric - /// - public Dictionary Labels { get; set; } = new Dictionary(); - - /// - /// Gets or sets the scraping model. - /// - public ScrapingV1 Scraping { get; set; } = new ScrapingV1(); - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerInstanceMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerInstanceMetricDefinitionV1.cs deleted file mode 100644 index 581aa98cd..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerInstanceMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class ContainerInstanceMetricDefinitionV1 : MetricDefinitionV1 - { - public string ContainerGroup { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.ContainerInstance; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerRegistryMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerRegistryMetricDefinitionV1.cs deleted file mode 100644 index 203301a6d..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ContainerRegistryMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class ContainerRegistryMetricDefinitionV1 : MetricDefinitionV1 - { - public string RegistryName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.ContainerRegistry; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/CosmosDbMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/CosmosDbMetricDefinitionV1.cs deleted file mode 100644 index dc0ec12f8..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/CosmosDbMetricDefinitionV1.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class CosmosDbMetricDefinitionV1 : MetricDefinitionV1 - { - public string DbName { get; set; } - - public override ResourceType ResourceType { get; } = ResourceType.CosmosDb; - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/GenericAzureMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/GenericAzureMetricDefinitionV1.cs deleted file mode 100644 index 0a61150cb..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/GenericAzureMetricDefinitionV1.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class GenericAzureMetricDefinitionV1 : MetricDefinitionV1 - { - public string Filter { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.Generic; - public string ResourceUri { get; set; } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/NetworkInterfaceMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/NetworkInterfaceMetricDefinitionV1.cs deleted file mode 100644 index d350e7d48..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/NetworkInterfaceMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class NetworkInterfaceMetricDefinitionV1 : MetricDefinitionV1 - { - public string NetworkInterfaceName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.NetworkInterface; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/PostgreSqlMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/PostgreSqlMetricDefinitionV1.cs deleted file mode 100644 index 7be0e1bbc..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/PostgreSqlMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class PostgreSqlMetricDefinitionV1 : MetricDefinitionV1 - { - public string ServerName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.PostgreSql; - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/RedisCacheMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/RedisCacheMetricDefinitionV1.cs deleted file mode 100644 index 849202bb6..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/RedisCacheMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class RedisCacheMetricDefinitionV1 : MetricDefinitionV1 - { - public string CacheName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.RedisCache; - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ServiceBusQueueMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ServiceBusQueueMetricDefinitionV1.cs deleted file mode 100644 index 7148bcb60..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/ServiceBusQueueMetricDefinitionV1.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class ServiceBusQueueMetricDefinitionV1 : MetricDefinitionV1 - { - public string Namespace { get; set; } - public string QueueName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.ServiceBusQueue; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/StorageQueueMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/StorageQueueMetricDefinitionV1.cs deleted file mode 100644 index 4d5e99f96..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/StorageQueueMetricDefinitionV1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class StorageQueueMetricDefinitionV1 : MetricDefinitionV1 - { - public string AccountName { get; set; } - public string QueueName { get; set; } - public SecretV1 SasToken { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.StorageQueue; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/VirtualMachineMetricDefinitionV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/VirtualMachineMetricDefinitionV1.cs deleted file mode 100644 index 5088becf5..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/ResourceTypes/VirtualMachineMetricDefinitionV1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Model; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes -{ - public class VirtualMachineMetricDefinitionV1 : MetricDefinitionV1 - { - public string VirtualMachineName { get; set; } - public override ResourceType ResourceType { get; } = ResourceType.VirtualMachine; - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/SecretV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/SecretV1.cs deleted file mode 100644 index 5b474180b..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/Metrics/SecretV1.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics -{ - public class SecretV1 - { - public string RawValue { get; set; } - public string EnvironmentVariable { get; set; } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricsDeclarationV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricsDeclarationV1.cs index 401ae561c..e1dc6891d 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricsDeclarationV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/MetricsDeclarationV1.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model { + /// + /// Represents the metrics configuration file. + /// public class MetricsDeclarationV1 { public string Version { get; set; } = SpecVersion.v1.ToString(); - - public AzureMetadataV1 AzureMetadata { get; set; } = new AzureMetadataV1(); - - public MetricDefaultsV1 MetricDefaults { get; set; } = new MetricDefaultsV1(); - - public List Metrics { get; set; } = new List(); + public AzureMetadataV1 AzureMetadata { get; set; } + public MetricDefaultsV1 MetricDefaults { get; set; } + public List Metrics { get; set; } } -} \ No newline at end of file +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerInstanceResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerInstanceResourceV1.cs new file mode 100644 index 000000000..8f52927ce --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerInstanceResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a Container Instance. + /// + public class ContainerInstanceResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The container group name. + /// + public string ContainerGroup { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerRegistryResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerRegistryResourceV1.cs new file mode 100644 index 000000000..3153ba9a5 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ContainerRegistryResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a Container Registry. + /// + public class ContainerRegistryResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The name of the registry to scrape. + /// + public string RegistryName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/CosmosDbResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/CosmosDbResourceV1.cs new file mode 100644 index 000000000..eb9e2d39f --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/CosmosDbResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a Cosmos database. + /// + public class CosmosDbResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The cosmos database name. + /// + public string DbName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/GenericResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/GenericResourceV1.cs new file mode 100644 index 000000000..e6b6bf5b1 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/GenericResourceV1.cs @@ -0,0 +1,19 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape an Azure resource. This allows + /// any resource that doesn't have a custom provider to be scraped. + /// + public class GenericResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The filter for the Azure metric query. + /// + public string Filter { get; set; } + + /// + /// The URI for the resource to get metrics for. + /// + public string ResourceUri { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/NetworkInterfaceResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/NetworkInterfaceResourceV1.cs new file mode 100644 index 000000000..86ca30ec1 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/NetworkInterfaceResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a Network Interface. + /// + public class NetworkInterfaceResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The name of the network interface to scrape. + /// + public string NetworkInterfaceName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/PostgreSqlResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/PostgreSqlResourceV1.cs new file mode 100644 index 000000000..5b4875c3a --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/PostgreSqlResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a Postgre SQL database. + /// + public class PostgreSqlResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The postgre server name. + /// + public string ServerName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/RedisCacheResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/RedisCacheResourceV1.cs new file mode 100644 index 000000000..2e01a5bba --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/RedisCacheResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a redis cache. + /// + public class RedisCacheResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The name of the redis cache. + /// + public string CacheName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ServiceBusQueueResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ServiceBusQueueResourceV1.cs new file mode 100644 index 000000000..d91ec7d97 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/ServiceBusQueueResourceV1.cs @@ -0,0 +1,18 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a service bus queue. + /// + public class ServiceBusQueueResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The service bus queue to scrape. + /// + public string QueueName { get; set; } + + /// + /// The service bus namespace. + /// + public string Namespace { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/StorageQueueResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/StorageQueueResourceV1.cs new file mode 100644 index 000000000..4812f6af4 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/StorageQueueResourceV1.cs @@ -0,0 +1,23 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a storage queue. + /// + public class StorageQueueResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The storage queue account name. + /// + public string AccountName { get; set; } + + /// + /// The name of the queue. + /// + public string QueueName { get; set; } + + /// + /// The SAS token for accessing the queue. + /// + public SecretV1 SasToken { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/VirtualMachineResourceV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/VirtualMachineResourceV1.cs new file mode 100644 index 000000000..15bd90be7 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ResourceTypes/VirtualMachineResourceV1.cs @@ -0,0 +1,13 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes +{ + /// + /// Contains the configuration required to scrape a virtual machine. + /// + public class VirtualMachineResourceV1 : AzureResourceDefinitionV1 + { + /// + /// The name of the virtual machine to get metrics for. + /// + public string VirtualMachineName { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ScrapingV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ScrapingV1.cs index c01494265..1fac53d30 100644 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ScrapingV1.cs +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/ScrapingV1.cs @@ -1,7 +1,13 @@ namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model { + /// + /// Contains settings about how promitor scrapes Azure metrics. + /// public class ScrapingV1 { + /// + /// A cron expression describing how often scrapes should occur. + /// public string Schedule { get; set; } } } diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/SecretV1.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/SecretV1.cs new file mode 100644 index 000000000..66fa8154e --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Model/SecretV1.cs @@ -0,0 +1,17 @@ +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Model +{ + public class SecretV1 + { + /// + /// The value of the secret. If you don't want to put the secret value directly + /// in the metric configuration, use the property + /// instead. + /// + public string RawValue { get; set; } + + /// + /// The name of an environment variable to get the secret value from. + /// + public string EnvironmentVariable { get; set; } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceDeserializer.cs new file mode 100644 index 000000000..ec68f6b64 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class ContainerInstanceDeserializer : ResourceDeserializer + { + private const string ContainerGroupTag = "containerGroup"; + + public ContainerInstanceDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var containerGroup = node.GetString(ContainerGroupTag); + + return new ContainerInstanceResourceV1 + { + ContainerGroup = containerGroup + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceMetricDeserializer.cs deleted file mode 100644 index 5122faede..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerInstanceMetricDeserializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class ContainerInstanceMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Container Instances metric node from the YAML configuration file. - /// The metric node to deserialize to Container Instances configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var containerGroup = metricNode.Children[new YamlScalarNode("containerGroup")]; - metricDefinition.ContainerGroup = containerGroup?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryDeserializer.cs new file mode 100644 index 000000000..3dd1be082 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class ContainerRegistryDeserializer : ResourceDeserializer + { + private const string RegistryNameTag = "registryName"; + + public ContainerRegistryDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var registryName = node.GetString(RegistryNameTag); + + return new ContainerRegistryResourceV1 + { + RegistryName = registryName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryMetricDeserializer.cs deleted file mode 100644 index 7825a788e..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ContainerRegistryMetricDeserializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class ContainerRegistryMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Container Registry metric node from the YAML configuration file. - /// The metric node to deserialize to Container Registry configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var registryName = metricNode.Children[new YamlScalarNode("registryName")]; - metricDefinition.RegistryName = registryName?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbDeserializer.cs new file mode 100644 index 000000000..6582dde25 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class CosmosDbDeserializer : ResourceDeserializer + { + private const string DatabaseNameTag = "dbName"; + + public CosmosDbDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var databaseName = node.GetString(DatabaseNameTag); + + return new CosmosDbResourceV1 + { + DbName = databaseName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbMetricDeserializer.cs deleted file mode 100644 index ca24d7980..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/CosmosDbMetricDeserializer.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class CosmosDbMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Cosmos DB metric node from the YAML configuration file. - /// The metric node to deserialize to Cosmos DB configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var dbName = metricNode.Children[new YamlScalarNode("dbName")]; - - metricDefinition.DbName = dbName?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericAzureMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericAzureMetricDeserializer.cs deleted file mode 100644 index 32f6ca613..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericAzureMetricDeserializer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class GenericAzureMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Generic Azure metric node from the YAML configuration file. - /// The metric node to deserialize to query an arbitrary Azure resource - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - if (metricNode.Children.TryGetValue(new YamlScalarNode(value: "filter"), out var filterNode)) - { - metricDefinition.Filter = filterNode?.ToString(); - } - - var resourceUri = metricNode.Children[new YamlScalarNode(value: "resourceUri")]; - - metricDefinition.ResourceUri = resourceUri?.ToString(); - - return metricDefinition; - } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericResourceDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericResourceDeserializer.cs new file mode 100644 index 000000000..dadfda114 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/GenericResourceDeserializer.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class GenericResourceDeserializer : ResourceDeserializer + { + private const string FilterTag = "filter"; + private const string ResourceUriTag = "resourceUri"; + + public GenericResourceDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var filter = node.GetString(FilterTag); + var resourceUri = node.GetString(ResourceUriTag); + + return new GenericResourceV1 + { + Filter = filter, + ResourceUri = resourceUri + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceDeserializer.cs new file mode 100644 index 000000000..0c1ab380b --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class NetworkInterfaceDeserializer : ResourceDeserializer + { + private const string NetworkInterfaceNameTag = "networkInterfaceName"; + + public NetworkInterfaceDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var networkInterfaceName = node.GetString(NetworkInterfaceNameTag); + + return new NetworkInterfaceResourceV1 + { + NetworkInterfaceName = networkInterfaceName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceMetricDeserializer.cs deleted file mode 100644 index 841ad9674..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/NetworkInterfaceMetricDeserializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class NetworkInterfaceMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Network Interface metric node from the YAML configuration file. - /// The metric node containing 'networkInterfaceName' parameter pointing to an instance of a Network Interface - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - var networkInterfaceName = metricNode.Children[new YamlScalarNode("networkInterfaceName")]; - - metricDefinition.NetworkInterfaceName = networkInterfaceName?.ToString(); - - return metricDefinition; - } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlDeserializer.cs new file mode 100644 index 000000000..db165db9d --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class PostgreSqlDeserializer : ResourceDeserializer + { + private const string ServerNameTag = "serverName"; + + public PostgreSqlDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var serverName = node.GetString(ServerNameTag); + + return new PostgreSqlResourceV1 + { + ServerName = serverName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlMetricDeserializer.cs deleted file mode 100644 index 381c4ba5f..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/PostgreSqlMetricDeserializer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - /// - /// Defines a deserializer for the PostgreSQL Server resource type - /// - internal class PostgreSqlMetricDeserializer : MetricDeserializer - { - /// - /// Deserializes the specified PostgreSQL Server metric node from the YAML configuration file. - /// - /// The metric node to deserialize to PostgreSQL Server configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var serverName = metricNode.Children[new YamlScalarNode("serverName")]; - metricDefinition.ServerName = serverName?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheDeserializer.cs new file mode 100644 index 000000000..7131e6a47 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class RedisCacheDeserializer : ResourceDeserializer + { + private const string CacheNameTag = "cacheName"; + + public RedisCacheDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var cacheName = node.GetString(CacheNameTag); + + return new RedisCacheResourceV1 + { + CacheName = cacheName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheMetricDeserializer.cs deleted file mode 100644 index 212ff29ee..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/RedisCacheMetricDeserializer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - /// - /// Defines a deserializer for the Redis Cache resource type - /// - internal class RedisCacheMetricDeserializer : MetricDeserializer - { - /// - /// Deserializes the specified Redis Cache metric node from the YAML configuration file. - /// - /// The metric node to deserialize to Redis Cache configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var cacheName = metricNode.Children[new YamlScalarNode("cacheName")]; - metricDefinition.CacheName = cacheName?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ResourceDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ResourceDeserializer.cs new file mode 100644 index 000000000..f75d1f8da --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ResourceDeserializer.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + /// + /// A base class for azure resource deserializers that makes sure that any shared + /// properties are deserialized correctly for all resources. + /// + public abstract class ResourceDeserializer : Deserializer + { + private const string ResourceGroupNameTag = "resourceGroupName"; + + protected ResourceDeserializer(ILogger logger) : base(logger) + { + } + + public override AzureResourceDefinitionV1 Deserialize(YamlMappingNode node) + { + var resource = DeserializeResource(node); + + resource.ResourceGroupName = node.GetString(ResourceGroupNameTag); + + return resource; + } + + /// + /// Implement on subclasses to return the correct type of + /// object with all its custom properties populated. + /// + /// The yaml node. + /// The deserialized object. + protected abstract AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node); + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueDeserializer.cs new file mode 100644 index 000000000..9435fc474 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueDeserializer.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class ServiceBusQueueDeserializer : ResourceDeserializer + { + private const string QueueNameTag = "queueName"; + private const string NamespaceTag = "namespace"; + + public ServiceBusQueueDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var queueName = node.GetString(QueueNameTag); + var @namespace = node.GetString(NamespaceTag); + + return new ServiceBusQueueResourceV1 + { + QueueName = queueName, + Namespace = @namespace + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueMetricDeserializer.cs deleted file mode 100644 index 0333b9594..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/ServiceBusQueueMetricDeserializer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class ServiceBusQueueMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Service Bus Queue metric node from the YAML configuration file. - /// The metric node to deserialize to Service Bus queue - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - - var queueName = metricNode.Children[new YamlScalarNode("queueName")]; - var namespaceName = metricNode.Children[new YamlScalarNode("namespace")]; - - metricDefinition.QueueName = queueName?.ToString(); - metricDefinition.Namespace = namespaceName?.ToString(); - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueDeserializer.cs new file mode 100644 index 000000000..6a8731571 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueDeserializer.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class StorageQueueDeserializer : ResourceDeserializer + { + private const string AccountNameTag = "accountName"; + private const string QueueNameTag = "queueName"; + private const string SasTokenTag = "sasToken"; + + private readonly IDeserializer _secretDeserializer; + + public StorageQueueDeserializer(IDeserializer secretDeserializer, ILogger logger) : base(logger) + { + _secretDeserializer = secretDeserializer; + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var accountName = node.GetString(AccountNameTag); + var queueName = node.GetString(QueueNameTag); + var sasToken = node.DeserializeChild(SasTokenTag, _secretDeserializer); + + return new StorageQueueResourceV1 + { + AccountName = accountName, + QueueName = queueName, + SasToken = sasToken + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueMetricDeserializer.cs deleted file mode 100644 index bce8a98e0..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/StorageQueueMetricDeserializer.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.Extensions.Logging; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class StorageQueueMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Storage Queue metric node from the YAML configuration file. - /// The metric node to deserialize to Storage queue configuration - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - var accountName = metricNode.Children[new YamlScalarNode("accountName")]; - var queueName = metricNode.Children[new YamlScalarNode("queueName")]; - - metricDefinition.AccountName = accountName?.ToString(); - metricDefinition.QueueName = queueName?.ToString(); - - var secretDeserializer = new SecretDeserializer(Logger); - - if (metricNode.Children.ContainsKey("sasToken")) - { - var sasTokenNode = (YamlMappingNode)metricNode.Children["sasToken"]; - metricDefinition.SasToken = secretDeserializer.Deserialize(sasTokenNode); - } - else - { - Logger.LogError($"No SAS token was configured for Azure Storage Account '{accountName}'"); - } - - return metricDefinition; - } - } -} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineDeserializer.cs new file mode 100644 index 000000000..0e9b98a51 --- /dev/null +++ b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineDeserializer.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers +{ + public class VirtualMachineDeserializer : ResourceDeserializer + { + private const string VirtualMachineNameTag = "virtualMachineName"; + + public VirtualMachineDeserializer(ILogger logger) : base(logger) + { + } + + protected override AzureResourceDefinitionV1 DeserializeResource(YamlMappingNode node) + { + var virtualMachineName = node.GetString(VirtualMachineNameTag); + + return new VirtualMachineResourceV1 + { + VirtualMachineName = virtualMachineName + }; + } + } +} diff --git a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineMetricDeserializer.cs b/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineMetricDeserializer.cs deleted file mode 100644 index a8aa48591..000000000 --- a/src/Promitor.Core.Scraping/Configuration/Serialization/v1/Providers/VirtualMachineMetricDeserializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using YamlDotNet.RepresentationModel; - -namespace Promitor.Core.Scraping.Configuration.Serialization.v1.Providers -{ - internal class VirtualMachineMetricDeserializer : MetricDeserializer - { - /// Deserializes the specified Virtual Machine metric node from the YAML configuration file. - /// The metric node containing 'virtualMachineName' parameter pointing to an instance of a Virtual Machine - /// A new object (strongly typed as a ) - internal override MetricDefinitionV1 Deserialize(YamlMappingNode metricNode) - { - var metricDefinition = base.DeserializeMetricDefinition(metricNode); - var virtualMachineName = metricNode.Children[new YamlScalarNode("virtualMachineName")]; - - metricDefinition.VirtualMachineName = virtualMachineName?.ToString(); - - return metricDefinition; - } - } -} \ No newline at end of file diff --git a/src/Promitor.Core.Scraping/Factories/MetricDeserializerFactory.cs b/src/Promitor.Core.Scraping/Factories/MetricDeserializerFactory.cs deleted file mode 100644 index 7a2f6c151..000000000 --- a/src/Promitor.Core.Scraping/Factories/MetricDeserializerFactory.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; - -namespace Promitor.Core.Scraping.Factories -{ - internal static class MetricDeserializerFactory - { - internal static MetricDeserializer GetDeserializerFor(Configuration.Model.ResourceType resource) - { - switch (resource) - { - case Configuration.Model.ResourceType.Generic: - return new GenericAzureMetricDeserializer(); - case Configuration.Model.ResourceType.ServiceBusQueue: - return new ServiceBusQueueMetricDeserializer(); - case Configuration.Model.ResourceType.StorageQueue: - return new StorageQueueMetricDeserializer(); - case Configuration.Model.ResourceType.ContainerInstance: - return new ContainerInstanceMetricDeserializer(); - case Configuration.Model.ResourceType.VirtualMachine: - return new VirtualMachineMetricDeserializer(); - case Configuration.Model.ResourceType.ContainerRegistry: - return new ContainerRegistryMetricDeserializer(); - case Configuration.Model.ResourceType.NetworkInterface: - return new NetworkInterfaceMetricDeserializer(); - case Configuration.Model.ResourceType.CosmosDb: - return new CosmosDbMetricDeserializer(); - case Configuration.Model.ResourceType.RedisCache: - return new RedisCacheMetricDeserializer(); - case Configuration.Model.ResourceType.PostgreSql: - return new PostgreSqlMetricDeserializer(); - } - - throw new ArgumentOutOfRangeException($@"Resource Type {resource} not supported."); - } - } -} diff --git a/src/Promitor.Scraper.Host/Extensions/IServiceCollectionExtensions.cs b/src/Promitor.Scraper.Host/Extensions/IServiceCollectionExtensions.cs index 68b483fbb..983bb1415 100644 --- a/src/Promitor.Scraper.Host/Extensions/IServiceCollectionExtensions.cs +++ b/src/Promitor.Scraper.Host/Extensions/IServiceCollectionExtensions.cs @@ -14,6 +14,9 @@ using Promitor.Core.Configuration.Model.Server; using Promitor.Core.Configuration.Model.Telemetry; using Promitor.Core.Configuration.Model.Telemetry.Sinks; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using Promitor.Core.Scraping.Factories; using Promitor.Core.Scraping.Prometheus; using Promitor.Core.Scraping.Prometheus.Interfaces; @@ -78,6 +81,17 @@ public static IServiceCollection DefineDependencies(this IServiceCollection serv services.AddTransient(); services.AddTransient(); + services.AddSingleton, V1Deserializer>(); + services.AddSingleton, AzureMetadataDeserializer>(); + services.AddSingleton, MetricDefaultsDeserializer>(); + services.AddSingleton, MetricDefinitionDeserializer>(); + services.AddSingleton, AggregationDeserializer>(); + services.AddSingleton, ScrapingDeserializer>(); + services.AddSingleton, AzureMetricConfigurationDeserializer>(); + services.AddSingleton(); + services.AddSingleton, MetricAggregationDeserializer>(); + services.AddSingleton, SecretDeserializer>(); + return services; } diff --git a/src/Promitor.Scraper.Host/Validation/RuntimeValidator.cs b/src/Promitor.Scraper.Host/Validation/RuntimeValidator.cs index ec7799869..c3fb5e68b 100644 --- a/src/Promitor.Scraper.Host/Validation/RuntimeValidator.cs +++ b/src/Promitor.Scraper.Host/Validation/RuntimeValidator.cs @@ -6,6 +6,8 @@ using Microsoft.Extensions.Options; using Promitor.Core.Configuration.Model.Metrics; using Promitor.Core.Scraping.Configuration.Providers; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using Promitor.Core.Telemetry.Loggers; using Promitor.Scraper.Host.Validation.Exceptions; using Promitor.Scraper.Host.Validation.Interfaces; @@ -24,11 +26,12 @@ public RuntimeValidator( IOptions metricsConfiguration, ValidationLogger validatorLogger, IConfiguration configuration, - IMapper mapper) + IMapper mapper, + IDeserializer v1Deserializer) { _validationLogger = validatorLogger; - var scrapeConfigurationProvider = new MetricsDeclarationProvider(configuration, _validationLogger, mapper); + var scrapeConfigurationProvider = new MetricsDeclarationProvider(configuration, _validationLogger, mapper, v1Deserializer); _validationSteps = new List { new ConfigurationPathValidationStep(metricsConfiguration, _validationLogger), diff --git a/src/Promitor.Scraper.Tests.Unit/Builders/Metrics/v1/MetricsDeclarationBuilder.cs b/src/Promitor.Scraper.Tests.Unit/Builders/Metrics/v1/MetricsDeclarationBuilder.cs index b6132114a..4cf9a42f6 100644 --- a/src/Promitor.Scraper.Tests.Unit/Builders/Metrics/v1/MetricsDeclarationBuilder.cs +++ b/src/Promitor.Scraper.Tests.Unit/Builders/Metrics/v1/MetricsDeclarationBuilder.cs @@ -2,12 +2,14 @@ using AutoMapper; using Microsoft.Azure.Management.Monitor.Fluent.Models; using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Model; using Promitor.Core.Scraping.Configuration.Serialization; using Promitor.Core.Scraping.Configuration.Serialization.Enum; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; using Promitor.Integrations.AzureStorage; +using Promitor.Scraper.Tests.Unit.Serialization.v1; namespace Promitor.Scraper.Tests.Unit.Builders.Metrics.v1 { @@ -20,6 +22,8 @@ public class MetricsDeclarationBuilder Scraping = new ScrapingV1 { Schedule = @"0 * * ? * *" } }; + private V1Deserializer _v1Deserializer; + public MetricsDeclarationBuilder(AzureMetadataV1 azureMetadata) { _azureMetadata = azureMetadata; @@ -59,21 +63,30 @@ public string Build(IMapper mapper) Metrics = _metrics }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, mapper); + _v1Deserializer = V1DeserializerFactory.CreateDeserializer(); + + var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, mapper, _v1Deserializer); return configurationSerializer.Serialize(metricsDeclaration); } public MetricsDeclarationBuilder WithServiceBusMetric(string metricName = "promitor-service-bus", string metricDescription = "Description for a metric", string queueName = "promitor-queue", string serviceBusNamespace = "promitor-namespace", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new ServiceBusQueueMetricDefinitionV1 + var resource = new ServiceBusQueueResourceV1 + { + QueueName = queueName, + Namespace = serviceBusNamespace + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - QueueName = queueName, - Namespace = serviceBusNamespace, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.ServiceBusQueue }; + _metrics.Add(metric); return this; @@ -82,12 +95,18 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithContainerInstanceMetric(string metricName = "promitor-container-instance", string metricDescription = "Description for a metric", string containerGroup = "promitor-group", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new ContainerInstanceMetricDefinitionV1 + var resource = new ContainerInstanceResourceV1 + { + ContainerGroup = containerGroup + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - ContainerGroup = containerGroup, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.ContainerInstance }; _metrics.Add(metric); @@ -98,13 +117,20 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithContainerRegistryMetric(string metricName = "promitor-container-registry", string metricDescription = "Description for a metric", string registryName = "promitor-container-registry", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new ContainerRegistryMetricDefinitionV1 + var resource = new ContainerRegistryResourceV1 + { + RegistryName = registryName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - RegistryName = registryName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.ContainerRegistry }; + _metrics.Add(metric); return this; @@ -113,13 +139,20 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithCosmosDbMetric(string metricName = "promitor-cosmosdb", string metricDescription = "Description for a metric", string dbName = "promitor-cosmosdb", string azureMetricName = "TotalRequests") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new CosmosDbMetricDefinitionV1 + var resource = new CosmosDbResourceV1 + { + DbName = dbName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - DbName = dbName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.CosmosDb }; + _metrics.Add(metric); return this; @@ -133,15 +166,22 @@ public string Build(IMapper mapper) RawValue = sasToken }; - var metric = new StorageQueueMetricDefinitionV1 + var resource = new StorageQueueResourceV1 { - Name = metricName, - Description = metricDescription, QueueName = queueName, AccountName = accountName, - SasToken = secret, - AzureMetricConfiguration = azureMetricConfiguration + SasToken = secret }; + + var metric = new MetricDefinitionV1 + { + Name = metricName, + Description = metricDescription, + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List { resource }, + ResourceType = ResourceType.StorageQueue + }; + _metrics.Add(metric); return this; @@ -150,12 +190,18 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithVirtualMachineMetric(string metricName = "promitor-virtual-machine", string metricDescription = "Description for a metric", string virtualMachineName = "promitor-virtual-machine-name", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new VirtualMachineMetricDefinitionV1 + var resource = new VirtualMachineResourceV1 + { + VirtualMachineName = virtualMachineName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - VirtualMachineName = virtualMachineName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.VirtualMachine }; _metrics.Add(metric); @@ -166,12 +212,18 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithNetworkInterfaceMetric(string metricName = "promitor-network-interface", string metricDescription = "Description for a metric", string networkInterfaceName = "promitor-network-interface-name", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new NetworkInterfaceMetricDefinitionV1 + var resource = new NetworkInterfaceResourceV1 + { + NetworkInterfaceName = networkInterfaceName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - NetworkInterfaceName = networkInterfaceName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.NetworkInterface }; _metrics.Add(metric); @@ -182,14 +234,21 @@ public string Build(IMapper mapper) public MetricsDeclarationBuilder WithGenericMetric(string metricName = "foo", string metricDescription = "Description for a metric", string resourceUri = "Microsoft.ServiceBus/namespaces/promitor-messaging", string filter = "EntityName eq \'orders\'", string azureMetricName = "Total") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new GenericAzureMetricDefinitionV1 + var resource = new GenericResourceV1 + { + ResourceUri = resourceUri, + Filter = filter + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - ResourceUri = resourceUri, - Filter = filter, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.Generic }; + _metrics.Add(metric); return this; @@ -210,13 +269,20 @@ private AzureMetricConfigurationV1 CreateAzureMetricConfiguration(string azureMe public MetricsDeclarationBuilder WithRedisCacheMetric(string metricName = "promitor-redis", string metricDescription = "Description for a metric", string cacheName = "promitor-redis", string azureMetricName = "CacheHits") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new RedisCacheMetricDefinitionV1 + var resource = new RedisCacheResourceV1 + { + CacheName = cacheName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - CacheName = cacheName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.RedisCache }; + _metrics.Add(metric); return this; @@ -225,13 +291,20 @@ private AzureMetricConfigurationV1 CreateAzureMetricConfiguration(string azureMe public MetricsDeclarationBuilder WithPostgreSqlMetric(string metricName = "promitor-postgresql", string metricDescription = "Description for a metric", string serverName = "promitor-postgresql", string azureMetricName = "cpu_percent") { var azureMetricConfiguration = CreateAzureMetricConfiguration(azureMetricName); - var metric = new PostgreSqlMetricDefinitionV1 + var resource = new PostgreSqlResourceV1 + { + ServerName = serverName + }; + + var metric = new MetricDefinitionV1 { Name = metricName, Description = metricDescription, - ServerName = serverName, - AzureMetricConfiguration = azureMetricConfiguration + AzureMetricConfiguration = azureMetricConfiguration, + Resources = new List {resource}, + ResourceType = ResourceType.PostgreSql }; + _metrics.Add(metric); return this; diff --git a/src/Promitor.Scraper.Tests.Unit/Promitor.Scraper.Tests.Unit.csproj b/src/Promitor.Scraper.Tests.Unit/Promitor.Scraper.Tests.Unit.csproj index 8a0c0defc..0910992bd 100644 --- a/src/Promitor.Scraper.Tests.Unit/Promitor.Scraper.Tests.Unit.csproj +++ b/src/Promitor.Scraper.Tests.Unit/Promitor.Scraper.Tests.Unit.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/YamlMappingNodeExtensionTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/YamlMappingNodeExtensionTests.cs new file mode 100644 index 000000000..fddda4536 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/YamlMappingNodeExtensionTests.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization +{ + [Category("Unit")] + public class YamlMappingNodeExtensionTests + { + [Fact] + public void GetString_PropertySpecified_ReturnsValue() + { + // Arrange + var node = YamlUtils.CreateYamlNode("property: value"); + + // Act + var value = node.GetString("property"); + + // Assert + Assert.Equal("value", value); + } + + [Fact] + public void GetString_PropertyNotSpecified_Null() + { + // Arrange + var node = YamlUtils.CreateYamlNode("otherProperty: value"); + + // Act + var value = node.GetString("property"); + + // Assert + Assert.Null(value); + } + + [Fact] + public void GetEnum_PropertySpecified_ReturnsValue() + { + // Arrange + var node = YamlUtils.CreateYamlNode("day: Wednesday"); + + // Act + var value = node.GetEnum("day"); + + // Assert + Assert.Equal(DayOfWeek.Wednesday, value); + } + + [Fact] + public void GetEnum_PropertyNotSpecified_Null() + { + // Arrange + var node = YamlUtils.CreateYamlNode("month: January"); + + // Act + var value = node.GetEnum("day"); + + // Assert + Assert.Null(value); + } + + [Fact] + public void GetEnum_EnumValueNotValid_ThrowsException() + { + // Arrange + var node = YamlUtils.CreateYamlNode("day: MonFriday"); + + // Act / Assert + Assert.Throws(() => node.GetEnum("day")); + } + + [Fact] + public void GetDictionary_PropertySpecified_DeserializesDictionary() + { + // Arrange + const string yamlText = +@"labels: + env: production + tier: web"; + var node = YamlUtils.CreateYamlNode(yamlText); + + // Act + var labels = node.GetDictionary("labels"); + + // Assert + var expected = new Dictionary + { + { "env", "production" }, + { "tier", "web" } + }; + + Assert.Equal(expected, labels); + } + + [Fact] + public void GetDictionary_PropertyNotSpecified_Null() + { + // Arrange + var node = YamlUtils.CreateYamlNode("property: value"); + + // Act + var labels = node.GetDictionary("labels"); + + // Assert + Assert.Null(labels); + } + + [Fact] + public void GetTimeSpan_PropertySpecified_ReturnsValue() + { + // Arrange + var node = YamlUtils.CreateYamlNode("time: 13:08:12"); + + // Act + var value = node.GetTimeSpan("time"); + + // Assert + Assert.Equal(new TimeSpan(0, 13, 8, 12), value); + } + + [Fact] + public void GetTimeSpan_PropertyNotSpecified_Null() + { + // Arrange + var node = YamlUtils.CreateYamlNode("day: Monday"); + + // Act + var value = node.GetTimeSpan("time"); + + // Assert + Assert.Null(value); + } + + [Fact] + public void DeserializeChild_PropertySpecified_DeserializesChild() + { + // Arrange + const string yamlText = +@"aggregation: + interval: 00:05:00"; + var node = YamlUtils.CreateYamlNode(yamlText); + var deserializer = new AggregationDeserializer(NullLogger.Instance); + + // Act + var aggregation = node.DeserializeChild("aggregation", deserializer); + + // Assert + Assert.Equal(TimeSpan.FromMinutes(5), aggregation.Interval); + } + + [Fact] + public void DeserializeChild_PropertyNotSpecified_Null() + { + // Arrange + var node = YamlUtils.CreateYamlNode(@"time: 00:05:30"); + var deserializer = new AggregationDeserializer(NullLogger.Instance); + + // Act + var aggregation = node.DeserializeChild("aggregation", deserializer); + + // Assert + Assert.Null(aggregation); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/YamlUtils.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/YamlUtils.cs new file mode 100644 index 000000000..4e55d2605 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/YamlUtils.cs @@ -0,0 +1,18 @@ +using System.IO; +using System.Linq; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization +{ + public class YamlUtils + { + public static YamlMappingNode CreateYamlNode(string yamlText) + { + var reader = new StringReader(yamlText); + var stream = new YamlStream(); + stream.Load(reader); + + return (YamlMappingNode)stream.Documents.First().RootNode; + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AggregationDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AggregationDeserializerTests.cs new file mode 100644 index 000000000..4700aa79c --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AggregationDeserializerTests.cs @@ -0,0 +1,48 @@ +using System; +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class AggregationDeserializerTests + { + private readonly AggregationDeserializer _deserializer; + + public AggregationDeserializerTests() + { + _deserializer = new AggregationDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_IntervalSupplied_SetsInterval() + { + // Arrange + const string yamlText = +@"aggregation: + interval: 00:07:00"; + YamlAssert.PropertySet( + _deserializer, + yamlText, + "aggregation", + TimeSpan.FromMinutes(7), + a => a.Interval); + } + + [Fact] + public void Deserialize_IntervalNotSupplied_UsesDefault() + { + const string yamlText = +@"aggregation: + someProperty: someValue"; + YamlAssert.PropertySet( + _deserializer, + yamlText, + "aggregation", + TimeSpan.FromMinutes(5), + a => a.Interval); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetadataDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetadataDeserializerTests.cs new file mode 100644 index 000000000..e96d872f5 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetadataDeserializerTests.cs @@ -0,0 +1,111 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class AzureMetadataDeserializerTests + { + private readonly AzureMetadataDeserializer _deserializer; + + public AzureMetadataDeserializerTests() + { + _deserializer = new AzureMetadataDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_TenantIdSupplied_SetsTenantId() + { + const string tenantId = "c8819874-9e56-4e3f-b1a8-1c0325138f27"; + + var yamlText = +$@"azureMetadata: + tenantId: '{tenantId}'"; + + YamlAssert.PropertySet( + _deserializer, + yamlText, + "azureMetadata", + tenantId, + a => a.TenantId); + } + + [Fact] + public void Deserialize_TenantIdNotSupplied_Null() + { + const string yamlText = +@"azureMetadata: + subscriptionId: '0f9d7fea-99e8-4768-8672-06a28514f77e'"; + + YamlAssert.PropertyNull( + _deserializer, + yamlText, + "azureMetadata", + a => a.TenantId); + } + + [Fact] + public void Deserialize_SubscriptionIdSupplied_SetsSubscriptionId() + { + const string subscriptionId = "0f9d7fea-99e8-4768-8672-06a28514f77e"; + + var yamlText = +$@"azureMetadata: + subscriptionId: '{subscriptionId}'"; + + YamlAssert.PropertySet( + _deserializer, + yamlText, + "azureMetadata", + subscriptionId, + a => a.SubscriptionId); + } + + [Fact] + public void Deserialize_SubscriptionIdNotSupplied_Null() + { + const string yamlText = +@"azureMetadata: + tenantId: 'c8819874-9e56-4e3f-b1a8-1c0325138f27'"; + + YamlAssert.PropertyNull( + _deserializer, + yamlText, + "azureMetadata", + a => a.SubscriptionId); + } + + [Fact] + public void Deserialize_ResourceGroupNameSupplied_SetsResourceGroupName() + { + const string resourceGroupName = "promitor-group"; + + var yamlText = +$@"azureMetadata: + resourceGroupName: '{resourceGroupName}'"; + + YamlAssert.PropertySet( + _deserializer, + yamlText, + "azureMetadata", + resourceGroupName, + a => a.ResourceGroupName); + } + + [Fact] + public void Deserialize_ResourceGroupNameNotSupplied_Null() + { + const string yamlText = +@"azureMetadata: + tenantId: 'c8819874-9e56-4e3f-b1a8-1c0325138f27'"; + + YamlAssert.PropertyNull( + _deserializer, + yamlText, + "azureMetadata", + a => a.ResourceGroupName); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetricConfigurationDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetricConfigurationDeserializerTests.cs new file mode 100644 index 000000000..679084207 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/AzureMetricConfigurationDeserializerTests.cs @@ -0,0 +1,73 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class AzureMetricConfigurationDeserializerTests + { + private readonly AzureMetricConfigurationDeserializer _deserializer; + private readonly Mock> _aggregationDeserializer; + + public AzureMetricConfigurationDeserializerTests() + { + _aggregationDeserializer = new Mock>(); + + _deserializer = new AzureMetricConfigurationDeserializer(_aggregationDeserializer.Object, NullLogger.Instance); + } + + [Fact] + public void Deserialize_MetricNameSupplied_SetsMetricName() + { + YamlAssert.PropertySet( + _deserializer, + "metricName: ActiveMessages", + "ActiveMessages", + a => a.MetricName); + } + + [Fact] + public void Deserialize_MetricNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + a => a.MetricName); + } + + [Fact] + public void Deserialize_AggregationSupplied_UsesDeserializer() + { + // Arrange + const string yamlText = +@"aggregation: + type: Average"; + var node = YamlUtils.CreateYamlNode(yamlText); + var aggregationNode = (YamlMappingNode) node.Children["aggregation"]; + + var aggregation = new MetricAggregationV1(); + _aggregationDeserializer.Setup(d => d.Deserialize(aggregationNode)).Returns(aggregation); + + // Act + var config = _deserializer.Deserialize(node); + + // Assert + Assert.Same(aggregation, config.Aggregation); + } + + [Fact] + public void Deserialize_AggregationNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "metricName: ActiveMessages", + c => c.Aggregation); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricAggregationDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricAggregationDeserializerTests.cs new file mode 100644 index 000000000..07e144fc5 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricAggregationDeserializerTests.cs @@ -0,0 +1,58 @@ +using System; +using System.ComponentModel; +using Microsoft.Azure.Management.Monitor.Fluent.Models; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class MetricAggregationDeserializerTests + { + private readonly MetricAggregationDeserializer _deserializer; + + public MetricAggregationDeserializerTests() + { + _deserializer = new MetricAggregationDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_TypeSupplied_SetsType() + { + YamlAssert.PropertySet( + _deserializer, + "type: Maximum", + AggregationType.Maximum, + a => a.Type); + } + + [Fact] + public void Deserialize_TypeNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "interval: 00:05:00", + a => a.Type); + } + + [Fact] + public void Deserialize_IntervalSupplied_SetsInterval() + { + YamlAssert.PropertySet( + _deserializer, + "interval: 00:07:00", + TimeSpan.FromMinutes(7), + a => a.Interval); + } + + [Fact] + public void Deserialize_IntervalNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "type: Average", + a => a.Interval); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefaultsDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefaultsDeserializerTests.cs new file mode 100644 index 000000000..1b1c973ce --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefaultsDeserializerTests.cs @@ -0,0 +1,104 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class MetricDefaultsDeserializerTests + { + private readonly MetricDefaultsDeserializer _deserializer; + private readonly Mock> _aggregationDeserializer; + private readonly Mock> _scrapingDeserializer; + + public MetricDefaultsDeserializerTests() + { + _aggregationDeserializer = new Mock>(); + _scrapingDeserializer = new Mock>(); + + _deserializer = new MetricDefaultsDeserializer( + _aggregationDeserializer.Object, _scrapingDeserializer.Object, NullLogger.Instance); + } + + [Fact] + public void Deserialize_AggregationPresent_UsesAggregationDeserializer() + { + // Arrange + const string yamlText = +@"metricDefaults: + aggregation: + interval: 00:05:00"; + var node = (YamlMappingNode)YamlUtils.CreateYamlNode(yamlText).Children["metricDefaults"]; + + var aggregationNode = (YamlMappingNode)node.Children["aggregation"]; + var aggregation = new AggregationV1(); + _aggregationDeserializer.Setup(d => d.Deserialize(aggregationNode)).Returns(aggregation); + + // Act + var defaults = _deserializer.Deserialize(node); + + // Assert + Assert.Same(aggregation, defaults.Aggregation); + } + + [Fact] + public void Deserialize_AggregationNotPresent_DoesNotUseDeserializer() + { + // Arrange + const string yamlText = +@"metricDefaults: + scraping: + schedule: '0 * * ? * *'"; + var node = (YamlMappingNode)YamlUtils.CreateYamlNode(yamlText).Children["metricDefaults"]; + + // Act + _deserializer.Deserialize(node); + + // Assert + _aggregationDeserializer.Verify(d => d.Deserialize(It.IsAny()), Times.Never); + } + + [Fact] + public void Deserialize_ScrapingPresent_UsesScrapingDeserializer() + { + // Arrange + const string yamlText = +@"metricDefaults: + scraping: + schedule: '0 * * ? * *'"; + var node = (YamlMappingNode)YamlUtils.CreateYamlNode(yamlText).Children["metricDefaults"]; + + var scrapingNode = (YamlMappingNode)node.Children["scraping"]; + var scraping = new ScrapingV1(); + _scrapingDeserializer.Setup(d => d.Deserialize(scrapingNode)).Returns(scraping); + + // Act + var defaults = _deserializer.Deserialize(node); + + // Assert + Assert.Same(scraping, defaults.Scraping); + } + + [Fact] + public void Deserialize_ScrapingNotPresent_DoesNotUseDeserializer() + { + // Arrange + const string yamlText = +@"metricDefaults: + aggregation: + interval: '00:05:00'"; + var node = (YamlMappingNode)YamlUtils.CreateYamlNode(yamlText).Children["metricDefaults"]; + + // Act + _deserializer.Deserialize(node); + + // Assert + _scrapingDeserializer.Verify(d => d.Deserialize(It.IsAny()), Times.Never); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefinitionDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefinitionDeserializerTests.cs new file mode 100644 index 000000000..85bd506cc --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/MetricDefinitionDeserializerTests.cs @@ -0,0 +1,232 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Model; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class MetricDefinitionDeserializerTests + { + private readonly Mock> _azureMetricConfigurationDeserializer; + private readonly Mock> _scrapingDeserializer; + private readonly Mock _resourceDeserializerFactory; + + private readonly MetricDefinitionDeserializer _deserializer; + + public MetricDefinitionDeserializerTests() + { + _azureMetricConfigurationDeserializer = new Mock>(); + _scrapingDeserializer = new Mock>(); + _resourceDeserializerFactory = new Mock(); + + _deserializer = new MetricDefinitionDeserializer( + _azureMetricConfigurationDeserializer.Object, + _scrapingDeserializer.Object, + _resourceDeserializerFactory.Object, + NullLogger.Instance); + } + + [Fact] + public void Deserialize_NameSupplied_SetsName() + { + YamlAssert.PropertySet( + _deserializer, + "name: promitor_test_metric", + "promitor_test_metric", + d => d.Name); + } + + [Fact] + public void Deserialize_NameNotSupplied_Null() + { + YamlAssert.PropertyNull(_deserializer, "description: 'Test metric'", d => d.Name); + } + + [Fact] + public void Deserialize_DescriptionSupplied_SetsDescription() + { + YamlAssert.PropertySet( + _deserializer, + "description: 'This is a test metric'", + "This is a test metric", + d => d.Description); + } + + [Fact] + public void Deserialize_DescriptionNotSupplied_Null() + { + YamlAssert.PropertyNull(_deserializer, "name: metric", d => d.Description); + } + + [Fact] + public void Deserialize_ResourceTypeSupplied_SetsResourceType() + { + YamlAssert.PropertySet( + _deserializer, + "resourceType: ServiceBusQueue", + ResourceType.ServiceBusQueue, + d => d.ResourceType); + } + + [Fact] + public void Deserialize_ResourceTypeNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "name: promitor_test_metric", + d => d.ResourceType); + } + + [Fact] + public void Deserialize_LabelsSupplied_SetsLabels() + { + const string yamlText = +@"labels: + app: promitor + env: test"; + + YamlAssert.PropertySet( + _deserializer, + yamlText, + new Dictionary{{"app", "promitor"}, {"env", "test"}}, + d => d.Labels); + } + + [Fact] + public void Deserialize_LabelsNotSupplied_Null() + { + YamlAssert.PropertyNull(_deserializer, "name: promitor_test_metric", d => d.Labels); + } + + [Fact] + public void Deserialize_AzureMetricConfigurationSupplied_UsesDeserializer() + { + // Arrange + const string yamlText = +@"azureMetricConfiguration: + metricName: ActiveMessages"; + var node = YamlUtils.CreateYamlNode(yamlText); + var configurationNode = (YamlMappingNode) node.Children["azureMetricConfiguration"]; + var configuration = new AzureMetricConfigurationV1(); + + _azureMetricConfigurationDeserializer.Setup(d => d.Deserialize(configurationNode)).Returns(configuration); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Same(configuration, definition.AzureMetricConfiguration); + } + + [Fact] + public void Deserialize_AzureMetricConfigurationNotSupplied_Null() + { + // Arrange + const string yamlText = @"name: promitor_test_metric"; + var node = YamlUtils.CreateYamlNode(yamlText); + + _azureMetricConfigurationDeserializer.Setup( + d => d.Deserialize(It.IsAny())).Returns(new AzureMetricConfigurationV1()); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Null(definition.AzureMetricConfiguration); + } + + [Fact] + public void Deserialize_ScrapingSupplied_UsesDeserializer() + { + // Arrange + const string yamlText = +@"scraping: + interval: '00:05:00'"; + var node = YamlUtils.CreateYamlNode(yamlText); + var scrapingNode = (YamlMappingNode)node.Children["scraping"]; + var scraping = new ScrapingV1(); + + _scrapingDeserializer.Setup(d => d.Deserialize(scrapingNode)).Returns(scraping); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Same(scraping, definition.Scraping); + } + + [Fact] + public void Deserialize_ScrapingNotSupplied_Null() + { + // Arrange + const string yamlText = "name: promitor_test_metric"; + var node = YamlUtils.CreateYamlNode(yamlText); + + _scrapingDeserializer.Setup(d => d.Deserialize(It.IsAny())).Returns(new ScrapingV1()); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Null(definition.Scraping); + } + + [Fact] + public void Deserialize_ResourcesSupplied_UsesDeserializer() + { + // Arrange + const string yamlText = +@"resourceType: Generic +resources: +- resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging +- resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging-2"; + var node = YamlUtils.CreateYamlNode(yamlText); + + var resourceDeserializer = new Mock>(); + _resourceDeserializerFactory.Setup( + f => f.GetDeserializerFor(ResourceType.Generic)).Returns(resourceDeserializer.Object); + + var resources = new List(); + resourceDeserializer.Setup( + d => d.Deserialize((YamlSequenceNode) node.Children["resources"])).Returns(resources); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Same(resources, definition.Resources); + } + + [Fact] + public void Deserialize_ResourcesWithUnspecifiedResourceType_Null() + { + // Arrange + const string yamlText = +@"resources: +- resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging +- resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging-2"; + var node = YamlUtils.CreateYamlNode(yamlText); + + var resourceDeserializer = new Mock>(); + _resourceDeserializerFactory.Setup( + f => f.GetDeserializerFor(It.IsAny())).Returns(resourceDeserializer.Object); + + var resources = new List(); + resourceDeserializer.Setup( + d => d.Deserialize((YamlSequenceNode)node.Children["resources"])).Returns(resources); + + // Act + var definition = _deserializer.Deserialize(node); + + // Assert + Assert.Null(definition.Resources); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/ScrapingDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/ScrapingDeserializerTests.cs new file mode 100644 index 000000000..cd3b4924a --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/ScrapingDeserializerTests.cs @@ -0,0 +1,47 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class ScrapingDeserializerTests + { + private readonly ScrapingDeserializer _deserializer; + + public ScrapingDeserializerTests() + { + _deserializer = new ScrapingDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_ScheduleSupplied_SetsSchedule() + { + const string yamlText = +@"scraping: + schedule: '0 * * ? * *'"; + + YamlAssert.PropertySet( + _deserializer, + yamlText, + "scraping", + "0 * * ? * *", + s => s.Schedule); + } + + [Fact] + public void Deserialize_ScheduleNotSupplied_SetsScheduleNull() + { + const string yamlText = +@"scraping: + otherProperty: otherValue"; + + YamlAssert.PropertyNull( + _deserializer, + yamlText, + "scraping", + s => s.Schedule); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/SecretDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/SecretDeserializerTests.cs new file mode 100644 index 000000000..a60cea923 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/SecretDeserializerTests.cs @@ -0,0 +1,56 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class SecretDeserializerTests + { + private readonly SecretDeserializer _deserializer; + + public SecretDeserializerTests() + { + _deserializer = new SecretDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_RawValueSupplied_SetsRawValue() + { + YamlAssert.PropertySet( + _deserializer, + "rawValue: abc123", + "abc123", + s => s.RawValue); + } + + [Fact] + public void Deserialize_RawValueNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "environmentVariable: MY_VARIABLE", + s => s.RawValue); + } + + [Fact] + public void Deserialize_EnvironmentVariableSupplied_SetsEnvironmentVariable() + { + YamlAssert.PropertySet( + _deserializer, + "environmentVariable: PROMITOR_SECRET", + "PROMITOR_SECRET", + s => s.EnvironmentVariable); + } + + [Fact] + public void Deserialize_EnvironmentVariableNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "rawValue: abc123", + s => s.EnvironmentVariable); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/V1DeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/V1DeserializerTests.cs new file mode 100644 index 000000000..082882a2e --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Core/V1DeserializerTests.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Core +{ + [Category("Unit")] + public class V1DeserializerTests + { + private readonly Mock> _metadataDeserializer; + private readonly Mock> _defaultsDeserializer; + private readonly Mock> _metricsDeserializer; + private readonly V1Deserializer _deserializer; + + public V1DeserializerTests() + { + _metadataDeserializer = new Mock>(); + _defaultsDeserializer = new Mock>(); + _metricsDeserializer = new Mock>(); + + _deserializer = new V1Deserializer( + _metadataDeserializer.Object, + _defaultsDeserializer.Object, + _metricsDeserializer.Object, + NullLogger.Instance); + } + + [Fact] + public void Deserialize_NoVersionSpecified_ThrowsException() + { + // Arrange + var yamlNode = YamlUtils.CreateYamlNode("azureMetadata:"); + + // Act + var exception = Assert.Throws(() => _deserializer.Deserialize(yamlNode)); + + // Assert + Assert.Equal("No 'version' element was found in the metrics config", exception.Message); + } + + [Fact] + public void Deserialize_VersionSpecified_SetsCorrectVersion() + { + // Arrange + var yamlNode = YamlUtils.CreateYamlNode("version: v1"); + + // Act + var builder = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Equal("v1", builder.Version); + } + + [Fact] + public void Deserialize_WrongVersionSpecified_ThrowsException() + { + // Arrange + var yamlNode = YamlUtils.CreateYamlNode("version: v2"); + + // Act + var exception = Assert.Throws(() => _deserializer.Deserialize(yamlNode)); + + // Assert + Assert.Equal("A 'version' element with a value of 'v1' was expected but the value 'v2' was found", exception.Message); + } + + [Fact] + public void Deserialize_AzureMetadata_UsesMetadataDeserializer() + { + // Arrange + const string config = +@"version: v1 +azureMetadata: + tenantId: 'abc-123'"; + var yamlNode = YamlUtils.CreateYamlNode(config); + var azureMetadata = new AzureMetadataV1(); + _metadataDeserializer.Setup(d => d.Deserialize(It.IsAny())).Returns(azureMetadata); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Same(azureMetadata, declaration.AzureMetadata); + } + + [Fact] + public void Deserialize_AzureMetadataNotSupplied_SetsMetadataNull() + { + // Arrange + var yamlNode = YamlUtils.CreateYamlNode("version: v1"); + _metadataDeserializer.Setup( + d => d.Deserialize(It.IsAny())).Returns(new AzureMetadataV1()); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Null(declaration.AzureMetadata); + } + + [Fact] + public void Deserialize_MetricDefaults_UsesDefaultsDeserializer() + { + // Arrange + const string config = + @"version: v1 +metricDefaults: + aggregation: + interval: '00:05:00'"; + var yamlNode = YamlUtils.CreateYamlNode(config); + var metricDefaults = new MetricDefaultsV1(); + _defaultsDeserializer.Setup(d => d.Deserialize(It.IsAny())).Returns(metricDefaults); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Same(metricDefaults, declaration.MetricDefaults); + } + + [Fact] + public void Deserialize_MetricDefaultsNotSupplied_SetsDefaultsNull() + { + // Arrange + const string config = + @"version: v1"; + var yamlNode = YamlUtils.CreateYamlNode(config); + _defaultsDeserializer.Setup( + d => d.Deserialize(It.IsAny())).Returns(new MetricDefaultsV1()); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Null(declaration.MetricDefaults); + } + + [Fact] + public void Deserialize_Metrics_UsesMetricsDeserializer() + { + // Arrange + const string config = + @"version: v1 +metrics: +- name: promitor_metrics_total"; + var yamlNode = YamlUtils.CreateYamlNode(config); + var metrics = new List(); + _metricsDeserializer.Setup(d => d.Deserialize(It.IsAny())).Returns(metrics); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Same(metrics, declaration.Metrics); + } + + [Fact] + public void Deserialize_Metric_SetsMetricsNull() + { + // Arrange + const string config = + @"version: v1"; + var yamlNode = YamlUtils.CreateYamlNode(config); + _metricsDeserializer.Setup( + d => d.Deserialize(It.IsAny())).Returns(new List()); + + // Act + var declaration = _deserializer.Deserialize(yamlNode); + + // Assert + Assert.Null(declaration.Metrics); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Mapping/MetricDefinitionV1MappingTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Mapping/MetricDefinitionV1MappingTests.cs index 0369f5261..9b155550e 100644 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Mapping/MetricDefinitionV1MappingTests.cs +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Mapping/MetricDefinitionV1MappingTests.cs @@ -1,10 +1,8 @@ using System.ComponentModel; using AutoMapper; -using Promitor.Core.Scraping.Configuration.Model; using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; using Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using Xunit; namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Mapping @@ -24,7 +22,7 @@ public MetricDefinitionV1MappingTests() public void Map_CanMapPrometheusMetricDefinition() { // Arrange - var resource = new GenericAzureMetricDefinitionV1 {Name = "promitor_metric"}; + var resource = new MetricDefinitionV1 {Name = "promitor_metric", Description = "Metric description"}; // Act var definition = _mapper.Map(resource); @@ -32,33 +30,7 @@ public void Map_CanMapPrometheusMetricDefinition() // Assert Assert.NotNull(definition.PrometheusMetricDefinition); Assert.Equal(resource.Name, definition.PrometheusMetricDefinition.Name); - } - - [Fact] - public void Map_MapsResourceType() - { - // Arrange - var resource = new StorageQueueMetricDefinitionV1(); - - // Act - var definition = _mapper.Map(resource); - - // Assert - Assert.Equal(ResourceType.StorageQueue, definition.ResourceType); - } - - [Fact] - public void Map_MapsSingleResource() - { - // Arrange - var resource = new RedisCacheMetricDefinitionV1(); - - // Act - var definition = _mapper.Map(resource); - - // Assert - var runtimeResource = Assert.Single(definition.Resources); - Assert.IsType(runtimeResource); + Assert.Equal(resource.Description, definition.PrometheusMetricDefinition.Description); } } } diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithAzureStorageQueueYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithAzureStorageQueueYamlSerializationTests.cs deleted file mode 100644 index a14e88965..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithAzureStorageQueueYamlSerializationTests.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; -using MetricDefinition = Promitor.Core.Scraping.Configuration.Model.Metrics.MetricDefinition; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithAzureStorageQueueYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *", "XYZ", null)] - [InlineData(null, null, null, null, "SAMPLE_SECRET")] - public void YamlSerialization_SerializeAndDeserializeValidConfigForAzureStorageQueue_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval, string sasTokenRawValue, string sasTokenEnvironmentVariable) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var azureStorageQueueMetricDefinition = GenerateBogusAzureStorageQueueMetricDefinition(resourceGroupName, metricScrapingInterval, sasTokenRawValue, sasTokenEnvironmentVariable); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new Promitor.Core.Scraping.Configuration.Serialization.v1.Model.MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - azureStorageQueueMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, azureStorageQueueMetricDefinition); - AssertAzureStorageQueueMetricDefinition(deserializedMetricDefinition, azureStorageQueueMetricDefinition); - } - - private static void AssertAzureStorageQueueMetricDefinition(MetricDefinition deserializedStorageQueueMetricDefinition, StorageQueueMetricDefinitionV1 storageQueueMetricDefinition) - { - var deserializedResource = deserializedStorageQueueMetricDefinition.Resources.Single() as StorageQueueResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(storageQueueMetricDefinition.AccountName, deserializedResource.AccountName); - Assert.Equal(storageQueueMetricDefinition.QueueName, deserializedResource.QueueName); - Assert.NotNull(deserializedResource.SasToken); - Assert.Equal(storageQueueMetricDefinition.SasToken.RawValue, deserializedResource.SasToken.RawValue); - Assert.Equal(storageQueueMetricDefinition.SasToken.EnvironmentVariable, deserializedResource.SasToken.EnvironmentVariable); - Assert.NotNull(deserializedStorageQueueMetricDefinition.AzureMetricConfiguration); - Assert.Equal(storageQueueMetricDefinition.AzureMetricConfiguration.MetricName, deserializedStorageQueueMetricDefinition.AzureMetricConfiguration.MetricName); - Assert.NotNull(deserializedStorageQueueMetricDefinition.AzureMetricConfiguration.Aggregation); - Assert.Equal(storageQueueMetricDefinition.AzureMetricConfiguration.Aggregation.Type, deserializedStorageQueueMetricDefinition.AzureMetricConfiguration.Aggregation.Type); - Assert.Equal(storageQueueMetricDefinition.AzureMetricConfiguration.Aggregation.Interval, deserializedStorageQueueMetricDefinition.AzureMetricConfiguration.Aggregation.Interval); - } - - private StorageQueueMetricDefinitionV1 GenerateBogusAzureStorageQueueMetricDefinition(string resourceGroupName, string metricScrapingInterval, string sasTokenRawValue, string sasTokenEnvironmentVariable) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.StorageQueue) - .RuleFor(metricDefinition => metricDefinition.AccountName, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.QueueName, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.SasToken, faker => new SecretV1 - { - RawValue = sasTokenRawValue, - EnvironmentVariable = sasTokenEnvironmentVariable - }) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerInstanceYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerInstanceYamlSerializationTests.cs deleted file mode 100644 index d8fcbb76a..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerInstanceYamlSerializationTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; -using MetricDefinition = Promitor.Core.Scraping.Configuration.Model.Metrics.MetricDefinition; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithContainerInstanceYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForContainerInstance_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var containerInstanceMetricDefinition = GenerateBogusContainerInstanceMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - containerInstanceMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, containerInstanceMetricDefinition); - AssertContainerInstanceMetricDefinition(deserializedMetricDefinition, containerInstanceMetricDefinition); - } - - private static void AssertContainerInstanceMetricDefinition(MetricDefinition deserializedContainerInstanceMetricDefinition, ContainerInstanceMetricDefinitionV1 containerInstanceMetricDefinition) - { - var deserializedResource = deserializedContainerInstanceMetricDefinition.Resources.Single() as ContainerInstanceResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(containerInstanceMetricDefinition.ContainerGroup, deserializedResource.ContainerGroup); - Assert.NotNull(deserializedContainerInstanceMetricDefinition.AzureMetricConfiguration); - Assert.Equal(containerInstanceMetricDefinition.AzureMetricConfiguration.MetricName, deserializedContainerInstanceMetricDefinition.AzureMetricConfiguration.MetricName); - Assert.NotNull(deserializedContainerInstanceMetricDefinition.AzureMetricConfiguration.Aggregation); - Assert.Equal(containerInstanceMetricDefinition.AzureMetricConfiguration.Aggregation.Type, deserializedContainerInstanceMetricDefinition.AzureMetricConfiguration.Aggregation.Type); - Assert.Equal(containerInstanceMetricDefinition.AzureMetricConfiguration.Aggregation.Interval, deserializedContainerInstanceMetricDefinition.AzureMetricConfiguration.Aggregation.Interval); - } - private ContainerInstanceMetricDefinitionV1 GenerateBogusContainerInstanceMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.ContainerInstance) - .RuleFor(metricDefinition => metricDefinition.ContainerGroup, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerRegistryYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerRegistryYamlSerializationTests.cs deleted file mode 100644 index 3347a568d..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithContainerRegistryYamlSerializationTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithContainerRegistryYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForContainerRegistry_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var containerRegistryMetricDefinition = GenerateBogusContainerRegistryMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - containerRegistryMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, containerRegistryMetricDefinition); - AssertContainerRegistryMetricDefinition(deserializedMetricDefinition, containerRegistryMetricDefinition); - } - - private static void AssertContainerRegistryMetricDefinition(MetricDefinition deserializedContainerRegistryMetricDefinition, ContainerRegistryMetricDefinitionV1 containerRegistryMetricDefinition) - { - var deserializedResource = deserializedContainerRegistryMetricDefinition.Resources.Single() as ContainerRegistryResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(containerRegistryMetricDefinition.RegistryName, deserializedResource.RegistryName); - } - - private ContainerRegistryMetricDefinitionV1 GenerateBogusContainerRegistryMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.ContainerRegistry) - .RuleFor(metricDefinition => metricDefinition.RegistryName, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithCosmosDbYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithCosmosDbYamlSerializationTests.cs deleted file mode 100644 index df84c28a7..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithCosmosDbYamlSerializationTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithCosmosDbYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForCosmosDb_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var cosmosDbMetricDefinition = GenerateBogusCosmosDbMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - cosmosDbMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, cosmosDbMetricDefinition); - AssertCosmosDbMetricDefinition(deserializedMetricDefinition, cosmosDbMetricDefinition); - } - - private static void AssertCosmosDbMetricDefinition(MetricDefinition deserializedCosmosDbMetricDefinition, CosmosDbMetricDefinitionV1 cosmosDbMetricDefinition) - { - var deserializedResource = deserializedCosmosDbMetricDefinition.Resources.Single() as CosmosDbResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(cosmosDbMetricDefinition.DbName, deserializedResource.DbName); - } - - private CosmosDbMetricDefinitionV1 GenerateBogusCosmosDbMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.CosmosDb) - .RuleFor(metricDefinition => metricDefinition.DbName, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithNetworkInterfaceYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithNetworkInterfaceYamlSerializationTests.cs deleted file mode 100644 index 197c40408..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithNetworkInterfaceYamlSerializationTests.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category(category: "Unit")] - public class MetricsDeclarationWithNetworkInterfaceYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"01:00", @"2:00")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForNetworkInterface_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var networkInterfaceMetricDefinition = GenerateBogusNetworkInterfaceMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - networkInterfaceMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, networkInterfaceMetricDefinition); - AssertNetworkInterfaceMetricDefinition(deserializedMetricDefinition, networkInterfaceMetricDefinition); - } - - private static void AssertNetworkInterfaceMetricDefinition(MetricDefinition deserializedNetworkInterfaceMetricDefinition, NetworkInterfaceMetricDefinitionV1 networkInterfaceMetricDefinition) - { - var deserializedResource = deserializedNetworkInterfaceMetricDefinition.Resources.Single() as NetworkInterfaceResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(networkInterfaceMetricDefinition.NetworkInterfaceName, deserializedResource.NetworkInterfaceName); - } - - private NetworkInterfaceMetricDefinitionV1 GenerateBogusNetworkInterfaceMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.NetworkInterface) - .RuleFor(metricDefinition => metricDefinition.NetworkInterfaceName, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithPostgreSqlYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithPostgreSqlYamlSerializationTests.cs deleted file mode 100644 index 5ecd97cf8..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithPostgreSqlYamlSerializationTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithPostgreSqlYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeConfigForPostgreSql_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var postgreSqlMetricDefinition = GenerateBogusPostgreSqlMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - postgreSqlMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, postgreSqlMetricDefinition); - AssertPostgreSqlMetricDefinition(deserializedMetricDefinition, postgreSqlMetricDefinition); - } - - private static void AssertPostgreSqlMetricDefinition(MetricDefinition deserializedPostgreSqlMetricDefinition, PostgreSqlMetricDefinitionV1 postgreSqlMetricDefinition) - { - var deserializedResource = deserializedPostgreSqlMetricDefinition.Resources.Single() as PostgreSqlResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(postgreSqlMetricDefinition.ServerName, deserializedResource.ServerName); - } - - private PostgreSqlMetricDefinitionV1 GenerateBogusPostgreSqlMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Lorem.Word()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.PostgreSql) - .RuleFor(metricDefinition => metricDefinition.ServerName, faker => faker.Lorem.Word()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithRedisCacheYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithRedisCacheYamlSerializationTests.cs deleted file mode 100644 index f5b353297..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithRedisCacheYamlSerializationTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class MetricsDeclarationWithRedisCacheYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeConfigForRedisCache_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var redisCacheMetricDefinition = GenerateBogusRedisCacheMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - redisCacheMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, redisCacheMetricDefinition); - AssertRedisCacheMetricDefinition(deserializedMetricDefinition, redisCacheMetricDefinition); - } - - private static void AssertRedisCacheMetricDefinition(MetricDefinition deserializedRedisCacheMetricDefinition, RedisCacheMetricDefinitionV1 redisCacheMetricDefinition) - { - var deserializedResource = deserializedRedisCacheMetricDefinition.Resources.Single() as RedisCacheResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(redisCacheMetricDefinition.CacheName, deserializedResource.CacheName); - } - - private RedisCacheMetricDefinitionV1 GenerateBogusRedisCacheMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Lorem.Word()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.RedisCache) - .RuleFor(metricDefinition => metricDefinition.CacheName, faker => faker.Lorem.Word()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithServiceBusQueueYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithServiceBusQueueYamlSerializationTests.cs deleted file mode 100644 index d2b520fcf..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithServiceBusQueueYamlSerializationTests.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class ServiceBusQueueYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForServiceBus_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var serviceBusMetricDefinition = GenerateBogusServiceBusMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1() - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - serviceBusMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, serviceBusMetricDefinition); - AssertServiceBusQueueMetricDefinition(deserializedMetricDefinition, serviceBusMetricDefinition); - } - - private static void AssertServiceBusQueueMetricDefinition(MetricDefinition deserializedServiceBusMetricDefinition, ServiceBusQueueMetricDefinitionV1 serviceBusMetricDefinition) - { - var deserializedResource = deserializedServiceBusMetricDefinition.Resources.Single() as ServiceBusQueueResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(serviceBusMetricDefinition.Namespace, deserializedResource.Namespace); - Assert.Equal(serviceBusMetricDefinition.QueueName, deserializedResource.QueueName); - } - - private ServiceBusQueueMetricDefinitionV1 GenerateBogusServiceBusMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.ServiceBusQueue) - .RuleFor(metricDefinition => metricDefinition.Namespace, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.QueueName, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary - { - { faker.Name.FirstName(), faker.Random.Guid().ToString() }, - { faker.Name.FirstName(), faker.Random.Guid().ToString() } - }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithVirtualMachineYamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithVirtualMachineYamlSerializationTests.cs deleted file mode 100644 index a74a54523..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/MetricsDeclarationWithVirtualMachineYamlSerializationTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using Bogus; -using Microsoft.Extensions.Logging.Abstractions; -using Promitor.Core.Scraping.Configuration.Model; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; -using Promitor.Core.Scraping.Configuration.Serialization; -using Promitor.Core.Scraping.Configuration.Serialization.Enum; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics.ResourceTypes; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category(category: "Unit")] - public class MetricsDeclarationWithVirtualMachineYamlSerializationTests : YamlSerializationTests - { - [Theory] - [InlineData("promitor1", @"* */1 * * * *", @"* */2 * * * *")] - [InlineData(null, null, null)] - public void YamlSerialization_SerializeAndDeserializeValidConfigForVirtualMachine_SucceedsWithIdenticalOutput(string resourceGroupName, string defaultScrapingInterval, string metricScrapingInterval) - { - // Arrange - var azureMetadata = GenerateBogusAzureMetadata(); - var virtualMachineMetricDefinition = GenerateBogusVirtualMachineMetricDefinition(resourceGroupName, metricScrapingInterval); - var metricDefaults = GenerateBogusMetricDefaults(defaultScrapingInterval); - var scrapingConfiguration = new MetricsDeclarationV1 - { - Version = SpecVersion.v1.ToString(), - AzureMetadata = azureMetadata, - MetricDefaults = metricDefaults, - Metrics = new List - { - virtualMachineMetricDefinition - } - }; - var configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, Mapper); - - // Act - var serializedConfiguration = configurationSerializer.Serialize(scrapingConfiguration); - var deserializedConfiguration = configurationSerializer.Deserialize(serializedConfiguration); - - // Assert - Assert.NotNull(deserializedConfiguration); - AssertAzureMetadata(deserializedConfiguration, azureMetadata); - AssertMetricDefaults(deserializedConfiguration, metricDefaults); - Assert.NotNull(deserializedConfiguration.Metrics); - Assert.Single(deserializedConfiguration.Metrics); - var deserializedMetricDefinition = deserializedConfiguration.Metrics.FirstOrDefault(); - AssertMetricDefinition(deserializedMetricDefinition, virtualMachineMetricDefinition); - AssertVirtualMachineMetricDefinition(deserializedMetricDefinition, virtualMachineMetricDefinition); - } - - private static void AssertVirtualMachineMetricDefinition(MetricDefinition deserializedVirtualMachineMetricDefinition, VirtualMachineMetricDefinitionV1 virtualMachineMetricDefinition) - { - var deserializedResource = deserializedVirtualMachineMetricDefinition.Resources.Single() as VirtualMachineResourceDefinition; - - Assert.NotNull(deserializedResource); - Assert.Equal(virtualMachineMetricDefinition.VirtualMachineName, deserializedResource.VirtualMachineName); - Assert.NotNull(deserializedVirtualMachineMetricDefinition.AzureMetricConfiguration); - Assert.Equal(virtualMachineMetricDefinition.AzureMetricConfiguration.MetricName, deserializedVirtualMachineMetricDefinition.AzureMetricConfiguration.MetricName); - Assert.NotNull(deserializedVirtualMachineMetricDefinition.AzureMetricConfiguration.Aggregation); - Assert.Equal(virtualMachineMetricDefinition.AzureMetricConfiguration.Aggregation.Type, deserializedVirtualMachineMetricDefinition.AzureMetricConfiguration.Aggregation.Type); - Assert.Equal(virtualMachineMetricDefinition.AzureMetricConfiguration.Aggregation.Interval, deserializedVirtualMachineMetricDefinition.AzureMetricConfiguration.Aggregation.Interval); - } - - private VirtualMachineMetricDefinitionV1 GenerateBogusVirtualMachineMetricDefinition(string resourceGroupName, string metricScrapingInterval) - { - var bogusScrapingInterval = GenerateBogusScrapingInterval(metricScrapingInterval); - var bogusAzureMetricConfiguration = GenerateBogusAzureMetricConfiguration(); - - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.Name, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Description, faker => faker.Lorem.Sentence(wordCount: 6)) - .RuleFor(metricDefinition => metricDefinition.ResourceType, faker => ResourceType.VirtualMachine) - .RuleFor(metricDefinition => metricDefinition.VirtualMachineName, faker => faker.Name.LastName()) - .RuleFor(metricDefinition => metricDefinition.AzureMetricConfiguration, faker => bogusAzureMetricConfiguration) - .RuleFor(metricDefinition => metricDefinition.ResourceGroupName, faker => resourceGroupName) - .RuleFor(metricDefinition => metricDefinition.Scraping, faker => bogusScrapingInterval) - .RuleFor(metricDefinition => metricDefinition.Labels, faker => new Dictionary { { faker.Name.FirstName(), faker.Random.Guid().ToString() } }); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/YamlSerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/YamlSerializationTests.cs deleted file mode 100644 index b2c9fdfc6..000000000 --- a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/MetricsDeclaration/YamlSerializationTests.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.ComponentModel; -using System.Linq; -using AutoMapper; -using Bogus; -using Promitor.Core.Scraping.Configuration.Model.Metrics; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.Metrics; -using Xunit; - -namespace Promitor.Scraper.Tests.Unit.Serialization.v1.MetricsDeclaration -{ - [Category("Unit")] - public class YamlSerializationTests - { - protected readonly IMapper Mapper; - - public YamlSerializationTests() - { - var mapperConfiguration = new MapperConfiguration(c => c.AddProfile()); - Mapper = mapperConfiguration.CreateMapper(); - } - - protected void AssertMetricDefinition(MetricDefinition deserializedMetricDefinition, MetricDefinitionV1 metricDefinition) - { - Assert.NotNull(deserializedMetricDefinition); - Assert.NotNull(deserializedMetricDefinition.PrometheusMetricDefinition); - Assert.Equal(metricDefinition.Name, deserializedMetricDefinition.PrometheusMetricDefinition.Name); - Assert.Equal(metricDefinition.Description, deserializedMetricDefinition.PrometheusMetricDefinition.Description); - Assert.Equal(metricDefinition.ResourceType, deserializedMetricDefinition.ResourceType); - Assert.NotNull(deserializedMetricDefinition.PrometheusMetricDefinition.Labels); - Assert.Equal(metricDefinition.Labels, deserializedMetricDefinition.PrometheusMetricDefinition.Labels); - Assert.NotEmpty(deserializedMetricDefinition.Resources); - Assert.Equal(deserializedMetricDefinition.Resources.Single().ResourceGroupName, metricDefinition.ResourceGroupName); - - foreach (var label in metricDefinition.Labels) - { - var deserializedLabel = deserializedMetricDefinition.PrometheusMetricDefinition.Labels[label.Key]; - Assert.NotNull(deserializedLabel); - Assert.Equal(label.Value, deserializedLabel); - } - - Assert.NotNull(deserializedMetricDefinition.AzureMetricConfiguration); - Assert.Equal(metricDefinition.AzureMetricConfiguration.MetricName, deserializedMetricDefinition.AzureMetricConfiguration.MetricName); - Assert.NotNull(deserializedMetricDefinition.AzureMetricConfiguration.Aggregation); - Assert.Equal(metricDefinition.AzureMetricConfiguration.Aggregation.Type, deserializedMetricDefinition.AzureMetricConfiguration.Aggregation.Type); - Assert.Equal(metricDefinition.AzureMetricConfiguration.Aggregation.Interval, deserializedMetricDefinition.AzureMetricConfiguration.Aggregation.Interval); - } - - protected void AssertMetricDefaults(Promitor.Core.Scraping.Configuration.Model.MetricsDeclaration deserializedConfiguration, MetricDefaultsV1 metricDefaults) - { - var deserializedMetricDefaults = deserializedConfiguration.MetricDefaults; - Assert.NotNull(deserializedMetricDefaults); - Assert.NotNull(deserializedMetricDefaults.Aggregation); - Assert.Equal(metricDefaults.Aggregation.Interval, deserializedMetricDefaults.Aggregation.Interval); - } - - protected void AssertAzureMetadata(Promitor.Core.Scraping.Configuration.Model.MetricsDeclaration deserializedConfiguration, AzureMetadataV1 azureMetadata) - { - Assert.NotNull(deserializedConfiguration.AzureMetadata); - Assert.Equal(azureMetadata.TenantId, deserializedConfiguration.AzureMetadata.TenantId); - Assert.Equal(azureMetadata.ResourceGroupName, deserializedConfiguration.AzureMetadata.ResourceGroupName); - Assert.Equal(azureMetadata.SubscriptionId, deserializedConfiguration.AzureMetadata.SubscriptionId); - } - - protected AzureMetricConfigurationV1 GenerateBogusAzureMetricConfiguration() - { - var bogusMetricAggregation = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(aggregation => aggregation.Type, faker => faker.PickRandom()) - .RuleFor(aggregation => aggregation.Interval, faker => TimeSpan.FromMinutes(faker.Random.Int())) - .Generate(); - - var bogusMetricConfiguration = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metricDefinition => metricDefinition.MetricName, faker => faker.Name.FirstName()) - .RuleFor(metricDefinition => metricDefinition.Aggregation, faker => bogusMetricAggregation) - .Generate(); - - return bogusMetricConfiguration; - } - - protected MetricDefaultsV1 GenerateBogusMetricDefaults(string defaultScrapingInterval) - { - var bogusAggregationGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(aggregation => aggregation.Interval, faker => TimeSpan.FromMinutes(faker.Random.Int())); - - var generatedAggregation = bogusAggregationGenerator.Generate(); - var metricDefaults = new MetricDefaultsV1 - { - Aggregation = generatedAggregation, - }; - - if (!string.IsNullOrWhiteSpace(defaultScrapingInterval)) - { - metricDefaults.Scraping.Schedule = defaultScrapingInterval; - } - - return metricDefaults; - } - - protected AzureMetadataV1 GenerateBogusAzureMetadata() - { - var bogusGenerator = new Faker() - .StrictMode(ensureRulesForAllProperties: true) - .RuleFor(metadata => metadata.TenantId, faker => faker.Finance.Account()) - .RuleFor(metadata => metadata.ResourceGroupName, faker => faker.Name.FirstName()) - .RuleFor(metadata => metadata.SubscriptionId, faker => faker.Finance.Account()); - - return bogusGenerator.Generate(); - } - - protected ScrapingV1 GenerateBogusScrapingInterval(string testInterval) - { - var bogusGenerator = new Faker() - .RuleFor(scraping => scraping.Schedule, faker => testInterval); - - return bogusGenerator.Generate(); - } - } -} \ No newline at end of file diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerInstanceDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerInstanceDeserializerTests.cs new file mode 100644 index 000000000..84453b953 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerInstanceDeserializerTests.cs @@ -0,0 +1,45 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class ContainerInstanceDeserializerTests : ResourceDeserializerTest + { + private readonly ContainerInstanceDeserializer _deserializer; + + public ContainerInstanceDeserializerTests() + { + _deserializer = new ContainerInstanceDeserializer(NullLogger.Instance); + } + + protected override IDeserializer CreateDeserializer() + { + return new ContainerInstanceDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_ContainerGroupSupplied_SetsContainerGroup() + { + YamlAssert.PropertySet( + _deserializer, + "containerGroup: promitor-group", + "promitor-group", + c => c.ContainerGroup); + } + + [Fact] + public void Deserialize_ContainerGroupNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-resource-group", + c => c.ContainerGroup); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerRegistryDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerRegistryDeserializerTests.cs new file mode 100644 index 000000000..2245c602f --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ContainerRegistryDeserializerTests.cs @@ -0,0 +1,45 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class ContainerRegistryDeserializerTests : ResourceDeserializerTest + { + private readonly ContainerRegistryDeserializer _deserializer; + + public ContainerRegistryDeserializerTests() + { + _deserializer = new ContainerRegistryDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_RegistryNameSupplied_SetsRegistryName() + { + YamlAssert.PropertySet( + _deserializer, + "registryName: promitor-registry", + "promitor-registry", + c => c.RegistryName); + } + + [Fact] + public void Deserialize_RegistryNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + c => c.RegistryName); + } + + protected override IDeserializer CreateDeserializer() + { + return new ContainerRegistryDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/CosmosDbDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/CosmosDbDeserializerTests.cs new file mode 100644 index 000000000..d18c079e2 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/CosmosDbDeserializerTests.cs @@ -0,0 +1,45 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class CosmosDbDeserializerTests : ResourceDeserializerTest + { + private readonly CosmosDbDeserializer _deserializer; + + public CosmosDbDeserializerTests() + { + _deserializer = new CosmosDbDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_DbNameSupplied_SetsDbName() + { + YamlAssert.PropertySet( + _deserializer, + "dbName: promitor-cosmos", + "promitor-cosmos", + c => c.DbName); + } + + [Fact] + public void Deserialize_DbNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + c => c.DbName); + } + + protected override IDeserializer CreateDeserializer() + { + return new CosmosDbDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/GenericResourceDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/GenericResourceDeserializerTests.cs new file mode 100644 index 000000000..54053491f --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/GenericResourceDeserializerTests.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + public class GenericResourceDeserializerTests : ResourceDeserializerTest + { + private readonly GenericResourceDeserializer _deserializer; + + public GenericResourceDeserializerTests() + { + _deserializer = new GenericResourceDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_FilterSupplied_SetsFilter() + { + YamlAssert.PropertySet( + _deserializer, + "filter: EntityName eq 'orders'", + "EntityName eq 'orders'", + r => r.Filter); + } + + [Fact] + public void Deserialize_FilterNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.Filter); + } + + [Fact] + public void Deserialize_ResourceUriSupplied_SetsResourceUri() + { + YamlAssert.PropertySet( + _deserializer, + "resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging", + "Microsoft.ServiceBus/namespaces/promitor-messaging", + r => r.ResourceUri); + } + + [Fact] + public void Deserialize_ResourceUriNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.ResourceUri); + } + + protected override IDeserializer CreateDeserializer() + { + return new GenericResourceDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/NetworkInterfaceDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/NetworkInterfaceDeserializerTests.cs new file mode 100644 index 000000000..03dd73e33 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/NetworkInterfaceDeserializerTests.cs @@ -0,0 +1,47 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class NetworkInterfaceDeserializerTests : ResourceDeserializerTest + { + private readonly NetworkInterfaceDeserializer _deserializer; + + public NetworkInterfaceDeserializerTests() + { + _deserializer = new NetworkInterfaceDeserializer(new Mock().Object); + } + + [Fact] + public void Deserialize_NetworkInterfaceNameSupplied_SetsNetworkInterfaceName() + { + YamlAssert.PropertySet( + _deserializer, + "networkInterfaceName: promitor-nic", + "promitor-nic", + r => r.NetworkInterfaceName); + } + + [Fact] + public void Deserialize_NetworkInterfaceNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.NetworkInterfaceName); + } + + protected override IDeserializer CreateDeserializer() + { + return new NetworkInterfaceDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/PostgreSqlDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/PostgreSqlDeserializerTests.cs new file mode 100644 index 000000000..d1b5e1c26 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/PostgreSqlDeserializerTests.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + public class PostgreSqlDeserializerTests : ResourceDeserializerTest + { + private readonly PostgreSqlDeserializer _deserializer; + + public PostgreSqlDeserializerTests() + { + _deserializer = new PostgreSqlDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_ServerNameSupplied_SetsServerName() + { + YamlAssert.PropertySet( + _deserializer, + "serverName: promitor-db", + "promitor-db", + r => r.ServerName); + } + + [Fact] + public void Deserialize_ServerNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.ServerName); + } + + protected override IDeserializer CreateDeserializer() + { + return new PostgreSqlDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/RedisCacheDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/RedisCacheDeserializerTests.cs new file mode 100644 index 000000000..cf99496d4 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/RedisCacheDeserializerTests.cs @@ -0,0 +1,45 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class RedisCacheDeserializerTests : ResourceDeserializerTest + { + private readonly RedisCacheDeserializer _deserializer; + + public RedisCacheDeserializerTests() + { + _deserializer = new RedisCacheDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_CacheNameSupplied_SetsCacheName() + { + YamlAssert.PropertySet( + _deserializer, + "cacheName: promitor-cache", + "promitor-cache", + r => r.CacheName); + } + + [Fact] + public void Deserialize_CacheNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.CacheName); + } + + protected override IDeserializer CreateDeserializer() + { + return new RedisCacheDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ResourceDeserializerTest.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ResourceDeserializerTest.cs new file mode 100644 index 000000000..e02a8d0d2 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ResourceDeserializerTest.cs @@ -0,0 +1,34 @@ +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + public abstract class ResourceDeserializerTest + { + protected abstract IDeserializer CreateDeserializer(); + + [Fact] + public void Deserialize_ResourceGroupNameSupplied_SetsResourceGroupName() + { + var deserializer = CreateDeserializer(); + + YamlAssert.PropertySet( + deserializer, + "resourceGroupName: promitor-resource-group", + "promitor-resource-group", + c => c.ResourceGroupName); + } + + [Fact] + public void Deserialize_ResourceGroupNameNotSupplied_Null() + { + var deserializer = CreateDeserializer(); + + YamlAssert.PropertyNull( + deserializer, + "someProperty: someValue", + c => c.ResourceGroupName); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ServiceBusQueueDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ServiceBusQueueDeserializerTests.cs new file mode 100644 index 000000000..e04b797d8 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/ServiceBusQueueDeserializerTests.cs @@ -0,0 +1,64 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class ServiceBusQueueDeserializerTests : ResourceDeserializerTest + { + private readonly ServiceBusQueueDeserializer _deserializer; + + public ServiceBusQueueDeserializerTests() + { + _deserializer = new ServiceBusQueueDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_QueueNameSupplied_SetsQueueName() + { + YamlAssert.PropertySet( + _deserializer, + "queueName: promitor-queue", + "promitor-queue", + r => r.QueueName); + } + + [Fact] + public void Deserialize_QueueNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.QueueName); + } + + [Fact] + public void Deserialize_NamespaceSupplied_SetsNamespace() + { + YamlAssert.PropertySet( + _deserializer, + "namespace: promitor-sb", + "promitor-sb", + r => r.Namespace); + } + + [Fact] + public void Deserialize_NamespaceNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.Namespace); + } + + protected override IDeserializer CreateDeserializer() + { + return new ServiceBusQueueDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/StorageQueueDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/StorageQueueDeserializerTests.cs new file mode 100644 index 000000000..535fb4240 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/StorageQueueDeserializerTests.cs @@ -0,0 +1,97 @@ +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + public class StorageQueueDeserializerTests : ResourceDeserializerTest + { + private readonly Mock> _secretDeserializer; + + private readonly StorageQueueDeserializer _deserializer; + + public StorageQueueDeserializerTests() + { + _secretDeserializer = new Mock>(); + + _deserializer = new StorageQueueDeserializer(_secretDeserializer.Object, NullLogger.Instance); + } + + [Fact] + public void Deserialize_AccountNameSupplied_SetsAccountName() + { + YamlAssert.PropertySet( + _deserializer, + "accountName: promitor-acct", + "promitor-acct", + r => r.AccountName); + } + + [Fact] + public void Deserialize_AccountNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.AccountName); + } + + [Fact] + public void Deserialize_QueueNameSupplied_SetsQueueName() + { + YamlAssert.PropertySet( + _deserializer, + "queueName: orders", + "orders", + r => r.QueueName); + } + + [Fact] + public void Deserialize_QueueNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.QueueName); + } + + [Fact] + public void Deserialize_SasTokenSupplied_UsesDeserializer() + { + // Arrange + const string yamlText = +@"sasToken: + rawValue: abc123"; + var node = YamlUtils.CreateYamlNode(yamlText); + var sasTokenNode = (YamlMappingNode)node.Children["sasToken"]; + + var secret = new SecretV1(); + _secretDeserializer.Setup(d => d.Deserialize(sasTokenNode)).Returns(secret); + + // Act + var resource = (StorageQueueResourceV1)_deserializer.Deserialize(node); + + // Assert + Assert.Same(secret, resource.SasToken); + } + + [Fact] + public void Deserialize_SasTokenNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.SasToken); + } + + protected override IDeserializer CreateDeserializer() + { + return new StorageQueueDeserializer(new Mock>().Object, NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/VirtualMachineDeserializerTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/VirtualMachineDeserializerTests.cs new file mode 100644 index 000000000..4c377e8ad --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/Providers/VirtualMachineDeserializerTests.cs @@ -0,0 +1,45 @@ +using System.ComponentModel; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Providers; +using Xunit; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1.Providers +{ + [Category("Unit")] + public class VirtualMachineDeserializerTests : ResourceDeserializerTest + { + private readonly VirtualMachineDeserializer _deserializer; + + public VirtualMachineDeserializerTests() + { + _deserializer = new VirtualMachineDeserializer(NullLogger.Instance); + } + + [Fact] + public void Deserialize_VirtualMachineNameSupplied_SetsName() + { + YamlAssert.PropertySet( + _deserializer, + "virtualMachineName: promitor-vm", + "promitor-vm", + r => r.VirtualMachineName); + } + + [Fact] + public void Deserialize_VirtualMachineNameNotSupplied_Null() + { + YamlAssert.PropertyNull( + _deserializer, + "resourceGroupName: promitor-group", + r => r.VirtualMachineName); + } + + protected override IDeserializer CreateDeserializer() + { + return new VirtualMachineDeserializer(NullLogger.Instance); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1DeserializerFactory.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1DeserializerFactory.cs new file mode 100644 index 000000000..9b5cebadd --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1DeserializerFactory.cs @@ -0,0 +1,30 @@ +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1 +{ + /// + /// Used to create a deserializer for use by tests. + /// + public static class V1DeserializerFactory + { + public static V1Deserializer CreateDeserializer() + { + var logger = NullLogger.Instance; + return new V1Deserializer( + new AzureMetadataDeserializer(logger), + new MetricDefaultsDeserializer( + new AggregationDeserializer(logger), + new ScrapingDeserializer(logger), + logger), + new MetricDefinitionDeserializer( + new AzureMetricConfigurationDeserializer( + new MetricAggregationDeserializer(logger), + logger), + new ScrapingDeserializer(logger), + new AzureResourceDeserializerFactory(new SecretDeserializer(logger), logger), + logger), + logger); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1SerializationTests.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1SerializationTests.cs new file mode 100644 index 000000000..151ecc402 --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/V1SerializationTests.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using AutoMapper; +using Microsoft.Azure.Management.Monitor.Fluent.Models; +using Microsoft.Extensions.Logging.Abstractions; +using Promitor.Core.Scraping.Configuration.Model.Metrics.ResourceTypes; +using Promitor.Core.Scraping.Configuration.Serialization; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Core; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model.ResourceTypes; +using Xunit; +using ResourceType = Promitor.Core.Scraping.Configuration.Model.ResourceType; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1 +{ + /// + /// This class contains tests that run the full end-to-end serialization and deserialization + /// process to try to catch anything that the individual unit tests for the deserializers haven't + /// caught. + /// + [Category("Unit")] + public class V1SerializationTests + { + private readonly V1Deserializer _v1Deserializer; + private readonly ConfigurationSerializer _configurationSerializer; + private readonly MetricsDeclarationV1 _metricsDeclaration; + + public V1SerializationTests() + { + var mapperConfiguration = new MapperConfiguration(c => c.AddProfile()); + var mapper = mapperConfiguration.CreateMapper(); + + _v1Deserializer = V1DeserializerFactory.CreateDeserializer(); + _configurationSerializer = new ConfigurationSerializer(NullLogger.Instance, mapper, _v1Deserializer); + + _metricsDeclaration = new MetricsDeclarationV1 + { + AzureMetadata = new AzureMetadataV1 + { + TenantId = "tenant", + SubscriptionId = "subscription", + ResourceGroupName = "promitor-group" + }, + MetricDefaults = new MetricDefaultsV1 + { + Aggregation = new AggregationV1 + { + Interval = TimeSpan.FromMinutes(7) + }, + Scraping = new ScrapingV1 + { + Schedule = "1 2 3 4 5" + } + }, + Metrics = new List + { + new MetricDefinitionV1 + { + Name = "promitor_demo_generic_queue_size", + Description = "Amount of active messages of the 'orders' queue (determined with Generic provider)", + ResourceType = ResourceType.Generic, + Labels = new Dictionary + { + {"app", "promitor"} + }, + AzureMetricConfiguration = new AzureMetricConfigurationV1 + { + MetricName = "ActiveMessages", + Aggregation = new MetricAggregationV1 + { + Type = AggregationType.Average + } + }, + Resources = new List + { + new GenericResourceV1 + { + ResourceUri = "Microsoft.ServiceBus/namespaces/promitor-messaging", + Filter = "EntityName eq 'orders'" + }, + new GenericResourceV1 + { + ResourceUri = "Microsoft.ServiceBus/namespaces/promitor-messaging", + Filter = "EntityName eq 'accounts'" + } + } + }, + new MetricDefinitionV1 + { + Name = "promitor_demo_servicebusqueue_queue_size", + Description = "Amount of active messages of the 'orders' queue (determined with ServiceBusQueue provider)", + ResourceType = ResourceType.ServiceBusQueue, + AzureMetricConfiguration = new AzureMetricConfigurationV1 + { + MetricName = "ActiveMessages", + Aggregation = new MetricAggregationV1 + { + Type = AggregationType.Average, + Interval = TimeSpan.FromMinutes(15) + } + }, + Scraping = new ScrapingV1 + { + Schedule = "5 4 3 2 1" + }, + Resources = new List + { + new ServiceBusQueueResourceV1 + { + Namespace = "promitor-messaging", + QueueName = "orders", + ResourceGroupName = "promitor-demo-group" + } + } + } + } + }; + } + + [Fact] + public void Deserialize_SerializedModel_CanDeserialize() + { + // This test creates a v1 model, serializes it to yaml, and then verifies that + // the V1Deserializer can deserialize it. + + // Arrange + var yaml = _configurationSerializer.Serialize(_metricsDeclaration); + + // Act + var deserializedModel = _v1Deserializer.Deserialize(YamlUtils.CreateYamlNode(yaml)); + + // Assert + Assert.NotNull(deserializedModel); + Assert.Equal("tenant", deserializedModel.AzureMetadata.TenantId); + Assert.Equal("subscription", deserializedModel.AzureMetadata.SubscriptionId); + Assert.Equal("promitor-group", deserializedModel.AzureMetadata.ResourceGroupName); + Assert.Equal(TimeSpan.FromMinutes(7), deserializedModel.MetricDefaults.Aggregation.Interval); + Assert.Equal("1 2 3 4 5", deserializedModel.MetricDefaults.Scraping.Schedule); + + // Check first metric + Assert.Equal("promitor_demo_generic_queue_size", deserializedModel.Metrics.ElementAt(0).Name); + Assert.Equal("Amount of active messages of the 'orders' queue (determined with Generic provider)", deserializedModel.Metrics.ElementAt(0).Description); + Assert.Equal(ResourceType.Generic, deserializedModel.Metrics.ElementAt(0).ResourceType); + Assert.Equal(new Dictionary {{"app", "promitor"}}, deserializedModel.Metrics.ElementAt(0).Labels); + Assert.Equal("ActiveMessages", deserializedModel.Metrics.ElementAt(0).AzureMetricConfiguration.MetricName); + Assert.Equal(AggregationType.Average, deserializedModel.Metrics.ElementAt(0).AzureMetricConfiguration.Aggregation.Type); + Assert.Equal(2, deserializedModel.Metrics.ElementAt(0).Resources.Count); + + var genericResource1 = Assert.IsType(deserializedModel.Metrics.ElementAt(0).Resources.ElementAt(0)); + Assert.Equal("Microsoft.ServiceBus/namespaces/promitor-messaging", genericResource1.ResourceUri); + Assert.Equal("EntityName eq 'orders'", genericResource1.Filter); + + var genericResource2 = Assert.IsType(deserializedModel.Metrics.ElementAt(0).Resources.ElementAt(1)); + Assert.Equal("Microsoft.ServiceBus/namespaces/promitor-messaging", genericResource2.ResourceUri); + Assert.Equal("EntityName eq 'accounts'", genericResource2.Filter); + + // Check second metric + Assert.Equal("promitor_demo_servicebusqueue_queue_size", deserializedModel.Metrics.ElementAt(1).Name); + Assert.Equal("Amount of active messages of the 'orders' queue (determined with ServiceBusQueue provider)", deserializedModel.Metrics.ElementAt(1).Description); + Assert.Equal(ResourceType.ServiceBusQueue, deserializedModel.Metrics.ElementAt(1).ResourceType); + Assert.Null(deserializedModel.Metrics.ElementAt(1).Labels); + Assert.Equal(TimeSpan.FromMinutes(15), deserializedModel.Metrics.ElementAt(1).AzureMetricConfiguration.Aggregation.Interval); + Assert.Equal("5 4 3 2 1", deserializedModel.Metrics.ElementAt(1).Scraping.Schedule); + + Assert.Single(deserializedModel.Metrics.ElementAt(1).Resources); + var serviceBusQueueResource = Assert.IsType(deserializedModel.Metrics.ElementAt(1).Resources.ElementAt(0)); + Assert.Equal("promitor-messaging", serviceBusQueueResource.Namespace); + Assert.Equal("orders", serviceBusQueueResource.QueueName); + Assert.Equal("promitor-demo-group", serviceBusQueueResource.ResourceGroupName); + } + + [Fact] + public void Deserialize_SerializedYaml_CanDeserializeToRuntimeModel() + { + // Arrange + var yaml = _configurationSerializer.Serialize(_metricsDeclaration); + + // Act + var runtimeModel = _configurationSerializer.Deserialize(yaml); + + // Assert + Assert.NotNull(runtimeModel); + + var firstMetric = runtimeModel.Metrics.ElementAt(0); + Assert.Equal(ResourceType.Generic, firstMetric.ResourceType); + Assert.Equal("promitor_demo_generic_queue_size", firstMetric.PrometheusMetricDefinition.Name); + Assert.Equal("Amount of active messages of the 'orders' queue (determined with Generic provider)", firstMetric.PrometheusMetricDefinition.Description); + Assert.Collection(firstMetric.Resources, + r => + { + var definition = Assert.IsType(r); + Assert.Equal("EntityName eq 'orders'", definition.Filter); + Assert.Equal("Microsoft.ServiceBus/namespaces/promitor-messaging", definition.ResourceUri); + }, + r => + { + var definition = Assert.IsType(r); + Assert.Equal("EntityName eq 'accounts'", definition.Filter); + Assert.Equal("Microsoft.ServiceBus/namespaces/promitor-messaging", definition.ResourceUri); + }); + + var secondMetric = runtimeModel.Metrics.ElementAt(1); + Assert.Equal(ResourceType.ServiceBusQueue, secondMetric.ResourceType); + Assert.Equal("promitor_demo_servicebusqueue_queue_size", secondMetric.PrometheusMetricDefinition.Name); + Assert.Equal("Amount of active messages of the 'orders' queue (determined with ServiceBusQueue provider)", secondMetric.PrometheusMetricDefinition.Description); + Assert.Collection(secondMetric.Resources, + r => + { + var definition = Assert.IsType(r); + Assert.Equal("promitor-messaging", definition.Namespace); + Assert.Equal("orders", definition.QueueName); + Assert.Equal("promitor-demo-group", definition.ResourceGroupName); + }); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Serialization/v1/YamlAssert.cs b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/YamlAssert.cs new file mode 100644 index 000000000..491aa4bbc --- /dev/null +++ b/src/Promitor.Scraper.Tests.Unit/Serialization/v1/YamlAssert.cs @@ -0,0 +1,146 @@ +using System; +using Promitor.Core.Scraping.Configuration.Serialization; +using Xunit; +using YamlDotNet.RepresentationModel; + +namespace Promitor.Scraper.Tests.Unit.Serialization.v1 +{ + public static class YamlAssert + { + /// + /// Deserializes the yaml using the deserializer, and asserts that the + /// specified property has been set. + /// + /// The type of object being deserialized. + /// The property type. + /// The deserializer. + /// The yaml to deserialize. + /// The expected result. + /// The property to check. + public static void PropertySet( + IDeserializer deserializer, string yamlText, TResult expected, Func propertyAccessor) + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText); + + // Act + var definition = deserializer.Deserialize(node); + + // Assert + Assert.Equal(expected, propertyAccessor(definition)); + } + + /// + /// Deserializes the yaml and asserts that the specified property has been set. + /// Use this overload where the deserializer actually returns a subclass of . + /// + /// + /// + /// + /// + /// + /// + /// + public static void PropertySet( + IDeserializer deserializer, string yamlText, TResult expected, Func propertyAccessor) + where TObject: TBaseObject + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText); + + // Act + var definition = deserializer.Deserialize(node); + + // Assert + Assert.Equal(expected, propertyAccessor((TObject)definition)); + } + + /// + /// Deserializes the yaml using the deserializer, and asserts that the + /// specified property underneath the specified yaml element has been set. + /// + /// The type of object being deserialized. + /// The property type. + /// The deserializer. + /// The yaml to deserialize. + /// The element to find the properties under. + /// The expected result. + /// The property to check. + public static void PropertySet( + IDeserializer deserializer, string yamlText, string yamlElement, TResult expected, Func propertyAccessor) + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText).Children[yamlElement]; + + // Act + var definition = deserializer.Deserialize((YamlMappingNode)node); + + // Assert + Assert.Equal(expected, propertyAccessor(definition)); + } + + /// + /// Deserializes the yaml and verifies that the specified property is null. + /// + /// The type of object being deserialized. + /// The deserializer. + /// The yaml to deserialize. + /// The property to check. + public static void PropertyNull( + IDeserializer deserializer, string yamlText, Func propertyAccessor) + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText); + + // Act + var definition = deserializer.Deserialize(node); + + // Assert + Assert.Null(propertyAccessor(definition)); + } + + /// + /// Deserializes the yaml and verifies that the specified property is null. + /// + /// The type of object being deserialized. + /// The type that the deserializer returns. + /// The deserializer. + /// The yaml to deserialize. + /// The property to check. + public static void PropertyNull( + IDeserializer deserializer, string yamlText, Func propertyAccessor) + where TObject: TBaseObject + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText); + + // Act + var definition = deserializer.Deserialize(node); + + // Assert + Assert.Null(propertyAccessor((TObject)definition)); + } + + /// + /// Deserializes the yaml and verifies that the specified property nested + /// under the specified yaml element is null. + /// + /// The type of object being deserialized. + /// The deserializer. + /// The yaml to deserialize. + /// The property to check. + /// The element to look for the property under. + public static void PropertyNull( + IDeserializer deserializer, string yamlText, string yamlElement, Func propertyAccessor) + { + // Arrange + var node = YamlUtils.CreateYamlNode(yamlText).Children[yamlElement]; + + // Act + var definition = deserializer.Deserialize((YamlMappingNode)node); + + // Assert + Assert.Null(propertyAccessor(definition)); + } + } +} diff --git a/src/Promitor.Scraper.Tests.Unit/Stubs/MetricsDeclarationProviderStub.cs b/src/Promitor.Scraper.Tests.Unit/Stubs/MetricsDeclarationProviderStub.cs index 506d168c5..43271fc7a 100644 --- a/src/Promitor.Scraper.Tests.Unit/Stubs/MetricsDeclarationProviderStub.cs +++ b/src/Promitor.Scraper.Tests.Unit/Stubs/MetricsDeclarationProviderStub.cs @@ -1,6 +1,7 @@ using AutoMapper; using Microsoft.Extensions.Logging.Abstractions; using Promitor.Core.Scraping.Configuration.Providers; +using Promitor.Scraper.Tests.Unit.Serialization.v1; namespace Promitor.Scraper.Tests.Unit.Stubs { @@ -8,7 +9,7 @@ public class MetricsDeclarationProviderStub : MetricsDeclarationProvider { private readonly string _rawMetricsDeclaration; - public MetricsDeclarationProviderStub(string rawMetricsDeclaration, IMapper mapper) : base(configuration: null, logger: NullLogger.Instance, mapper: mapper) + public MetricsDeclarationProviderStub(string rawMetricsDeclaration, IMapper mapper) : base(configuration: null, logger: NullLogger.Instance, mapper: mapper, v1Deserializer: V1DeserializerFactory.CreateDeserializer()) { _rawMetricsDeclaration = rawMetricsDeclaration; } diff --git a/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/GeneralMetricsDeclarationValidationStepTests.cs b/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/GeneralMetricsDeclarationValidationStepTests.cs index 815d6e055..0c9d891b4 100644 --- a/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/GeneralMetricsDeclarationValidationStepTests.cs +++ b/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/GeneralMetricsDeclarationValidationStepTests.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using AutoMapper; -using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using Promitor.Core.Scraping.Configuration.Serialization.v1.Mapping; +using Promitor.Core.Scraping.Configuration.Serialization.v1.Model; using Promitor.Scraper.Host.Validation.Steps; using Promitor.Scraper.Tests.Unit.Stubs; using Xunit; diff --git a/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/ResourceTypes/CosmosDbMetricsDeclarationValidationStepTests.cs b/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/ResourceTypes/CosmosDbMetricsDeclarationValidationStepTests.cs index 74fac5d76..4e6b6aa30 100644 --- a/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/ResourceTypes/CosmosDbMetricsDeclarationValidationStepTests.cs +++ b/src/Promitor.Scraper.Tests.Unit/Validation/Metrics/ResourceTypes/CosmosDbMetricsDeclarationValidationStepTests.cs @@ -11,7 +11,7 @@ namespace Promitor.Scraper.Tests.Unit.Validation.Metrics.ResourceTypes [Category("Unit")] public class CosmosDbMetricsDeclarationValidationStepTests { - private IMapper _mapper; + private readonly IMapper _mapper; public CosmosDbMetricsDeclarationValidationStepTests() { diff --git a/src/metric-config.yaml b/src/metric-config.yaml index 020d25cee..53ff2b295 100644 --- a/src/metric-config.yaml +++ b/src/metric-config.yaml @@ -13,19 +13,18 @@ metrics: - name: promitor_demo_generic_queue_size description: "Amount of active messages of the 'orders' queue (determined with Generic provider)" resourceType: Generic - resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging - filter: EntityName eq 'orders' labels: app: promitor azureMetricConfiguration: metricName: ActiveMessages aggregation: type: Average + resources: + - resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging + filter: EntityName eq 'orders' - name: promitor_demo_generic_namespace_size description: "Size of all queues in our Azure Service Bus namespace (determined with Generic provider)" resourceType: Generic - resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging - # filter is deliberately omitted given filter is optional scraping: # Every 2 minutes schedule: "0 */2 * ? * *" @@ -33,24 +32,24 @@ metrics: metricName: ActiveMessages aggregation: type: Average + resources: + # filter is deliberately omitted given filter is optional + - resourceUri: Microsoft.ServiceBus/namespaces/promitor-messaging - name: promitor_demo_servicebusqueue_queue_size description: "Amount of active messages of the 'orders' queue (determined with ServiceBusQueue provider)" resourceType: ServiceBusQueue - namespace: promitor-messaging - queueName: orders azureMetricConfiguration: metricName: ActiveMessages aggregation: type: Average # Optionally override the default aggregation interval (metricDefaults.aggregation.interval) interval: 00:15:00 + resources: + - namespace: promitor-messaging + queueName: orders - name: promitor_demo_azurestoragequeue_queue_size description: "Approximate amount of messages in 'orders' queue (determined with StorageQueue provider)" resourceType: StorageQueue - accountName: promitor - queueName: orders - sasToken: - rawValue: "?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwla&se=2022-08-07T00:16:01Z&st=2019-08-06T16:16:01Z&spr=https&sig=Ik4jprS89kGIFRM0qaQpXrv0ttP3pnlhmGQuYVQ7cbA%3D" scraping: # Every 2 minutes schedule: "0 */2 * ? * *" @@ -58,14 +57,20 @@ metrics: metricName: MessageCount aggregation: type: Total + resources: + - accountName: promitor + queueName: orders + sasToken: + rawValue: "?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwla&se=2022-08-07T00:16:01Z&st=2019-08-06T16:16:01Z&spr=https&sig=Ik4jprS89kGIFRM0qaQpXrv0ttP3pnlhmGQuYVQ7cbA%3D" - name: promitor_demo_azurestoragequeue_queue_timespentinqueue description: "Approximate amount of time that the oldest message has been in 'orders' queue (determined with StorageQueue provider)" resourceType: StorageQueue - accountName: promitor - queueName: orders - sasToken: - environmentVariable: SECRETS_STORAGEQUEUE_SAS azureMetricConfiguration: metricName: TimeSpentInQueue aggregation: type: Total + resources: + - accountName: promitor + queueName: orders + sasToken: + environmentVariable: SECRETS_STORAGEQUEUE_SAS