Skip to content

Commit d0f4b8b

Browse files
authored
[MetricsAdvisor] Merged MetricsAdvisorKeyCredential UpdateKey methods into single one (Azure#21947)
1 parent dfd877f commit d0f4b8b

File tree

7 files changed

+122
-43
lines changed

7 files changed

+122
-43
lines changed

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- Moved `DatasourceCredential`, `DataFeedSource`, `NotificationHook`, and all of their concrete child types to the `Azure.AI.MetricsAdvisor.Administration` namespace.
1717
- Moved `MetricFeedback` and all of its concrete child types to the `Azure.AI.MetricsAdvisor` namespace.
1818
- Changed order of parameters of `MetricsAdvisorClient.GetMetricEnrichedSeriesData`. Now, `detectionConfigurationId` appears first.
19+
- In `MetricsAdvisorKeyCredential`, merged `UpdateSubscriptionKey` and `UpdateApiKey` into a single method, `Update`, to make it an atomic operation.
1920

2021
## 1.0.0-beta.4 (2021-06-07)
2122

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/api/Azure.AI.MetricsAdvisor.netstandard2.0.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ public enum ServiceVersion
224224
public partial class MetricsAdvisorKeyCredential
225225
{
226226
public MetricsAdvisorKeyCredential(string subscriptionKey, string apiKey) { }
227-
public void UpdateApiKey(string apiKey) { }
228-
public void UpdateSubscriptionKey(string subscriptionKey) { }
227+
public void Update(string subscriptionKey, string apiKey) { }
229228
}
230229
}
231230
namespace Azure.AI.MetricsAdvisor.Administration

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/MetricsAdvisorKeyCredential.cs

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,59 +13,40 @@ namespace Azure.AI.MetricsAdvisor
1313
/// </summary>
1414
public class MetricsAdvisorKeyCredential
1515
{
16-
private string _subscriptionKey;
17-
18-
private string _apiKey;
16+
private Tuple<string, string> _keyPair;
1917

2018
/// <summary>
2119
/// Initializes a new instance of the <see cref="MetricsAdvisorKeyCredential"/> class.
2220
/// </summary>
2321
/// <param name="subscriptionKey">The subscription key to use to authenticate with the Azure service.</param>
24-
/// <param name="apiKey">The API key to use to authenticate the user with the Metrics Advisor service. Used to identify administrators.</param>
22+
/// <param name="apiKey">The API key to use to authenticate the user with the Metrics Advisor service. Used to differentiate administrators and viewers.</param>
2523
/// <exception cref="ArgumentNullException"><paramref name="subscriptionKey"/> or <paramref name="apiKey"/> is null.</exception>
2624
/// <exception cref="ArgumentException"><paramref name="subscriptionKey"/> or <paramref name="apiKey"/> is empty.</exception>
2725
public MetricsAdvisorKeyCredential(string subscriptionKey, string apiKey)
2826
{
29-
UpdateSubscriptionKey(subscriptionKey);
30-
UpdateApiKey(apiKey);
31-
}
32-
33-
internal string SubscriptionKey
34-
{
35-
get => Volatile.Read(ref _subscriptionKey);
36-
private set => Volatile.Write(ref _subscriptionKey, value);
27+
Update(subscriptionKey, apiKey);
3728
}
3829

39-
internal string ApiKey
30+
internal Tuple<string, string> KeyPair
4031
{
41-
get => Volatile.Read(ref _apiKey);
42-
private set => Volatile.Write(ref _apiKey, value);
32+
get => Volatile.Read(ref _keyPair);
33+
private set => Volatile.Write(ref _keyPair, value);
4334
}
4435

4536
/// <summary>
46-
/// Updates the subscription key. This is intended to be used when you've regenerated
47-
/// your subscription key and want to update long lived clients.
37+
/// Updates the subscription and API keys. This is intended to be used when you've regenerated
38+
/// your keys and want to update long lived clients.
4839
/// </summary>
4940
/// <param name="subscriptionKey">The subscription key to authenticate the service against.</param>
50-
/// <exception cref="ArgumentNullException"><paramref name="subscriptionKey"/> is null.</exception>
51-
/// <exception cref="ArgumentException"><paramref name="subscriptionKey"/> is empty.</exception>
52-
public void UpdateSubscriptionKey(string subscriptionKey)
41+
/// <param name="apiKey">The API key to use to authenticate the user with the Metrics Advisor service. Used to differentiate administrators and viewers.</param>
42+
/// <exception cref="ArgumentNullException"><paramref name="subscriptionKey"/> or <paramref name="apiKey"/> is null.</exception>
43+
/// <exception cref="ArgumentException"><paramref name="subscriptionKey"/> or <paramref name="apiKey"/> is empty.</exception>
44+
public void Update(string subscriptionKey, string apiKey)
5345
{
5446
Argument.AssertNotNullOrEmpty(subscriptionKey, nameof(subscriptionKey));
55-
SubscriptionKey = subscriptionKey;
56-
}
57-
58-
/// <summary>
59-
/// Updates the API key. This is intended to be used when you've regenerated your
60-
/// API key and want to update long lived clients.
61-
/// </summary>
62-
/// <param name="apiKey">The API key to use to authenticate the user with the Metrics Advisor service. Used to identify administrators.</param>
63-
/// <exception cref="ArgumentNullException"><paramref name="apiKey"/> is null.</exception>
64-
/// <exception cref="ArgumentException"><paramref name="apiKey"/> is empty.</exception>
65-
public void UpdateApiKey(string apiKey)
66-
{
6747
Argument.AssertNotNullOrEmpty(apiKey, nameof(apiKey));
68-
ApiKey = apiKey;
48+
49+
KeyPair = Tuple.Create(subscriptionKey, apiKey);
6950
}
7051
}
7152
}

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/MetricsAdvisorKeyCredentialPolicy.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using System;
45
using Azure.Core;
56
using Azure.Core.Pipeline;
67

