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

Add lookup mechanism for ID to apiversion #19437

Merged
merged 48 commits into from
Mar 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
bd06bf1
WIP: updates
bquantump Mar 8, 2021
a11a769
WIP: updates
bquantump Mar 10, 2021
71dabee
Merge branch 'feature/mgmt-track2' of https://github.com/Azure/azure-…
bquantump Mar 10, 2021
b72173b
Update test
bquantump Mar 10, 2021
79cb491
Update ResourceListOperationsTest.cs
bquantump Mar 11, 2021
f4162e3
Update CreateSingleVmExample.cs
bquantump Mar 11, 2021
ff8d333
Update CreateSingleVmExample.cs
bquantump Mar 11, 2021
9fa1e0c
Update CreateSingleVmExample.cs
bquantump Mar 11, 2021
a9da33b
Update CreateSingleVmExample.cs
bquantump Mar 11, 2021
e35f07c
WIP: Updates
bquantump Mar 11, 2021
d884f56
Add extra line
bquantump Mar 11, 2021
fcc2aab
Update
bquantump Mar 11, 2021
4f2dae5
WIP:
bquantump Mar 11, 2021
aee7547
WIP: updates
bquantump Mar 15, 2021
6b7ba0f
Merge branch 'mgmt-track2' of https://github.com/AME-Redmond/azure-sd…
bquantump Mar 15, 2021
db3b7f4
WIp: updates
bquantump Mar 15, 2021
e5fd067
Remove API version extensions
bquantump Mar 16, 2021
93da13a
WIP: updates
bquantump Mar 16, 2021
baacd99
Updates
bquantump Mar 16, 2021
c398fb8
Update test
bquantump Mar 16, 2021
8e5f11d
WIP updates
bquantump Mar 16, 2021
2f47da4
Merge branch 'feature/mgmt-track2' into stevens_5117
bquantump Mar 16, 2021
757015c
Updates
bquantump Mar 17, 2021
2bc016e
WIP
bquantump Mar 17, 2021
6bdf327
Remove blank lines
bquantump Mar 17, 2021
45c23e7
Update filtering
bquantump Mar 17, 2021
af3d5e6
Updates
bquantump Mar 17, 2021
5ec195c
Update
bquantump Mar 18, 2021
847e593
WIP: updates
bquantump Mar 18, 2021
d76be3f
WIP: updates
bquantump Mar 18, 2021
f267bf3
Add space
bquantump Mar 18, 2021
26f4385
Remove debug
bquantump Mar 18, 2021
9e26522
Updates
bquantump Mar 18, 2021
fcba084
WIP: updates
bquantump Mar 22, 2021
3dc030d
WIP
bquantump Mar 22, 2021
10f6ad0
Change the accessbility to virtual for Resource.Id
YalinLi0312 Mar 24, 2021
b8291aa
WIP: updates
bquantump Mar 25, 2021
db74f22
WIP Updates
bquantump Mar 25, 2021
ff09cb4
Merge branch 'mgmt-track2' of https://github.com/AME-Redmond/azure-sd…
bquantump Mar 25, 2021
428f6bc
WIP updates
bquantump Mar 26, 2021
2013b78
WIP
bquantump Mar 26, 2021
6a2dec1
WIP
bquantump Mar 26, 2021
9ea1997
WIP:
bquantump Mar 26, 2021
00b5d31
revert
bquantump Mar 26, 2021
431479a
WIP: updates
bquantump Mar 26, 2021
69a6f6b
WIP: updates
bquantump Mar 26, 2021
804515d
WIP: updated
bquantump Mar 26, 2021
b01050c
WIP
bquantump Mar 26, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ private AzureResourceManagerClient GetCleanupClient()
return null;
}

