public async Task GetAnomalies(bool populateOptionalMembers) { MetricsAdvisorClient client = GetMetricsAdvisorClient(); var options = new GetAnomaliesForDetectionConfigurationOptions(SamplingStartTime, SamplingEndTime); if (populateOptionalMembers) { options.Filter = new GetAnomaliesForDetectionConfigurationFilter(AnomalySeverity.Medium, AnomalySeverity.Medium); var groupKey1 = new DimensionKey(); groupKey1.AddDimensionColumn("city", "Delhi"); groupKey1.AddDimensionColumn("category", "Handmade"); var groupKey2 = new DimensionKey(); groupKey2.AddDimensionColumn("city", "Kolkata"); options.Filter.SeriesGroupKeys.Add(groupKey1); options.Filter.SeriesGroupKeys.Add(groupKey2); } var anomalyCount = 0; await foreach (DataPointAnomaly anomaly in client.GetAnomaliesAsync(DetectionConfigurationId, options)) { Assert.That(anomaly, Is.Not.Null); Assert.That(anomaly.AnomalyDetectionConfigurationId, Is.Null); Assert.That(anomaly.MetricId, Is.Null); Assert.That(anomaly.CreatedTime, Is.Null); Assert.That(anomaly.ModifiedTime, Is.Null); Assert.That(anomaly.Status, Is.Null); Assert.That(anomaly.Timestamp, Is.InRange(SamplingStartTime, SamplingEndTime)); Assert.That(anomaly.Severity, Is.Not.EqualTo(default(AnomalySeverity))); Assert.That(anomaly.SeriesKey, Is.Not.Null); Dictionary <string, string> dimensionColumns = anomaly.SeriesKey.AsDictionary(); Assert.That(dimensionColumns.Count, Is.EqualTo(2)); Assert.That(dimensionColumns.ContainsKey("city")); Assert.That(dimensionColumns.ContainsKey("category")); string city = dimensionColumns["city"]; string category = dimensionColumns["category"]; Assert.That(city, Is.Not.Null.And.Not.Empty); Assert.That(category, Is.Not.Null.And.Not.Empty); if (populateOptionalMembers) { Assert.That(anomaly.Severity, Is.EqualTo(AnomalySeverity.Medium)); Assert.That((city == "Delhi" && category == "Handmade") || city == "Kolkata"); } if (++anomalyCount >= MaximumSamplesCount) { break; } } Assert.That(anomalyCount, Is.GreaterThan(0)); }
public async Task CreateAndGetDetectionConfigurationWithSeriesConditions() { // Set required parameters of the configuration to be created. MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient(); string configName = Recording.GenerateAlphaNumericId("config"); var wholeConditions = new MetricWholeSeriesDetectionCondition() { HardThresholdCondition = new (AnomalyDetectorDirection.Both, new (1, 2.0)) { UpperBound = 20.0, LowerBound = 10.0 } }; var configToCreate = new AnomalyDetectionConfiguration(MetricId, configName, wholeConditions); // Set the series conditions and create the configuration. var seriesKey1 = new DimensionKey(); var seriesKey2 = new DimensionKey(); seriesKey1.AddDimensionColumn("city", "Delhi"); seriesKey1.AddDimensionColumn("category", "Handmade"); seriesKey2.AddDimensionColumn("city", "Koltaka"); seriesKey2.AddDimensionColumn("category", "Grocery & Gourmet Food"); var seriesConditions0 = new MetricSingleSeriesDetectionCondition(seriesKey1) { SmartDetectionCondition = new (30.0, AnomalyDetectorDirection.Both, new (3, 4.0)) }; var seriesConditions1 = new MetricSingleSeriesDetectionCondition(seriesKey2) { ChangeThresholdCondition = new (40.0, 12, false, AnomalyDetectorDirection.Up, new (5, 6.0)) }; configToCreate.SeriesDetectionConditions.Add(seriesConditions0); configToCreate.SeriesDetectionConditions.Add(seriesConditions1); await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate); // Get the created configuration and validate top-level members. AnomalyDetectionConfiguration createdConfig = await adminClient.GetDetectionConfigurationAsync(disposableConfig.Id); Assert.That(createdConfig.Id, Is.EqualTo(disposableConfig.Id)); Assert.That(createdConfig.MetricId, Is.EqualTo(MetricId)); Assert.That(createdConfig.Name, Is.EqualTo(configName)); Assert.That(createdConfig.Description, Is.Empty); Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null.And.Empty); // Validate whole series detection conditions. MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions; Assert.That(createdWholeConditions, Is.Not.Null); Assert.That(createdWholeConditions.CrossConditionsOperator, Is.Null); Assert.That(createdWholeConditions.ChangeThresholdCondition, Is.Null); Assert.That(createdWholeConditions.SmartDetectionCondition, Is.Null); ValidateHardThresholdCondition(createdWholeConditions.HardThresholdCondition, AnomalyDetectorDirection.Both, 20.0, 10.0, 1, 2.0); // Start series conditions validation. Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null); Assert.That(createdConfig.SeriesDetectionConditions.Count, Is.EqualTo(2)); // Validate first series conditions. var createdSeriesConditions0 = createdConfig.SeriesDetectionConditions[0]; Assert.That(createdSeriesConditions0, Is.Not.Null); ValidateSeriesKey(createdSeriesConditions0.SeriesKey); Dictionary <string, string> dimensionColumns = createdSeriesConditions0.SeriesKey.AsDictionary(); Assert.That(dimensionColumns["city"], Is.EqualTo("Delhi")); Assert.That(dimensionColumns["category"], Is.EqualTo("Handmade")); Assert.That(createdSeriesConditions0.CrossConditionsOperator, Is.Null); Assert.That(createdSeriesConditions0.HardThresholdCondition, Is.Null); Assert.That(createdSeriesConditions0.ChangeThresholdCondition, Is.Null); ValidateSmartDetectionCondition(createdSeriesConditions0.SmartDetectionCondition, 30.0, AnomalyDetectorDirection.Both, 3, 4.0); // Validate last series conditions. var createdSeriesConditions1 = createdConfig.SeriesDetectionConditions[1]; Assert.That(createdSeriesConditions1, Is.Not.Null); ValidateSeriesKey(createdSeriesConditions1.SeriesKey); dimensionColumns = createdSeriesConditions1.SeriesKey.AsDictionary(); Assert.That(dimensionColumns["city"], Is.EqualTo("Koltaka")); Assert.That(dimensionColumns["category"], Is.EqualTo("Grocery & Gourmet Food")); Assert.That(createdSeriesConditions1.CrossConditionsOperator, Is.Null); Assert.That(createdSeriesConditions1.HardThresholdCondition, Is.Null); Assert.That(createdSeriesConditions1.SmartDetectionCondition, Is.Null); ValidateChangeThresholdCondition(createdSeriesConditions1.ChangeThresholdCondition, 40.0, 12, false, AnomalyDetectorDirection.Up, 5, 6.0); }