@@ -20,8 +21,10 @@ public override void OnSendingRequest(HttpMessage message)
2021
{
2122
base.OnSendingRequest(message);
2223

23-
message.Request.Headers.SetValue(Constants.SubscriptionAuthorizationHeader, _credential.SubscriptionKey);
24-
message.Request.Headers.SetValue(Constants.ApiAuthorizationHeader, _credential.ApiKey);
24+
Tuple<string, string> keyPair = _credential.KeyPair;
25+
26+
message.Request.Headers.SetValue(Constants.SubscriptionAuthorizationHeader, keyPair.Item1);
27+
message.Request.Headers.SetValue(Constants.ApiAuthorizationHeader, keyPair.Item2);
2528
}
2629
}
2730
}

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/tests/MetricsAdvisorAdministrationClient/NotificationHookLiveTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Linq;
77
using System.Threading.Tasks;
88
using Azure.AI.MetricsAdvisor.Administration;
9-
using Azure.AI.MetricsAdvisor.Models;
109
using Azure.Core.TestFramework;
1110
using NUnit.Framework;
1211

sdk/metricsadvisor/Azure.AI.MetricsAdvisor/tests/MockClientTestBase.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,25 @@ public MockClientTestBase(bool isAsync) : base(isAsync)
1818

1919
public string FakeGuid => "00000000-0000-0000-0000-000000000000";
2020

21-
public MetricsAdvisorClient CreateInstrumentedClient(MockResponse response)
21+
public MetricsAdvisorClient CreateInstrumentedClient(MockResponse response) =>
22+
CreateInstrumentedClient(new MockTransport(response));
23+
24+
public MetricsAdvisorClient CreateInstrumentedClient(MockTransport transport, MetricsAdvisorKeyCredential credential = null)
2225
{
2326
var fakeEndpoint = new Uri("http://notreal.azure.com");
24-
var fakeCredential = new MetricsAdvisorKeyCredential("fakeSubscriptionKey", "fakeApiKey");
25-
var options = new MetricsAdvisorClientsOptions() { Transport = new MockTransport(response) };
27+
var fakeCredential = credential ?? new MetricsAdvisorKeyCredential("fakeSubscriptionKey", "fakeApiKey");
28+
var options = new MetricsAdvisorClientsOptions() { Transport = transport };
2629

2730
return InstrumentClient(new MetricsAdvisorClient(fakeEndpoint, fakeCredential, options));
2831
}
2932

3033
public MetricsAdvisorAdministrationClient CreateInstrumentedAdministrationClient(MockResponse response) =>
3134
CreateInstrumentedAdministrationClient(new MockTransport(response));
3235