protected AzureResourceManagerClient GetArmClient()
protected AzureResourceManagerClient GetArmClient(AzureResourceManagerClientOptions clientOptions = default)
{
var options = InstrumentClientOptions(new AzureResourceManagerClientOptions());
var options = InstrumentClientOptions(clientOptions ?? new AzureResourceManagerClientOptions());
options.AddPolicy(CleanupPolicy, HttpPipelinePosition.PerCall);

return CreateClient<AzureResourceManagerClient>(
Expand Down Expand Up @@ -107,7 +107,7 @@ protected void StopSessionRecording()
{
throw new InvalidOperationException("The test didn't instrument any clients but had recordings. Please call InstrumentClient for the client being recorded.");
}

SessionRecording?.Dispose(true);
GlobalClient = null;
}
Expand Down
189 changes: 189 additions & 0 deletions sdk/resourcemanager/Azure.ResourceManager.Core/src/ApiVersions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using Azure.ResourceManager.Resources;
using System.Reflection;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Threading;
using Azure.Core;
using Azure.ResourceManager.Resources.Models;

namespace Azure.ResourceManager.Core
{
/// <summary>
/// A class representing Azure resource manager client options.
/// </summary>
public class ApiVersions
{
private ProvidersOperations ProviderOperations;
private AzureResourceManagerClientOptions _clientOptions;

/// <summary>
/// Initializes a new instance of the <see cref="ApiVersions"/> class.
/// </summary>
internal ApiVersions(AzureResourceManagerClientOptions clientOptions)
{
BuildApiTable(clientOptions);
_clientOptions = clientOptions;
ProviderOperations = null;
}

/// <summary>
/// Make a provider resource client class.
/// </summary>
internal void SetProviderClient(TokenCredential credential, Uri baseUri, string subscription)
{
ProviderOperations = new ResourcesManagementClient(
baseUri,
subscription,
credential,
_clientOptions.Convert<ResourcesManagementClientOptions>()).Providers;
}

private Dictionary<string, PropertyWrapper> _loadedResourceToApiVersions = new Dictionary<string, PropertyWrapper>();
private Dictionary<string, string> _nonLoadedResourceToApiVersion = new Dictionary<string, string>();

private void BuildApiTable(AzureResourceManagerClientOptions clientOptions)
{
var methods = GetExtensionMethods();
foreach (var method in methods)
{
if (method.Name.EndsWith("RestApiVersions", StringComparison.Ordinal))
{
var apiObject = method.Invoke(null, new object[] { clientOptions });
var properties = apiObject.GetType().GetProperties();
foreach (var prop in properties)
{
if (prop.GetValue(apiObject) is ApiVersionsBase propVal)
{
var key = propVal.ResourceType;
_loadedResourceToApiVersions.Add(key.ToString(), new PropertyWrapper(prop, apiObject));
}
}
}
}
}

private static IEnumerable<MethodInfo> GetExtensionMethods()
{
// See TODO ADO #5692
var results =
m-nash marked this conversation as resolved.
Show resolved Hide resolved
from assembly in AppDomain.CurrentDomain.GetAssemblies()
where assembly.GetName().ToString().StartsWith("Azure.", StringComparison.Ordinal) || assembly.GetName().ToString().StartsWith("Proto.", StringComparison.Ordinal)
from type in assembly.GetTypes()
where type.IsSealed && !type.IsGenericType && !type.IsNested && type.Name.Equals("AzureResourceManagerClientOptionsExtensions", StringComparison.Ordinal)
from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == typeof(AzureResourceManagerClientOptions)
select method;
return results;
}

private string LoadApiVersion(ResourceType resourceType, CancellationToken cancellationToken)
{
Response<Provider> results;
try
{
results = ProviderOperations.Get(resourceType.Namespace, null, cancellationToken);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
return null;
}
foreach (var type in results.Value.ResourceTypes)
{
if (type.ResourceType.Equals(resourceType.Type))
{
_nonLoadedResourceToApiVersion.Add(resourceType.ToString(), type.ApiVersions[0]);
return type.ApiVersions[0];
}
}
return null;
}

private async Task<string> LoadApiVersionAsync(ResourceType resourceType, CancellationToken cancellationToken)
{
Response<Provider> results;
try
{
results = await ProviderOperations.GetAsync(resourceType.Namespace, null, cancellationToken).ConfigureAwait(false);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
return null;
}
foreach (var type in results.Value.ResourceTypes)
{
if (type.ResourceType.Equals(resourceType.Type))
{
_nonLoadedResourceToApiVersion.Add(resourceType.ToString(), type.ApiVersions[0]);
return type.ApiVersions[0];
}
}
return null;
}

/// <summary>
/// Try to get api version for a give resource id, returns null if will use the latest API version for the given resources
/// </summary>
public string TryGetApiVersion(ResourceType resourceType, CancellationToken cancellationToken = default)
{
string val;
if (TryGetApiVersion(resourceType.ToString(), out val))
{
return val;
}
return ProviderOperations == null ? null : LoadApiVersion(resourceType.ToString(), cancellationToken);
}

/// <summary>
/// Try to get api version for a give resource id, returns null if will use the latest API version for the given resources
/// </summary>
public async Task<string> TryGetApiVersionAsync(ResourceType resourceType, CancellationToken cancellationToken = default)
{
string val;
if (TryGetApiVersion(resourceType.ToString(), out val))
{
return val;
}
return ProviderOperations == null ? null : await LoadApiVersionAsync(resourceType.ToString(), cancellationToken).ConfigureAwait(false);
}

private bool TryGetApiVersion(string resourceType, out string val)
{
PropertyWrapper propertyWrapper;
if (_loadedResourceToApiVersions.TryGetValue(resourceType, out propertyWrapper))
{
val = propertyWrapper.GetValue();
return true;
}

if (_nonLoadedResourceToApiVersion.TryGetValue(resourceType, out val))
{
return true;
}
val = null;
return false;
}

/// <summary>
/// Set the API version given a resource ID
/// </summary>
public void SetApiVersion(ResourceType resourceType, string apiVersion)
{
PropertyWrapper propertyWrapper;
if (_loadedResourceToApiVersions.TryGetValue(resourceType.ToString(), out propertyWrapper))
{
propertyWrapper.SetValue(apiVersion);
}
else
{
_nonLoadedResourceToApiVersion[resourceType.ToString()] = apiVersion;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public static implicit operator string(ApiVersionsBase version)
return version._value;
}

/// <summary>
/// Implicit operator to convert ApiVersionsBase to string.
/// </summary>
/// <returns> API version value. </returns>
public virtual ResourceType ResourceType {get; }

/// <summary>
/// Overrides == operator for comparing ApiVersionsBase object with string object.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ private AzureResourceManagerClient(
_credentials = credential;
_baseUri = baseUri;
_clientOptions = options ?? new AzureResourceManagerClientOptions();

DefaultSubscription = string.IsNullOrWhiteSpace(defaultSubscriptionId)
? GetDefaultSubscription()
: GetSubscriptionOperations(defaultSubscriptionId).Get().Value;
_clientOptions.ApiVersions.SetProviderClient(credential, baseUri, DefaultSubscription.Id.Subscription);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Azure.ResourceManager.Core
{
Expand All @@ -17,6 +20,11 @@ public sealed class AzureResourceManagerClientOptions : ClientOptions
{
private readonly ConcurrentDictionary<Type, object> _overrides = new ConcurrentDictionary<Type, object>();

/// <summary>
/// Gets the ApiVersions object
/// </summary>
public ApiVersions ApiVersions { get; }

/// <summary>
/// Initializes a new instance of the <see cref="AzureResourceManagerClientOptions"/> class.
/// </summary>
Expand Down Expand Up @@ -50,6 +58,7 @@ internal AzureResourceManagerClientOptions(LocationData defaultLocation, AzureRe
Copy(other);
DefaultLocation = defaultLocation;
ApiVersionOverrides = new Dictionary<string, string>();
ApiVersions = new ApiVersions(this);
}

/// <summary>
Expand Down
Loading