Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MetricsAdvisor] Made NotificationHook constructors parameterless #18475

Merged
merged 5 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sdk/metricsadvisor/Azure.AI.MetricsAdvisor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,21 @@
- The constructor of the `MetricSingleSeriesDetectionCondition` class is now parameterless. Dimension columns can be added directly to `SeriesKey`.
- The constructor of the `MetricSeriesGroupDetectionCondition` class is now parameterless. Dimension columns can be added directly to `SeriesGroupKey`.
- The constructor of the `AnomalyAlertConfiguration` class is now parameterless. Required properties should be set via setters.
- The constructor of the `EmailNotificationHook` and `WebNotificationHook` are now parameterless. Required properies should be set via setters.
- In `DataFeed`, added property setters to `Name`, `DataSource`, `Granularity`, `IngestionSettings`, and `Schema`.
- In `DataFeedIngestionSettings`, added a property setter to `IngestionStartTime`.
- In `AnomalyDetectionConfiguration`, added property setters to `MetricId`, `Name`, and `WholeSeriesDetectionConditions`.
- In `AnomalyAlertConfiguration`, added a property setter to `Name`.
- In `MetricAnomalyAlertSnoozeCondition`, added property setters to `AutoSnooze`, `IsOnlyForSuccessive`, and `SnoozeScope`.
- In `MetricBoundaryCondition`, added a property setter to `Direction`.
- In `SeverityCondition`, added property setters to `MaximumAlertSeverity` and `MinimumAlertSeverity`.
- In `NotificationHook`, added a property setter to `Name`.
- In `WebNotificationHook`, added a property setter to `Endpoint`.
- In `DataFeed`, removed the setters of the properties `Administrators` and `Viewers`.
- In `DataFeedSchema`, removed the setter of the property `DimensionColumns`.
- In `DataFeedRollupSettings`, removed the setter of the property `AutoRollupGroupByColumnNames`.
- In `AnomalyDetectionConfiguration`, removed the setters of the properties `SeriesDetectionConditions` and `SeriesGroupDetectionConditions`.
- In `WebNotificationHook`, removed the setter of the property `Headers`.
- `DataFeed.SourceType` is now nullable. It will be null whenever `DataFeed.DataSource` is null.
- `DataFeed.IngestionStartTime` is now nullable.
- `MetricsAdvisorAdministrationClient.CreateDataFeed` sync and async methods now throw an `ArgumentException` if required properties are not set properly.
Expand Down
9 changes: 5 additions & 4 deletions sdk/metricsadvisor/Azure.AI.MetricsAdvisor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,14 @@ Metrics Advisor supports the [`EmailNotificationHook`](#notification-hook) and t

```C# Snippet:CreateHookAsync
string hookName = "Sample hook";
var emailsToAlert = new List<string>()

var emailHook = new EmailNotificationHook()
{
"[email protected]",
"[email protected]"
Name = hookName
};

var emailHook = new EmailNotificationHook(hookName, emailsToAlert);
emailHook.EmailsToAlert.Add("[email protected]");
emailHook.EmailsToAlert.Add("[email protected]");

Response<string> response = await adminClient.CreateHookAsync(emailHook);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ public ElasticsearchDataFeedSource(string host, string port, string authorizatio
}
public partial class EmailNotificationHook : Azure.AI.MetricsAdvisor.Models.NotificationHook
{
public EmailNotificationHook(string name, System.Collections.Generic.IList<string> emailsToAlert) { }
public EmailNotificationHook() { }
public System.Collections.Generic.IList<string> EmailsToAlert { get { throw null; } }
}
public partial class EnrichmentStatus
Expand Down Expand Up @@ -1072,7 +1072,7 @@ internal NotificationHook() { }
public string Description { get { throw null; } set { } }
public string ExternalLink { get { throw null; } set { } }
public string Id { get { throw null; } }
public string Name { get { throw null; } }
public string Name { get { throw null; } set { } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct PeriodType : System.IEquatable<Azure.AI.MetricsAdvisor.Models.PeriodType>
Expand Down Expand Up @@ -1150,11 +1150,11 @@ public TopNGroupScope(int top, int period, int minimumTopCount) { }
}
public partial class WebNotificationHook : Azure.AI.MetricsAdvisor.Models.NotificationHook
{
public WebNotificationHook(string name, string endpoint) { }
public WebNotificationHook() { }
public string CertificateKey { get { throw null; } set { } }
public string CertificatePassword { get { throw null; } set { } }
public string Endpoint { get { throw null; } }
public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } set { } }
public string Endpoint { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } }
public string Password { get { throw null; } set { } }
public string Username { get { throw null; } set { } }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ Page<DataFeed> NextPageFunc(string nextLink, int? pageSizeHint)
/// <exception cref="ArgumentException"><paramref name="dataFeed"/>.Name is empty.</exception>
public virtual async Task<Response<string>> CreateDataFeedAsync(DataFeed dataFeed, CancellationToken cancellationToken = default)
{
ValidateDataFeedToCreate(dataFeed);
ValidateDataFeedToCreate(dataFeed, nameof(dataFeed));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateDataFeed)}");
scope.Start();
Expand Down Expand Up @@ -311,7 +311,7 @@ public virtual async Task<Response<string>> CreateDataFeedAsync(DataFeed dataFee
/// <exception cref="ArgumentException"><paramref name="dataFeed"/>.Name is empty.</exception>
public virtual Response<string> CreateDataFeed(DataFeed dataFeed, CancellationToken cancellationToken = default)
{
ValidateDataFeedToCreate(dataFeed);
ValidateDataFeedToCreate(dataFeed, nameof(dataFeed));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateDataFeed)}");
scope.Start();
Expand Down Expand Up @@ -680,15 +680,15 @@ private static IReadOnlyList<DataFeed> ConvertToDataFeeds(IReadOnlyList<DataFeed
return dataFeeds;
}

private static void ValidateDataFeedToCreate(DataFeed dataFeed)
private static void ValidateDataFeedToCreate(DataFeed dataFeed, string paramName)
{
Argument.AssertNotNull(dataFeed, nameof(dataFeed));
Argument.AssertNotNullOrEmpty(dataFeed.Name, $"{nameof(dataFeed)}.{nameof(dataFeed.Name)}");
Argument.AssertNotNull(dataFeed.DataSource, $"{nameof(dataFeed)}.{nameof(dataFeed.DataSource)}");
Argument.AssertNotNull(dataFeed.Granularity, $"{nameof(dataFeed)}.{nameof(dataFeed.Granularity)}");
Argument.AssertNotNull(dataFeed.Schema, $"{nameof(dataFeed)}.{nameof(dataFeed.Schema)}");
Argument.AssertNotNull(dataFeed.IngestionSettings, $"{nameof(dataFeed)}.{nameof(dataFeed.IngestionSettings)}");
Argument.AssertNotNull(dataFeed.IngestionSettings.IngestionStartTime, $"{nameof(dataFeed)}.{nameof(dataFeed.IngestionSettings)}.{nameof(dataFeed.IngestionSettings.IngestionStartTime)}");
Argument.AssertNotNull(dataFeed, paramName);
Argument.AssertNotNullOrEmpty(dataFeed.Name, $"{paramName}.{nameof(dataFeed.Name)}");
Argument.AssertNotNull(dataFeed.DataSource, $"{paramName}.{nameof(dataFeed.DataSource)}");
Argument.AssertNotNull(dataFeed.Granularity, $"{paramName}.{nameof(dataFeed.Granularity)}");
Argument.AssertNotNull(dataFeed.Schema, $"{paramName}.{nameof(dataFeed.Schema)}");
Argument.AssertNotNull(dataFeed.IngestionSettings, $"{paramName}.{nameof(dataFeed.IngestionSettings)}");
Argument.AssertNotNull(dataFeed.IngestionSettings.IngestionStartTime, $"{paramName}.{nameof(dataFeed.IngestionSettings)}.{nameof(dataFeed.IngestionSettings.IngestionStartTime)}");
}

#endregion DataFeed
Expand All @@ -708,7 +708,7 @@ private static void ValidateDataFeedToCreate(DataFeed dataFeed)
/// <exception cref="ArgumentException"><paramref name="detectionConfiguration"/>.MetricId or <paramref name="detectionConfiguration"/>.Name is empty.</exception>
public virtual async Task<Response<string>> CreateDetectionConfigurationAsync(AnomalyDetectionConfiguration detectionConfiguration, CancellationToken cancellationToken = default)
{
ValidateDetectionConfigurationToCreate(detectionConfiguration);
ValidateDetectionConfigurationToCreate(detectionConfiguration, nameof(detectionConfiguration));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateDetectionConfiguration)}");
scope.Start();
Expand Down Expand Up @@ -740,7 +740,7 @@ public virtual async Task<Response<string>> CreateDetectionConfigurationAsync(An
/// <exception cref="ArgumentException"><paramref name="detectionConfiguration"/>.MetricId or <paramref name="detectionConfiguration"/>.Name is empty.</exception>
public virtual Response<string> CreateDetectionConfiguration(AnomalyDetectionConfiguration detectionConfiguration, CancellationToken cancellationToken = default)
{
ValidateDetectionConfigurationToCreate(detectionConfiguration);
ValidateDetectionConfigurationToCreate(detectionConfiguration, nameof(detectionConfiguration));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateDetectionConfiguration)}");
scope.Start();
Expand Down Expand Up @@ -1009,12 +1009,12 @@ public virtual Response DeleteDetectionConfiguration(string detectionConfigurati
}
}

private static void ValidateDetectionConfigurationToCreate(AnomalyDetectionConfiguration configuration)
private static void ValidateDetectionConfigurationToCreate(AnomalyDetectionConfiguration configuration, string paramName)
{
Argument.AssertNotNull(configuration, nameof(configuration));
Argument.AssertNotNullOrEmpty(configuration.MetricId, $"{nameof(configuration)}.{nameof(AnomalyDetectionConfiguration.MetricId)}");
Argument.AssertNotNullOrEmpty(configuration.Name, $"{nameof(configuration)}.{nameof(AnomalyDetectionConfiguration.Name)}");
Argument.AssertNotNull(configuration.WholeSeriesDetectionConditions, $"{nameof(configuration)}.{nameof(AnomalyDetectionConfiguration.WholeSeriesDetectionConditions)}");
Argument.AssertNotNull(configuration, paramName);
Argument.AssertNotNullOrEmpty(configuration.MetricId, $"{paramName}.{nameof(AnomalyDetectionConfiguration.MetricId)}");
Argument.AssertNotNullOrEmpty(configuration.Name, $"{paramName}.{nameof(AnomalyDetectionConfiguration.Name)}");
Argument.AssertNotNull(configuration.WholeSeriesDetectionConditions, $"{paramName}.{nameof(AnomalyDetectionConfiguration.WholeSeriesDetectionConditions)}");
}

#endregion AnomalyDetectionConfiguration
Expand Down Expand Up @@ -1354,12 +1354,7 @@ public virtual Response DeleteAlertConfiguration(string alertConfigurationId, Ca
/// <exception cref="ArgumentException"><paramref name="hook"/> is an <see cref="EmailNotificationHook"/> and <paramref name="hook"/>.EmailsToAlert is empty.</exception>
public virtual async Task<Response<string>> CreateHookAsync(NotificationHook hook, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(hook, nameof(hook));

if (hook is EmailNotificationHook emailHook)
{
Argument.AssertNotNullOrEmpty(emailHook.EmailsToAlert, nameof(EmailNotificationHook.EmailsToAlert));
}
ValidateHookToCreate(hook, nameof(hook));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateHook)}");
scope.Start();
Expand Down Expand Up @@ -1391,12 +1386,7 @@ public virtual async Task<Response<string>> CreateHookAsync(NotificationHook hoo
/// <exception cref="ArgumentException"><paramref name="hook"/> is an <see cref="EmailNotificationHook"/> and <paramref name="hook"/>.EmailsToAlert is empty.</exception>
public virtual Response<string> CreateHook(NotificationHook hook, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(hook, nameof(hook));

if (hook is EmailNotificationHook emailHook)
{
Argument.AssertNotNullOrEmpty(emailHook.EmailsToAlert, nameof(EmailNotificationHook.EmailsToAlert));
}
ValidateHookToCreate(hook, nameof(hook));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(CreateHook)}");
scope.Start();
Expand Down Expand Up @@ -1431,11 +1421,6 @@ public virtual async Task<Response> UpdateHookAsync(string hookId, NotificationH
Guid hookGuid = ClientCommon.ValidateGuid(hookId, nameof(hookId));
Argument.AssertNotNull(hook, nameof(hook));

if (hook is EmailNotificationHook emailHook)
{
Argument.AssertNotNullOrEmpty(emailHook.EmailsToAlert, nameof(EmailNotificationHook.EmailsToAlert));
}

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(UpdateHook)}");
scope.Start();

Expand Down Expand Up @@ -1468,11 +1453,6 @@ public virtual Response UpdateHook(string hookId, NotificationHook hook, Cancell
Guid hookGuid = ClientCommon.ValidateGuid(hookId, nameof(hookId));
Argument.AssertNotNull(hook, nameof(hook));

if (hook is EmailNotificationHook emailHook)
{
Argument.AssertNotNullOrEmpty(emailHook.EmailsToAlert, nameof(EmailNotificationHook.EmailsToAlert));
}

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MetricsAdvisorAdministrationClient)}.{nameof(UpdateHook)}");
scope.Start();

Expand Down Expand Up @@ -1693,6 +1673,25 @@ Page<NotificationHook> NextPageFunc(string nextLink, int? pageSizeHint)
return PageableHelpers.CreateEnumerable(FirstPageFunc, NextPageFunc);
}

private static void ValidateHookToCreate(NotificationHook hook, string paramName)
{
Argument.AssertNotNull(hook, paramName);
Argument.AssertNotNullOrEmpty(hook.Name, $"{paramName}.{nameof(hook.Name)}");

if (hook is EmailNotificationHook emailHook)
{
Argument.AssertNotNullOrEmpty(emailHook.EmailsToAlert, $"{paramName}.{nameof(EmailNotificationHook.EmailsToAlert)}");
}
else if (hook is WebNotificationHook webHook)
{
Argument.AssertNotNullOrEmpty(webHook.Endpoint, $"{paramName}.{nameof(WebNotificationHook.Endpoint)}");
}
else
{
throw new ArgumentException($"Invalid hook type. A hook must be created from an ${nameof(EmailNotificationHook)} or a {nameof(WebNotificationHook)} instance.");
}
}

#endregion NotificationHook
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using Azure.Core;

Expand All @@ -17,35 +16,28 @@ public partial class EmailNotificationHook : NotificationHook
{
/// <summary>
/// Initializes a new instance of the <see cref="EmailNotificationHook"/> class.
/// <param name="name">The name to assign to the hook.</param>
/// <param name="emailsToAlert">The list of e-mail addresses to alert.</param>
/// <exception cref="ArgumentNullException"><paramref name="name"/> or <paramref name="emailsToAlert"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="name"/> is empty.</exception>
/// </summary>
public EmailNotificationHook(string name, IList<string> emailsToAlert)
: base(name)
public EmailNotificationHook()
{
Argument.AssertNotNull(emailsToAlert, nameof(emailsToAlert));

HookParameter = new EmailHookParameter(emailsToAlert);
HookType = HookType.Email;
EmailsToAlert = new ChangeTrackingList<string>();
}

internal EmailNotificationHook(HookType hookType, string id, string name, string description, string externalLink, IReadOnlyList<string> administrators, EmailHookParameter hookParameter)
: base(hookType, id, name, description, externalLink, administrators)
{
HookParameter = hookParameter;
HookType = hookType;
EmailsToAlert = hookParameter.ToList;
}

/// <summary>
/// The list of e-mail addresses to alert.
/// </summary>
public IList<string> EmailsToAlert => HookParameter.ToList;
public IList<string> EmailsToAlert { get; }

/// <summary>
/// Used by CodeGen during serialization.
/// </summary>
internal EmailHookParameter HookParameter { get; }
internal EmailHookParameter HookParameter => new EmailHookParameter(EmailsToAlert);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ namespace Azure.AI.MetricsAdvisor.Models
/// An alert notification to be triggered after an anomaly is detected by Metrics Advisor.
/// </summary>
[CodeGenModel("HookInfo")]
[CodeGenSuppress(nameof(NotificationHook), typeof(string))]
public partial class NotificationHook
{
internal NotificationHook(string name)
internal NotificationHook()
{
Argument.AssertNotNullOrEmpty(name, nameof(name));

Name = name;
}

/// <summary>
Expand All @@ -30,7 +28,7 @@ internal NotificationHook(string name)
/// The name of the hook.
/// </summary>
[CodeGenMember("HookName")]
public string Name { get; }
public string Name { get; set; }

/// <summary>
/// The list of user e-mails with administrative rights to manage this hook.
Expand Down
Loading