33-
public MetricsAdvisorAdministrationClient CreateInstrumentedAdministrationClient(MockTransport transport)
36+
public MetricsAdvisorAdministrationClient CreateInstrumentedAdministrationClient(MockTransport transport, MetricsAdvisorKeyCredential credential = null)
3437
{
3538
var fakeEndpoint = new Uri("http://notreal.azure.com");
36-
var fakeCredential = new MetricsAdvisorKeyCredential("fakeSubscriptionKey", "fakeApiKey");
39+
var fakeCredential = credential ?? new MetricsAdvisorKeyCredential("fakeSubscriptionKey", "fakeApiKey");
3740
var options = new MetricsAdvisorClientsOptions() { Transport = transport };
3841

3942
return InstrumentClient(new MetricsAdvisorAdministrationClient(fakeEndpoint, fakeCredential, options));
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
using Azure.AI.MetricsAdvisor.Administration;
8+
using Azure.Core.TestFramework;
9+
using NUnit.Framework;
10+
11+
namespace Azure.AI.MetricsAdvisor.Tests
12+
{
13+
public class MetricsAdvisorKeyCredentialTests : MockClientTestBase
14+
{
15+
public MetricsAdvisorKeyCredentialTests(bool isAsync) : base(isAsync)
16+
{
17+
}
18+
19+
[Test]
20+
public async Task MetricsAdvisorKeyCredentialSendsSecretInMetricsAdvisorClient()
21+
{
22+
MockResponse response = new MockResponse(200);
23+
response.SetContent("{}");
24+
25+
MockTransport mockTransport = new MockTransport(response);
26+
27+
string expectedSubscriptionKey = "fakeSubscriptionKey";
28+
string expectedApiKey = "fakeApiKey";
29+
MetricsAdvisorKeyCredential credential = new MetricsAdvisorKeyCredential(expectedSubscriptionKey, expectedApiKey);
30+
31+
MetricsAdvisorClient client = CreateInstrumentedClient(mockTransport, credential);
32+
33+
IAsyncEnumerator<MetricFeedback> asyncEnumerator = client.GetAllFeedbackAsync(FakeGuid).GetAsyncEnumerator();
34+
await asyncEnumerator.MoveNextAsync();
35+
36+
MockRequest request = mockTransport.Requests.First();
37+
38+
Assert.That(request.Headers.TryGetValue(Constants.SubscriptionAuthorizationHeader, out string subscriptionKey));
39+
Assert.That(request.Headers.TryGetValue(Constants.ApiAuthorizationHeader, out string apiKey));
40+
41+
Assert.That(subscriptionKey, Is.EqualTo(expectedSubscriptionKey));
42+
Assert.That(apiKey, Is.EqualTo(expectedApiKey));
43+
}
44+
45+
[Test]
46+
public async Task MetricsAdvisorKeyCredentialSendsSecretInMetricsAdvisorAdministrationClient()
47+
{
48+
MockResponse response = new MockResponse(204);
49+
MockTransport mockTransport = new MockTransport(response);
50+
51+
string expectedSubscriptionKey = "fakeSubscriptionKey";
52+
string expectedApiKey = "fakeApiKey";
53+
MetricsAdvisorKeyCredential credential = new MetricsAdvisorKeyCredential(expectedSubscriptionKey, expectedApiKey);
54+
55+
MetricsAdvisorAdministrationClient adminClient = CreateInstrumentedAdministrationClient(mockTransport, credential);
56+
57+
await adminClient.DeleteAlertConfigurationAsync(FakeGuid);
58+
59+
MockRequest request = mockTransport.Requests.First();
60+
61+
Assert.That(request.Headers.TryGetValue(Constants.SubscriptionAuthorizationHeader, out string subscriptionKey));
62+
Assert.That(request.Headers.TryGetValue(Constants.ApiAuthorizationHeader, out string apiKey));
63+
64+
Assert.That(subscriptionKey, Is.EqualTo(expectedSubscriptionKey));
65+
Assert.That(apiKey, Is.EqualTo(expectedApiKey));
66+
}
67+
68+
[Test]
69+
public async Task MetricsAdvisorKeyCredentialUpdatesSecret()
70+
{
71+
MockResponse response = new MockResponse(204);
72+
MockTransport mockTransport = new MockTransport(response);
73+
MetricsAdvisorKeyCredential credential = new MetricsAdvisorKeyCredential("fakeSubscriptionKey", "fakeApiKey");
74+
75+
string expectedSubscriptionKey = "newFakeSubscriptionKey";
76+
string expectedApiKey = "newFakeApiKey";
77+
78+
MetricsAdvisorAdministrationClient adminClient = CreateInstrumentedAdministrationClient(mockTransport, credential);
79+
80+
credential.Update(expectedSubscriptionKey, expectedApiKey);
81+
82+
await adminClient.DeleteAlertConfigurationAsync(FakeGuid);
83+
84+
MockRequest request = mockTransport.Requests.First();
85+
86+
Assert.That(request.Headers.TryGetValue(Constants.SubscriptionAuthorizationHeader, out string subscriptionKey));
87+
Assert.That(request.Headers.TryGetValue(Constants.ApiAuthorizationHeader, out string apiKey));
88+
89+
Assert.That(subscriptionKey, Is.EqualTo(expectedSubscriptionKey));
90+
Assert.That(apiKey, Is.EqualTo(expectedApiKey));
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)