diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs
index ac7ce5335c1b..5b0925c4b983 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs
@@ -7,22 +7,24 @@ namespace Azure.ResourceManager.Core
/// A class representing a generic proxy resource in Azure
///
/// The type of the underlying model this class wraps
- public abstract class ProxyResource : Resource
- where TModel : class
+ /// The type of the underlying modelresource Id
+ public abstract class ProxyResource : Resource
+ where TModel : class
+ where TIdentifier : TenantResourceIdentifier
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The identifier of the resource that is the target of operations.
/// The model to copy from.
- protected ProxyResource(ResourceIdentifier id, TModel data)
+ protected ProxyResource(TIdentifier id, TModel data)
{
Id = id;
Model = data;
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The identifier of the resource that is the target of operations.
/// The model to copy from.
@@ -34,7 +36,7 @@ protected ProxyResource(string id, TModel data)
}
else
{
- Id = id;
+ Id = ResourceIdentifier.Create(id) as TIdentifier;
}
Model = data;
@@ -43,7 +45,7 @@ protected ProxyResource(string id, TModel data)
///
/// Gets or sets the identifier for the resource.
///
- public override ResourceIdentifier Id { get; protected set; }
+ public override TIdentifier Id { get; protected set; }
///
/// Gets or sets the Model this resource is based off.
@@ -51,10 +53,10 @@ protected ProxyResource(string id, TModel data)
public virtual TModel Model { get; set; }
///
- /// Converts from a into the TModel.
+ /// Converts from a into the TModel.
///
/// The tracked resource convert from.
- public static implicit operator TModel(ProxyResource other)
+ public static implicit operator TModel(ProxyResource other)
{
return other.Model;
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs
index f6aed917167f..4a3ae7ccf0b2 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs
@@ -8,17 +8,19 @@ namespace Azure.ResourceManager.Core
///
/// A class representing a generic tracked resource in Azure.
///
+ /// The type of the underlying resource id
/// The type of the underlying model this class wraps
- public abstract class TrackedResource : TrackedResource
+ public abstract class TrackedResource : TrackedResource
+ where TIdentifier : TenantResourceIdentifier
where TModel : class
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The identifier of the resource that is the target of operations.
/// The location of the resource.
/// The model to copy from.
- protected TrackedResource(ResourceIdentifier id, LocationData location, TModel data)
+ protected TrackedResource(TIdentifier id, LocationData location, TModel data)
{
Id = id;
Location = location;
@@ -26,7 +28,7 @@ protected TrackedResource(ResourceIdentifier id, LocationData location, TModel d
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The identifier of the resource that is the target of operations.
/// The location of the resource.
@@ -39,7 +41,7 @@ protected TrackedResource(string id, LocationData location, TModel data)
}
else
{
- Id = id;
+ Id = ResourceIdentifier.Create(id) as TIdentifier;
}
Location = location;
@@ -55,7 +57,7 @@ protected TrackedResource(string id, LocationData location, TModel data)
/// Converts from a into the TModel.
///
/// The tracked resource convert from.
- public static implicit operator TModel(TrackedResource other)
+ public static implicit operator TModel(TrackedResource other)
{
return other.Model;
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs
index 6660dbe67684..f58fd70e715f 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs
@@ -10,18 +10,20 @@ namespace Azure.ResourceManager.Core
///
/// A class representing a builder object used to create Azure resources.
///
+ /// The type of the Identifier class for a specific resource.
/// The type of the operations class for a specific resource.
/// The type of the class containing properties for the underlying resource.
- public class ArmBuilder
- where TResource : Resource
- where TOperations : ResourceOperationsBase
+ public class ArmBuilder
+ where TIdentifier: TenantResourceIdentifier
+ where TResource : Resource
+ where TOperations : ResourceOperationsBase
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The container object to create the resource in.
/// The resource to create.
- public ArmBuilder(ResourceContainerBase container, TResource resource)
+ public ArmBuilder(ResourceContainerBase container, TResource resource)
{
Resource = resource;
UnTypedContainer = container;
@@ -40,7 +42,7 @@ public ArmBuilder(ResourceContainerBase container, TReso
///
/// Gets the container object to create the resource in.
///
- protected ResourceContainerBase UnTypedContainer { get; private set; }
+ protected ResourceContainerBase UnTypedContainer { get; private set; }
///
/// Creates the resource object to send to the Azure API.
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs
index 845397384fc9..ac17d0a2cebc 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs
@@ -101,7 +101,7 @@ private AzureResourceManagerClient(
DefaultSubscription = string.IsNullOrWhiteSpace(defaultSubscriptionId)
? GetDefaultSubscription()
: GetSubscriptionOperations(defaultSubscriptionId).Get().Value;
- _clientOptions.ApiVersions.SetProviderClient(credential, baseUri, DefaultSubscription.Id.Subscription);
+ _clientOptions.ApiVersions.SetProviderClient(credential, baseUri, DefaultSubscription.Id.SubscriptionId);
}
///
@@ -145,9 +145,9 @@ public virtual ResourceGroupOperations GetResourceGroupOperations(string subscri
///
/// The resource identifier of the resource group.
/// Resource group operations.
- public virtual ResourceGroupOperations GetResourceGroupOperations(ResourceIdentifier resourceGroupId)
+ public virtual ResourceGroupOperations GetResourceGroupOperations(ResourceGroupResourceIdentifier resourceGroupId)
{
- return GetSubscriptionOperations(resourceGroupId.Subscription).GetResourceGroupOperations(resourceGroupId.ResourceGroup);
+ return GetSubscriptionOperations(resourceGroupId.SubscriptionId).GetResourceGroupOperations(resourceGroupId.ResourceGroupName);
}
///
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs
index 7195b18f3fda..229478888eb3 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs
@@ -13,30 +13,31 @@ namespace Azure.ResourceManager.Core
/// Base class representing collection of resources.
///
/// The type of the class containing operations for the underlying resource.
- public abstract class ContainerBase : OperationsBase
- where TOperations : ResourceOperationsBase
+ /// The type of the resource identifier.
+ public abstract class ContainerBase : OperationsBase
+ where TOperations : ResourceOperationsBase where TIdentifier : ResourceIdentifier
{
///
- /// Initializes a new instance of the class for mocking.
+ /// Initializes a new instance of the class for mocking.
///
protected ContainerBase()
{
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
/// A credential used to authenticate to an Azure Service.
/// The base URI of the service.
- protected ContainerBase(AzureResourceManagerClientOptions options, ResourceIdentifier id, TokenCredential credential, Uri baseUri)
+ protected ContainerBase(AzureResourceManagerClientOptions options, TIdentifier id, TokenCredential credential, Uri baseUri)
: base(options, id, credential, baseUri)
{
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The resource representing the parent resource.
protected ContainerBase(ResourceOperationsBase parent)
@@ -104,15 +105,15 @@ public virtual bool DoesExist(string resourceName)
/// Get an instance of the operations this container holds.
///
/// The name of the resource to scope the operations to.
- /// An instance of .
- protected virtual ResourceOperationsBase GetOperation(string resourceName)
+ /// An instance of .
+ protected virtual ResourceOperationsBase GetOperation(string resourceName)
{
return Activator.CreateInstance(
typeof(TOperations).BaseType,
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
null,
new object[] { Parent, resourceName },
- CultureInfo.InvariantCulture) as ResourceOperationsBase;
+ CultureInfo.InvariantCulture) as ResourceOperationsBase;
}
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs
index 84f62ecfee69..aa1a3d892df3 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs
@@ -9,7 +9,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the generic azure resource data model.
///
- public class GenericResourceData : TrackedResource
+ public class GenericResourceData : TrackedResource
{
///
/// Initializes a new instance of the class.
@@ -41,7 +41,7 @@ public GenericResourceData(ResourceManager.Resources.Models.GenericResource gene
/// Initializes a new instance of the class.
///
/// The identifier of the resource that is the target of operations.
- public GenericResourceData(ResourceIdentifier id)
+ public GenericResourceData(TenantResourceIdentifier id)
: base(id, LocationData.Default, null)
{
}
@@ -51,13 +51,13 @@ public GenericResourceData(ResourceIdentifier id)
///
/// The identifier of the resource that is the target of operations.
/// The location of the resource.
- public GenericResourceData(ResourceIdentifier id, LocationData location)
+ public GenericResourceData(TenantResourceIdentifier id, LocationData location)
: base(id, location, null)
{
}
///
- public override ResourceIdentifier Id { get; protected set; }
+ public override TenantResourceIdentifier Id { get; protected set; }
///
/// Gets or sets who this resource is managed by.
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs
index f99ef82f538e..185201af7588 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs
@@ -13,14 +13,14 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the operations that can be performed over a specific ArmResource.
///
- public class GenericResourceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
+ public class GenericResourceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
{
///
/// Initializes a new instance of the class.
///
/// The resource operations to copy the options from.
/// The identifier of the resource that is the target of operations.
- internal GenericResourceOperations(ResourceOperationsBase operations, ResourceIdentifier id)
+ internal GenericResourceOperations(ResourceOperationsBase operations, TenantResourceIdentifier id)
: base(operations, id)
{
}
@@ -28,11 +28,23 @@ internal GenericResourceOperations(ResourceOperationsBase operations, ResourceId
///
protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType;
- private ResourcesOperations Operations => new ResourcesManagementClient(
- BaseUri,
- Id.Subscription,
- Credential,
- ClientOptions.Convert()).Resources;
+ private ResourcesOperations Operations
+ {
+ get
+ {
+ string subscription;
+ if (!Id.TryGetSubscriptionId(out subscription))
+ {
+ subscription = Guid.Empty.ToString();
+ }
+
+ return new ResourcesManagementClient(
+ BaseUri,
+ subscription,
+ Credential,
+ ClientOptions.Convert()).Resources;
+ }
+ }
///
/// Delete the resource.
@@ -242,7 +254,7 @@ await op.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false),
private string GetApiVersion(CancellationToken cancellationToken)
{
- string version = ClientOptions.ApiVersions.TryGetApiVersion(Id.Type, cancellationToken);
+ string version = ClientOptions.ApiVersions.TryGetApiVersion(Id.ResourceType, cancellationToken);
if (version is null)
{
throw new InvalidOperationException($"An invalid resouce id was given {Id}");
@@ -251,7 +263,7 @@ private string GetApiVersion(CancellationToken cancellationToken)
}
private async Task GetApiVersionAsync(CancellationToken cancellationToken)
{
- string version = await ClientOptions.ApiVersions.TryGetApiVersionAsync(Id.Type, cancellationToken).ConfigureAwait(false);
+ string version = await ClientOptions.ApiVersions.TryGetApiVersionAsync(Id.ResourceType, cancellationToken).ConfigureAwait(false);
if (version is null)
{
throw new InvalidOperationException($"An invalid resouce id was given {Id}");
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs
index 812d8f072704..c33b18ada7af 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs
@@ -10,9 +10,11 @@ namespace Azure.ResourceManager.Core
///
/// Interface for operations that allow manipulating resource tags.
///
+ /// The identifier type for this resource.
/// The typed operations for a specific resource.
- public interface ITaggableResource
- where TOperations : ResourceOperationsBase
+ public interface ITaggableResource
+ where TOperations : ResourceOperationsBase
+ where TIdentifier : TenantResourceIdentifier
{
///
/// Add a tag to the resource.
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs
index 51dadf390af0..b8342b36b658 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs
@@ -68,11 +68,19 @@ protected OperationsBase(AzureResourceManagerClientOptions options, ResourceIden
///
/// Gets the resource client.
///
- protected ResourcesManagementClient ResourcesClient => new ResourcesManagementClient(
- BaseUri,
- Id.Subscription,
- Credential,
- ClientOptions.Convert());
+ protected ResourcesManagementClient ResourcesClient
+ {
+ get
+ {
+ string subscription;
+ if (!Id.TryGetSubscriptionId(out subscription))
+ {
+ subscription = Guid.Empty.ToString();
+ }
+
+ return new ResourcesManagementClient(BaseUri, subscription, Credential, ClientOptions.Convert());
+ }
+ }
///
/// Validate the resource identifier against current operations.
@@ -80,8 +88,8 @@ protected OperationsBase(AzureResourceManagerClientOptions options, ResourceIden
/// The resource identifier.
protected virtual void Validate(ResourceIdentifier identifier)
{
- if (identifier?.Type != ValidResourceType)
- throw new ArgumentException($"Invalid resource type {identifier?.Type} expected {ValidResourceType}");
+ if (identifier?.ResourceType != ValidResourceType)
+ throw new ArgumentException($"Invalid resource type {identifier?.ResourceType} expected {ValidResourceType}");
}
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs
index 175310efcb45..a653c6282620 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs
@@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the ResourceGroup data model.
///
- public class ResourceGroupData : TrackedResource
+ public class ResourceGroupData : TrackedResource
{
///
/// Initializes a new instance of the class.
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs
index be3b12feeb18..922bff84bc54 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs
@@ -9,7 +9,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the subscription data model.
///
- public class SubscriptionData : Resource
+ public class SubscriptionData : Resource
{
///
/// Initializes a new instance of the class.
@@ -23,7 +23,7 @@ public SubscriptionData(ResourceManager.Resources.Models.Subscription subscripti
State = subscription.State;
SubscriptionPolicies = subscription.SubscriptionPolicies;
AuthorizationSource = subscription.AuthorizationSource;
- Id = subscription.Id;
+ Id = new SubscriptionResourceIdentifier(subscription.Id);
ManagedByTenants = subscription.ManagedByTenants;
Tags = subscription.Tags;
}
@@ -59,7 +59,7 @@ public SubscriptionData(ResourceManager.Resources.Models.Subscription subscripti
public string AuthorizationSource { get; }
///
- public override ResourceIdentifier Id { get; protected set; }
+ public override SubscriptionResourceIdentifier Id { get; protected set; }
///
/// Gets an array containing the tenants managing the subscription.
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs
index ec896f0f26b4..62d0eefc945f 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs
@@ -10,24 +10,26 @@ namespace Azure.ResourceManager.Core
///
/// A class representing collection of resources and their operations over their parent.
///
+ /// The type of the resource identifier.
/// The type of the class containing operations for the underlying resource.
/// The type of the class containing properties for the underlying resource.
- public abstract class ResourceContainerBase : ContainerBase
- where TOperations : ResourceOperationsBase
- where TResource : Resource
+ public abstract class ResourceContainerBase : ContainerBase
+ where TOperations : ResourceOperationsBase
+ where TResource : Resource
+ where TIdentifier : TenantResourceIdentifier
{
private static readonly object _parentLock = new object();
private object _parentResource;
///
- /// Initializes a new instance of the class for mocking.
+ /// Initializes a new instance of the class for mocking.
///
protected ResourceContainerBase()
{
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The resource representing the parent resource.
protected ResourceContainerBase(ResourceOperationsBase parent)
@@ -42,8 +44,8 @@ protected ResourceContainerBase(ResourceOperationsBase parent)
/// Resource identifier is not a valid type for this container.
protected override void Validate(ResourceIdentifier identifier)
{
- if (identifier.Type != ValidResourceType)
- throw new InvalidOperationException($"{identifier.Type} is not a valid container for {Id.Type}");
+ if (identifier.ResourceType != ValidResourceType)
+ throw new InvalidOperationException($"{identifier.ResourceType} is not a valid container for {Id.ResourceType}");
}
///
@@ -112,11 +114,13 @@ public abstract Task> StartCreateOrUpdateAsync(
/// Gets the location of the parent object.
///
/// The type of the parents full resource object.
+ /// The type of the parents resource id.
/// The type of the parents operations object.
/// The associated with the parent object.
- protected TParent GetParentResource()
+ protected TParent GetParentResource()
where TParent : TParentOperations
- where TParentOperations : ResourceOperationsBase
+ where TParentOperations : ResourceOperationsBase
+ where TParentId : ResourceIdentifier
{
if (_parentResource is null)
{
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs
index 4f4441eb1bdb..5a88837c374b 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs
@@ -13,7 +13,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing collection of ResourceGroupContainer and their operations over a ResourceGroup.
///
- public class ResourceGroupContainer : ResourceContainerBase
+ public class ResourceGroupContainer : ResourceContainerBase
{
///
/// Initializes a new instance of the class for mocking.
@@ -34,11 +34,20 @@ internal ResourceGroupContainer(SubscriptionOperations subscription)
///
protected override ResourceType ValidResourceType => SubscriptionOperations.ResourceType;
- private ResourceGroupsOperations Operations => new ResourcesManagementClient(
- BaseUri,
- Id.Subscription,
- Credential,
- ClientOptions.Convert()).ResourceGroups;
+ private ResourceGroupsOperations Operations
+ {
+ get
+ {
+ string subscriptionId;
+ if (Id is null || !Id.TryGetSubscriptionId(out subscriptionId))
+ subscriptionId = Guid.NewGuid().ToString();
+ return new ResourcesManagementClient(
+ BaseUri,
+ subscriptionId,
+ Credential,
+ ClientOptions.Convert()).ResourceGroups;
+ }
+ }
///
/// Constructs an object used to create a resource group.
@@ -48,7 +57,7 @@ internal ResourceGroupContainer(SubscriptionOperations subscription)
/// Who the resource group is managed by.
/// A builder with and .
/// Location cannot be null.
- public ArmBuilder Construct(LocationData location, IDictionary tags = default, string managedBy = default)
+ public ArmBuilder Construct(LocationData location, IDictionary tags = default, string managedBy = default)
{
if (location is null)
throw new ArgumentNullException(nameof(location));
@@ -57,7 +66,7 @@ public ArmBuilder Construct(LocationData locat
if (!(tags is null))
model.Tags.ReplaceWith(tags);
model.ManagedBy = managedBy;
- return new ArmBuilder(this, new ResourceGroupData(model));
+ return new ArmBuilder(this, new ResourceGroupData(model));
}
///
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs
index d5057ad8fa90..bfad3556ff1e 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs
@@ -15,13 +15,13 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the operations that can be performed over a specific ResourceGroup.
///
- public class ResourceGroupOperations : ResourceOperationsBase,
- ITaggableResource, IDeletableResource
+ public class ResourceGroupOperations : ResourceOperationsBase,
+ ITaggableResource, IDeletableResource
{
///
/// Gets the resource type definition for a ResourceType.
///
- public static readonly ResourceType ResourceType = "Microsoft.Resources/resourceGroups";
+ public static readonly ResourceType ResourceType = "Microsoft.Resources/subscriptions/resourceGroups";
///
/// Initializes a new instance of the class for mocking.
@@ -36,7 +36,7 @@ protected ResourceGroupOperations()
/// The client parameters to use in these operations.
/// The name of the resource group to use.
internal ResourceGroupOperations(SubscriptionOperations options, string rgName)
- : base(options, $"{options.Id}/resourceGroups/{rgName}")
+ : base(options, new ResourceGroupResourceIdentifier(options.Id, rgName))
{
if (rgName.Length > 90)
throw new ArgumentOutOfRangeException(nameof(rgName), "ResourceGroupName cannot be longer than 90 characters.");
@@ -52,7 +52,7 @@ internal ResourceGroupOperations(SubscriptionOperations options, string rgName)
///
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
- protected ResourceGroupOperations(ResourceOperationsBase options, ResourceIdentifier id)
+ protected ResourceGroupOperations(ResourceOperationsBase options, ResourceGroupResourceIdentifier id)
: base(options, id)
{
}
@@ -62,7 +62,7 @@ protected ResourceGroupOperations(ResourceOperationsBase options, ResourceIdenti
private ResourceGroupsOperations Operations => new ResourcesManagementClient(
BaseUri,
- Id.Subscription,
+ Id.SubscriptionId,
Credential,
ClientOptions.Convert()).ResourceGroups;
@@ -316,21 +316,23 @@ await Operations.UpdateAsync(Id.Name, patch, cancellationToken).ConfigureAwait(f
/// The model representing the object to create. />.
/// The type of the class containing the container for the specific resource.
/// The type of the operations class for a specific resource.
+ /// The type of the resource identifier.
/// The type of the class containing properties for the underlying resource.
/// Returns a response with the operation for this resource.
/// Name cannot be null or a whitespace.
/// Model cannot be null.
- public virtual ArmResponse CreateResource(string name, TResource model)
- where TResource : TrackedResource
- where TOperations : ResourceOperationsBase
- where TContainer : ResourceContainerBase
+ public virtual ArmResponse CreateResource(string name, TResource model)
+ where TResource : TrackedResource
+ where TOperations : ResourceOperationsBase
+ where TContainer : ResourceContainerBase
+ where TIdentifier : SubscriptionResourceIdentifier
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException($"{nameof(name)} provided cannot be null or a whitespace.", nameof(name));
if (model is null)
throw new ArgumentNullException(nameof(model));
- var myResource = model as TrackedResource;
+ var myResource = model as TrackedResource;
TContainer container = Activator.CreateInstance(typeof(TContainer), ClientOptions, myResource) as TContainer;
return container.CreateOrUpdate(name, model);
@@ -343,22 +345,24 @@ public virtual ArmResponse CreateResource The model representing the object to create. />.
/// A token to allow the caller to cancel the call to the service. The default value is .
/// The type of the class containing the container for the specific resource.
- /// The type of the operations class for a specific resource.
+ /// The type of the operations class for a specific resource.
+ /// The type of the resource identifier.
/// The type of the class containing properties for the underlying resource.
/// A that on completion returns a response with the operation for this resource.
/// Name cannot be null or a whitespace.
/// Model cannot be null.
- public virtual Task> CreateResourceAsync(string name, TResource model, CancellationToken cancellationToken = default)
- where TResource : TrackedResource
- where TOperations : ResourceOperationsBase
- where TContainer : ResourceContainerBase
+ public virtual Task> CreateResourceAsync(string name, TResource model, CancellationToken cancellationToken = default)
+ where TResource : TrackedResource
+ where TOperations : ResourceOperationsBase
+ where TContainer : ResourceContainerBase
+ where TIdentifier : SubscriptionResourceIdentifier
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException($"{nameof(name)} provided cannot be null or a whitespace.", nameof(name));
if (model is null)
throw new ArgumentNullException(nameof(model));
- var myResource = model as TrackedResource;
+ var myResource = model as TrackedResource;
TContainer container = Activator.CreateInstance(typeof(TContainer), ClientOptions, myResource) as TContainer;
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs
index 469af5edd69b..8217e11ec8c1 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs
@@ -107,7 +107,8 @@ public static AsyncPageable ListAtContextAsync(
private static ResourcesManagementClient GetResourcesClient(ResourceOperationsBase resourceOperations)
{
- return new ResourcesManagementClient(resourceOperations.BaseUri, resourceOperations.Id.Subscription, resourceOperations.Credential);
+ var subscription = resourceOperations.Id as SubscriptionResourceIdentifier;
+ return new ResourcesManagementClient(resourceOperations.BaseUri, subscription?.SubscriptionId, resourceOperations.Credential);
}
private static AsyncPageable ListAtContextInternalAsync(
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs
index 429da52c7e4e..6f5cd988b505 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs
@@ -23,6 +23,15 @@ protected ResourceOperationsBase()
{
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The generic operations representing the resource
+ protected ResourceOperationsBase(GenericResourceOperations operations)
+ : base(operations.ClientOptions, operations.Id, operations.Credential, operations.BaseUri)
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -59,19 +68,20 @@ protected ResourceOperationsBase(AzureResourceManagerClientOptions options, Reso
/// Base class for all operations over a resource
///
/// The type implementing operations over the resource.
+ /// The The identifier type for the resource.
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Types differ by type argument only")]
- public abstract class ResourceOperationsBase : ResourceOperationsBase
- where TOperations : ResourceOperationsBase
+ public abstract class ResourceOperationsBase : ResourceOperationsBase
+ where TOperations : ResourceOperationsBase where TIdentifier : ResourceIdentifier
{
///
- /// Initializes a new instance of the class for mocking.
+ /// Initializes a new instance of the class for mocking.
///
protected ResourceOperationsBase()
{
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// Generic ARMResourceOperations for this resource type.
protected ResourceOperationsBase(GenericResourceOperations genericOperations)
@@ -80,7 +90,7 @@ protected ResourceOperationsBase(GenericResourceOperations genericOperations)
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The resource representing the parent resource.
/// The identifier of the resource that is the target of operations.
@@ -90,7 +100,7 @@ protected ResourceOperationsBase(ResourceOperationsBase parentOperations, Resour
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
@@ -101,6 +111,14 @@ protected ResourceOperationsBase(AzureResourceManagerClientOptions options, Reso
{
}
+ ///
+ /// The typed resource identifier for the underlying resource
+ ///
+ public virtual new TIdentifier Id
+ {
+ get { return base.Id as TIdentifier; }
+ }
+
///
/// Gets details for this resource from the service.
///
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs
index a87b0120127c..2b7133da62d5 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs
@@ -20,6 +20,7 @@ public class LocationContainer : OperationsBase
internal LocationContainer(SubscriptionOperations subscriptionOperations)
: base(subscriptionOperations.ClientOptions, subscriptionOperations.Id, subscriptionOperations.Credential, subscriptionOperations.BaseUri)
{
+ Id = subscriptionOperations.Id;
}
///
@@ -30,6 +31,11 @@ internal LocationContainer(SubscriptionOperations subscriptionOperations)
///
private SubscriptionsOperations SubscriptionsClient => ResourcesClient.Subscriptions;
+ ///
+ /// The resource id
+ ///
+ public new SubscriptionResourceIdentifier Id { get; }
+
///
/// Gets the Azure subscriptions.
///
@@ -45,7 +51,7 @@ public SubscriptionContainer GetSubscriptionContainer()
/// A collection of location data that may take multiple service requests to iterate over.
public Pageable List()
{
- return new PhWrappingPageable(SubscriptionsClient.ListLocations(Id.Subscription), s => s.DisplayName);
+ return new PhWrappingPageable(SubscriptionsClient.ListLocations(Id.SubscriptionId), s => s.DisplayName);
}
///
@@ -55,7 +61,7 @@ public Pageable List()
/// An async collection of location data that may take multiple service requests to iterate over.
public AsyncPageable ListAsync(CancellationToken token = default(CancellationToken))
{
- return new PhWrappingAsyncPageable(SubscriptionsClient.ListLocationsAsync(Id.Subscription, token), s => s.DisplayName);
+ return new PhWrappingAsyncPageable(SubscriptionsClient.ListLocationsAsync(Id.SubscriptionId, token), s => s.DisplayName);
}
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs
new file mode 100644
index 000000000000..900b34fe0163
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// The identifier for a resource that is contained in a location.
+ ///
+ public sealed class LocationResourceIdentifier : SubscriptionResourceIdentifier
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The identifier of the subscription that is the parent of this resource.
+ /// The name of the location.
+ internal LocationResourceIdentifier(SubscriptionResourceIdentifier parent, LocationData location)
+ : base(parent, ResourceIdentifier.LocationsKey, location.Name)
+ {
+ Location = location;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A string representation of a location resource identifier.
+ public LocationResourceIdentifier(string resourceId)
+ {
+ var id = ResourceIdentifier.Create(resourceId) as LocationResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid location level resource", nameof(resourceId));
+ Name = id.Name;
+ ResourceType = id.ResourceType;
+ Parent = id.Parent;
+ IsChild = id.IsChild;
+ Location = id.Location;
+ SubscriptionId = id.SubscriptionId;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Used to initialize resources in the same namespace as the parent resource.
+ ///
+ ///
+ ///
+ ///
+ internal LocationResourceIdentifier(LocationResourceIdentifier parent, string resourceType, string resourceName)
+ : base(parent, resourceType, resourceName)
+ {
+ Location = parent.Location;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Used to initialize resource in a different namespace than the parent resource.
+ ///
+ /// The identifier of the parent resource.
+ /// The namespace of the resource, for example 'Microsoft.Compute'.
+ /// The simple type name of the resource, for example 'virtualMachines'.
+ /// The name of this resource.
+ internal LocationResourceIdentifier(LocationResourceIdentifier target, string providerNamespace, string resourceType, string resourceName)
+ : base(target, providerNamespace, resourceType, resourceName)
+ {
+ Location = target.Location;
+ }
+
+ ///
+ /// The location of the resource.
+ ///
+ public LocationData Location { get; }
+
+ ///
+ public override bool TryGetLocation(out LocationData location)
+ {
+ location = Location;
+ return true;
+ }
+
+ ///
+ public override bool TryGetSubscriptionId(out string subscriptionId)
+ {
+ subscriptionId = SubscriptionId;
+ return true;
+ }
+
+ ///
+ /// Convert resourceId string to LocationResourceIdentifier.
+ ///
+ /// A string representation of a resource id.
+ public static implicit operator LocationResourceIdentifier(string other)
+ {
+ if (other is null)
+ return null;
+ LocationResourceIdentifier id = ResourceIdentifier.Create(other) as LocationResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid location level resource", nameof(other));
+ return id;
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs
index 961546c1cbef..81faffdf9533 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
@@ -9,13 +9,13 @@ namespace Azure.ResourceManager.Core
/// A class representing the base resource used by all azure resources.
///
[ReferenceType]
- public abstract class Resource : IEquatable, IEquatable, IComparable,
- IComparable
+ public abstract class Resource : IEquatable>, IEquatable,
+ IComparable>, IComparable where TIdentifier : TenantResourceIdentifier
{
///
/// Gets or sets the resource identifier.
///
- public virtual ResourceIdentifier Id { get; protected set; }
+ public virtual TIdentifier Id { get; protected set; }
///
/// Gets the name.
@@ -25,10 +25,10 @@ public abstract class Resource : IEquatable, IEquatable, IComp
///
/// Gets the resource type.
///
- public virtual ResourceType Type => Id?.Type;
+ public virtual ResourceType Type => Id?.ResourceType;
///
- public virtual int CompareTo(Resource other)
+ public virtual int CompareTo(Resource other)
{
if (other == null)
return 1;
@@ -48,11 +48,11 @@ public virtual int CompareTo(Resource other)
///
public virtual int CompareTo(string other)
{
- return string.Compare(Id?.Id, other, StringComparison.InvariantCultureIgnoreCase);
+ return string.Compare(Id, other, StringComparison.InvariantCultureIgnoreCase);
}
///
- public virtual bool Equals(Resource other)
+ public virtual bool Equals(Resource other)
{
if (Id == null)
return false;
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs
new file mode 100644
index 000000000000..6f223de9029a
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// The identifier for a resource contained in a resource group.
+ ///
+ public sealed class ResourceGroupResourceIdentifier : SubscriptionResourceIdentifier
+ {
+ ///
+ /// Initializes a new instance of the class for a resource group.
+ ///
+ /// The of the parent of this child resource.
+ /// The name of the resourceGroup.
+ internal ResourceGroupResourceIdentifier(SubscriptionResourceIdentifier parent, string resourceGroupName)
+ : base(parent, ResourceIdentifier.ResourceGroupsKey, resourceGroupName)
+ {
+ if (string.IsNullOrWhiteSpace(resourceGroupName))
+ throw new ArgumentOutOfRangeException(nameof(resourceGroupName), "Invalid resource group name.");
+ ResourceGroupName = resourceGroupName;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for a resource in a different namespace than its parent.
+ ///
+ /// he of the target of this extension resource.
+ /// The provider namespace of the extension.
+ /// The full ARM resource type of the extension.
+ /// The name of the extension resource.
+ internal ResourceGroupResourceIdentifier(ResourceGroupResourceIdentifier target, string providerNamespace, string resourceType, string resourceName)
+ : base(target, providerNamespace, resourceType, resourceName)
+ {
+ ResourceGroupName = target.ResourceGroupName;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for a resource in the same namespace as its parent.
+ ///
+ /// he of the target of this extension resource.
+ /// The full ARM resource type of the extension.
+ /// The name of the extension resource.
+ internal ResourceGroupResourceIdentifier(ResourceGroupResourceIdentifier target, string childResourceType, string childResourceName)
+ : base(target, childResourceType, childResourceName)
+ {
+ ResourceGroupName = target.ResourceGroupName;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// The string representation of a resource id.
+ public ResourceGroupResourceIdentifier(string resourceId)
+ {
+ var id = ResourceIdentifier.Create(resourceId) as ResourceGroupResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid tenant level resource", nameof(resourceId));
+ Name = id.Name;
+ ResourceType = id.ResourceType;
+ Parent = id.Parent;
+ IsChild = id.IsChild;
+ ResourceGroupName = id.ResourceGroupName;
+ SubscriptionId = id.SubscriptionId;
+ }
+
+ ///
+ /// The name of the resource group for this resource.
+ ///
+ public string ResourceGroupName { get; }
+
+ ///
+ public override bool TryGetResourceGroupName(out string resourceGroupName)
+ {
+ resourceGroupName = ResourceGroupName;
+ return true;
+ }
+
+ ///
+ /// Convert a string into a resource group resource identifier.
+ ///
+ /// The string representation of a resource Id.
+ public static implicit operator ResourceGroupResourceIdentifier(string other)
+ {
+ if (other is null)
+ return null;
+ ResourceGroupResourceIdentifier id = ResourceIdentifier.Create(other) as ResourceGroupResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid resource group level resource", nameof(other));
+ return id;
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs
index 71caa38ee72f..4c19a5cf59b0 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs
@@ -3,295 +3,448 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
+using System.Text;
namespace Azure.ResourceManager.Core
{
///
- /// Canonical Representation of a Resource Identity.
+ /// An Azure Resource Manager resource identifier.
///
- public sealed class ResourceIdentifier :
- IEquatable,
- IEquatable,
- IComparable,
- IComparable
+ public abstract class ResourceIdentifier : IEquatable, IComparable
{
- private readonly IDictionary _partsDictionary =
- new Dictionary(StringComparer.OrdinalIgnoreCase);
+ internal const string ProvidersKey = "providers", SubscriptionsKey = "subscriptions",
+ ResourceGroupsKey = "resourceGroups", LocationsKey = "locations";
+
+ internal const string ResourceGroupsLowerKey = "resourcegroups";
+
+ internal const string BuiltInResourceNamespace = "Microsoft.Resources";
+
+ internal static ResourceType SubscriptionType => new ResourceType(BuiltInResourceNamespace, SubscriptionsKey);
+ internal static ResourceType LocationsType =>
+ new ResourceType(BuiltInResourceNamespace, $"{SubscriptionsKey}/{LocationsKey}");
+ internal static ResourceType ResourceGroupsType =>
+ new ResourceType(BuiltInResourceNamespace, $"{SubscriptionsKey}/{ResourceGroupsKey}");
///
- /// Initializes a new instance of the class.
+ /// The root of the resource hierarchy
+ ///
+ public static ResourceIdentifier RootResourceIdentifier => new RootResourceIdentifier();
+
+ ///
+ /// For internal use only.
///
- /// The identifier of the resource that is the target of operations.
- public ResourceIdentifier(string id)
+ internal ResourceIdentifier()
{
- Id = id;
- Parse(id);
+ _stringValue = null;
}
///
- /// Gets the Resource ID.
+ /// For internal use only.
///
- public string Id { get; private set; }
+ /// The type of the resource.
+ /// The name of the resource.
+ internal ResourceIdentifier(ResourceType resourceType, string name)
+ {
+ ResourceType = resourceType;
+ Name = name;
+ _stringValue = null;
+ }
///
- /// Gets the Resource Name.
+ /// Initializes a new instance of the class.
///
- public string Name { get; private set; }
+ /// The string representation of a resource Id.
+ /// The resource identifier.
+ public static ResourceIdentifier Create(string resourceId)
+ {
+ if (resourceId is null)
+ throw new ArgumentNullException(nameof(resourceId));
+ if (!resourceId.StartsWith("/", StringComparison.InvariantCultureIgnoreCase))
+ throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id.");
+ var parts = resourceId.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
+ if (parts.Count < 2)
+ throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id.");
+ switch (parts[0].ToLowerInvariant())
+ {
+ case SubscriptionsKey:
+ {
+ ResourceIdentifier id = CreateBaseSubscriptionIdentifier(parts[1], parts.Trim(2));
+ id.StringValue = resourceId;
+ return id;
+ }
+ case ProvidersKey:
+ {
+ if (parts.Count > 3)
+ {
+ ResourceIdentifier id = CreateTenantIdentifier(new TenantResourceIdentifier(new ResourceType(parts[1], parts[2]), parts[3]), parts.Trim(4));
+ id.StringValue = resourceId;
+ return id;
+ }
+ throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id.");
+ }
+ default:
+ throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id.");
+ }
+ }
///
- /// Gets the Resource Type.
+ /// Create a new instance of the class for resource identifiers
+ /// that are contained in a subscription.
///
- public ResourceType Type { get; private set; }
+ /// The GUID string representing the resource.
+ /// The path segments in the resource id following the subscription Guid.
+ /// The resource identifier for the given resource path.
+ internal static ResourceIdentifier CreateBaseSubscriptionIdentifier(string subscriptionId, List parts)
+ {
+ Guid subscriptionGuid;
+ if (!Guid.TryParse(subscriptionId, out subscriptionGuid))
+ throw new ArgumentOutOfRangeException(nameof(subscriptionId), "Invalid subscription id.");
+ var subscription = new SubscriptionResourceIdentifier( subscriptionGuid);
+ if (parts.Count == 0)
+ return subscription;
+ if (parts.Count > 1)
+ {
+ switch (parts[0].ToLowerInvariant())
+ {
+ case LocationsKey:
+ return CreateBaseLocationIdentifier(subscription, parts[1], parts.Trim(2));
+ case ResourceGroupsLowerKey:
+ return CreateBaseResourceGroupIdentifier(subscription, parts[1], parts.Trim(2));
+ case ProvidersKey:
+ {
+ if (parts.Count > 3)
+ return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(subscription,
+ parts[1], parts[2], parts[3]), parts.Skip(4).ToList());
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource string");
+ }
+ default:
+ {
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
+ }
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
///
- /// Gets the Subscription.
+ /// Create a new instance of the class for resource identifiers
+ /// that are contained in a location.
///
- public string Subscription => _partsDictionary.ContainsKey(KnownKeys.Subscription)
- ? _partsDictionary[KnownKeys.Subscription]
- : null;
+ /// The resource id of the subscription for this resource.
+ /// The location of the resource.
+ /// The path segments in the resource id following the location.
+ /// The resource identifier for the given resource path.
+ internal static ResourceIdentifier CreateBaseLocationIdentifier(SubscriptionResourceIdentifier subscription, LocationData location, List parts)
+ {
+ var parent = new LocationResourceIdentifier(subscription, location);
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ switch (parts[0].ToLowerInvariant())
+ {
+ case ProvidersKey:
+ {
+ if (parts.Count > 3)
+ return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
+ default:
+ return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2));
+ }
+ }
///
- /// Gets the Resource Group.
+ /// Create a new instance of the class for resource identifiers
+ /// that are contained in a resource group.
///
- public string ResourceGroup => _partsDictionary.ContainsKey(KnownKeys.ResourceGroup)
- ? _partsDictionary[KnownKeys.ResourceGroup]
- : null;
+ /// The resource id of the subscription for this resource.
+ /// The resource group containing the resource.
+ /// The path segments in the resource id following the resource group name.
+ /// The resource identifier for the given resource path.
+ internal static ResourceIdentifier CreateBaseResourceGroupIdentifier(SubscriptionResourceIdentifier subscription, string resourceGroupName, List parts)
+ {
+ var parent = new ResourceGroupResourceIdentifier(subscription, resourceGroupName);
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ switch (parts[0].ToLowerInvariant())
+ {
+ case ProvidersKey:
+ {
+ if (parts.Count > 3)
+ return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
+ default:
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
+ }
///
- /// Gets the Parent.
- /// Currently this will contain the identifier for either the parent resource, the resource group, the location, the subscription, or the tenant that is the logical parent of this resource.
+ /// Create a new instance of the class for resource identifiers
+ /// that are based in the tenant.
///
- public ResourceIdentifier Parent { get; private set; }
+ /// The resource id of the parent resource.
+ /// The path segments in the resource path after the parent.
+ /// A resource identifier for a resource contained in the tenant.
+ internal static ResourceIdentifier CreateTenantIdentifier(TenantResourceIdentifier parent, List parts)
+ {
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ return new TenantResourceIdentifier(parent, parts[0], string.Empty);
+ if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateTenantIdentifier(new TenantResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateTenantIdentifier(new TenantResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
+ }
///
- /// Initializes a new instance of the class from a string.
+ /// Create a new instance of the class for resource identifiers
+ /// that are based in a subscription.
///
- /// String to be implicit converted into a object.
- public static implicit operator ResourceIdentifier(string other)
+ /// The resource id of the parent resource.
+ /// The path segments in the resource path after the parent.
+ /// A resource identifier for a resource contained in the subscription.
+ internal static ResourceIdentifier CreateSubscriptionIdentifier(SubscriptionResourceIdentifier parent, List parts)
{
- if (other is null)
- return null;
-
- return new ResourceIdentifier(other);
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ return new SubscriptionResourceIdentifier(parent, parts[0], string.Empty);
+ if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
}
///
- /// Creates a new string from a object.
+ /// Create a new instance of the class for resource identifiers
+ /// that are contained in a location.
///
- /// object to be implicit converted into an string.
- public static implicit operator string(ResourceIdentifier other)
+ /// The resource id of the parent resource.
+ /// The path segments in the resource path after the parent.
+ /// A resource identifier for a resource contained in a location.
+ internal static ResourceIdentifier CreateLocationIdentifier(LocationResourceIdentifier parent, List parts)
{
- if (other is null)
- return null;
-
- return other.Id;
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ return new LocationResourceIdentifier(parent, parts[0], string.Empty);
+ if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
}
///
- /// Allow static, safe comparisons of resource identifier strings or objects.
+ /// Create a new instance of the class for resource identifiers
+ /// that are contained in a resource group.
///
- /// A resource id.
- /// Another resource id.
- /// True if the resource ids are equivalent, otherwise False.
- public static bool Equals(ResourceIdentifier x, ResourceIdentifier y)
+ /// The resource id of the parent resource.
+ /// The path segments in the resource path after the parent.
+ /// A resource identifier for a resource contained in a resource group.
+ internal static ResourceIdentifier CreateResourceGroupIdentifier(ResourceGroupResourceIdentifier parent, List parts)
{
- if (null == x && null == y)
- return true;
-
- if (null == x || null == y)
- return false;
-
- return x.Equals(y);
+ if (parts.Count == 0)
+ return parent;
+ if (parts.Count == 1)
+ return new ResourceGroupResourceIdentifier(parent, parts[0], string.Empty);
+ if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4));
+ if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase))
+ return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2));
+ throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id.");
}
+ private object lockObject = new object();
+ private string _stringValue;
+
///
- /// Allow static null-safe comparisons between resource identifier strings or objects.
+ /// Cache the string representation of this resource, so traversal only needs to occur once.
///
- /// A resource id.
- /// Another resource id.
- /// -1 if x < y, 0 if x == y, 1 if x > y.
- public static int CompareTo(ResourceIdentifier x, ResourceIdentifier y)
+ internal string StringValue
{
- if (null == x && null == y)
- return 0;
+ get
+ {
+ lock (lockObject)
+ {
+ if (_stringValue is null)
+ {
+ _stringValue = ToResourceString();
+ }
+
+ return _stringValue;
+ }
+ }
- if (null == x)
- return -1;
+ set
+ {
+ lock (lockObject)
+ {
+ _stringValue = value;
+ }
+ }
+ }
- if (null == y)
- return 1;
+ ///
+ /// The resource type of the resource.
+ ///
+ public virtual ResourceType ResourceType { get; internal set; }
- return x.CompareTo(y);
- }
+ ///
+ /// The name of the resource.
+ ///
+ public virtual string Name { get; internal set; }
- ///
- public override int GetHashCode()
- {
- return Id.GetHashCode();
- }
+ ///
+ /// The immediate parent containing this resource.
+ ///
+ public virtual ResourceIdentifier Parent { get; internal set; }
- ///
- public override string ToString()
- {
- return Id;
- }
+ ///
+ /// Determines whether this resource is in the same namespace as its parent.
+ ///
+ internal virtual bool IsChild { get; set; }
///
- /// Compares this instance ID with another instance's ID.
+ /// Tries to get the resource identifier of the parent of this resource.
///
- /// object to compare.
- /// -1 for less than, 0 for equals, 1 for greater than.
- public int CompareTo(ResourceIdentifier other)
+ /// The resource id of the parent resource.
+ /// True if the resource has a parent, otherwise false.
+ public virtual bool TryGetParent(out ResourceIdentifier containerId)
{
- return string.Compare(
- Id?.ToLowerInvariant(),
- other?.Id?.ToLowerInvariant(),
- StringComparison.InvariantCultureIgnoreCase);
+ containerId = default(ResourceIdentifier);
+ if (this.Parent is RootResourceIdentifier)
+ return false;
+ containerId = this.Parent;
+ return true;
}
///
- /// Compares this instance ID with another plain text ID.
+ /// Tries to get the subscription associated with this resource.
///
- /// The ID to compare.
- /// -1 for less than, 0 for equals, 1 for greater than.
- public int CompareTo(string other)
+ /// The resource Id of the subscription for this resource.
+ /// True if the resource is contained in a subscription, otherwise false.
+ public virtual bool TryGetSubscriptionId(out string subscriptionId)
{
- return string.Compare(
- Id?.ToLowerInvariant(),
- other?.ToLowerInvariant(),
- StringComparison.InvariantCultureIgnoreCase);
+ subscriptionId = default(string);
+ return false;
}
///
- /// Compares this instance ID with another instance's ID and determines if they are equals.
+ /// Tries to get the resource group associated with this resource.
///
- /// object to compare.
- /// True if they are equals, otherwise false.
- public bool Equals(ResourceIdentifier other)
+ /// The resource group for this resource.
+ /// True if the resource is contained in a resource group, otherwise false.
+ public virtual bool TryGetResourceGroupName(out string resourceGroupName)
{
- return string.Equals(
- Id?.ToLowerInvariant(),
- other?.Id?.ToLowerInvariant(),
- StringComparison.InvariantCultureIgnoreCase);
+ resourceGroupName = default(string);
+ return false;
}
///
- /// Compares this instance ID with another plain text ID. and determines if they are equals.
+ /// Tries to get the location associated with this resource.
///
- /// The ID to compare.
- /// True if they are equals, otherwise false.
- public bool Equals(string other)
+ /// The location for thsi resource.
+ /// True if the resource is contained in a location, otherwise false.
+ public virtual bool TryGetLocation(out LocationData location)
{
- return string.Equals(
- Id?.ToLowerInvariant(),
- other?.ToLowerInvariant(),
- StringComparison.InvariantCultureIgnoreCase);
+ location = default(LocationData);
+ return false;
}
///
- /// Populate Resource Identity fields from input string.
+ /// Create the resource id string based on the resource id string of the parent resource.
///
- /// A properly formed resource identity.
- private void Parse(string id)
+ /// The string representation of this resource id.
+ internal virtual string ToResourceString()
{
- // Throw for null, empty, and string without the correct form
- if (string.IsNullOrWhiteSpace(id) || !id.Contains('/'))
- throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource");
-
- // Resource ID paths consist mainly of name/value pairs. Split the uri so we have an array of name/value pairs
- var parts = id.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
- // There must be at least one name/value pair for the resource id to be valid
- if (parts.Count < 2 && !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase))
- throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource");
-
- // This is asserting that resources must start with '/subscriptions', /tenants, or /locations.
- // TODO: we will need to update this code to accomodate tenant based resources (which start with /providers)
- if (!KnownKeys.Subscription.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) &&
- !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) &&
- !KnownKeys.ProviderNamespace.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) &&
- !KnownKeys.Location.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase))
+ StringBuilder builder = new StringBuilder(Parent.ToResourceString());
+ if (IsChild)
{
- throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource");
+ builder.Append($"/{ResourceType.Types.Last()}");
+ if (!string.IsNullOrWhiteSpace(Name))
+ builder.Append($"/{Name}");
}
-
- Type = new ResourceType(id);
-
- // In the case that this resource is a singleton proxy resource, the number of parts will be odd,
- // where the last part is the type name of the singleton
- if (parts.Count % 2 != 0 && !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase))
+ else
{
- _partsDictionary.Add(KnownKeys.UntrackedSubResource, parts.Last());
- parts.RemoveAt(parts.Count - 1);
+ builder.Append($"/providers/{ResourceType.Namespace}/{ResourceType.Type}/{Name}");
}
- // This spplits into resource that come from a provider (which have the providers keyword) and
- // resources that are built in to ARM (e.g. /subscriptions/{sub}, /subscriptions/{sub}/resourceGroups/{rg})
- // TODO: This code will need to be updates for extension resources, which have two providers
- if (id.ToLowerInvariant().Contains("providers"))
- {
- ParseProviderResource(parts);
- }
- else if (!KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase))
- {
- ParseGenericResource(parts);
- }
+ return builder.ToString();
}
///
- /// Helper method to parse a built in resource.
+ /// Return the string representation of the resource identifier.
///
- /// Resource ID paths consisting of name/value pairs.
- private void ParseGenericResource(IList parts)
+ /// The string representation of this resource identifier.
+ public override string ToString()
{
- Debug.Assert(parts != null, "Parts parameter is null.");
- Debug.Assert(parts.Count > 1, "Parts should be a list containing more than 1 elements.");
-
- // The resource consists of well-known name-value pairs. Make a resource dictionary
- // using the names as keys, and the values as values
- for (var i = 0; i < parts.Count - 1; i += 2)
- {
- _partsDictionary.Add(parts[i], parts[i + 1]);
- }
-
- // resource name is always the last part
- Name = parts.Last();
- parts.RemoveAt(parts.Count - 1);
- parts.RemoveAt(parts.Count - 1);
+ return StringValue;
+ }
- // remove the last key/value pair to arrive at the parent (Count will be zero for /subscriptions/{foo})
- Parent = parts.Count > 1 ? new ResourceIdentifier($"/{string.Join("/", parts)}") : null;
+ ///
+ /// Determine if this resource identifier is equivalent to the given resource identifier.
+ ///
+ /// The resource identifier to compare to.
+ /// True if the resource identifiers are equivalent, otherwise false.
+ public bool Equals(ResourceIdentifier other)
+ {
+ if (other is null)
+ return false;
+ return string.Equals(this.ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
///
- /// Helper method to parse a resource that comes from a provider.
+ /// Compre this resource identifier to the given resource identifier.
///
- /// Resource ID paths consisting of name/value pairs.
- private void ParseProviderResource(IList parts)
+ /// The resource identifier to compare to.
+ /// 0 if the resource identifiers are equivalent, -1 if this resource identifier
+ /// should be ordered before the given resource identifier, 1 if this resource identifier
+ /// should be ordered after the given resource identifier.
+ public int CompareTo(ResourceIdentifier other)
{
- // The resource consists of name/value pairs, make a dictionary out of it
- for (var i = 0; i < parts.Count - 1; i += 2)
- {
- _partsDictionary[parts[i]] = parts[i + 1];
- }
+ if (other is null)
+ return 1;
+ return string.Compare(this.ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase);
+ }
- Name = parts.Last();
- parts.RemoveAt(parts.Count - 1);
+ ///
+ public override bool Equals(object obj)
+ {
+ ResourceIdentifier resourceObj = obj as ResourceIdentifier;
+ if (!(resourceObj is null))
+ return resourceObj.Equals(this);
+ string stringObj = obj as string;
+ if (!(stringObj is null))
+ return this.Equals(ResourceIdentifier.Create(stringObj));
+ return false;
+ }
- // remove the type name (there will be no typename if this is a singleton sub resource)
- if (parts.Count % 2 == 1)
- parts.RemoveAt(parts.Count - 1);
+ ///
+ public override int GetHashCode()
+ {
+ return ToString().GetHashCode();
+ }
- // If this is a top-level resource, remove the providers/Namespace pair, otherwise continue
- if (parts.Count > 2 && string.Equals(parts[parts.Count - 2], KnownKeys.ProviderNamespace))
- {
- parts.RemoveAt(parts.Count - 1);
- parts.RemoveAt(parts.Count - 1);
- }
+ ///
+ /// Convert a string into a resource identifier.
+ ///
+ /// The string representation of a resource identifier.
+ public static implicit operator ResourceIdentifier(string other) => (other is null ? null : ResourceIdentifier.Create(other));
- // If this is not a top-level resource, it will have a parent
- Parent = parts.Count > 1 ? new ResourceIdentifier($"/{string.Join("/", parts)}") : null;
- }
+ ///
+ /// Convert a resource identifier to a string
+ ///
+ /// The resource identifier.
+ public static implicit operator string(ResourceIdentifier id) => id?.ToString();
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs
new file mode 100644
index 000000000000..ef5af2d1a6a7
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs
@@ -0,0 +1,160 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// Extensions over ResourceIdentifier types.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class ResourceIdentifierExtensions
+ {
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The provider namespace of the added resource.
+ /// The simple type of the added resource, without slashes (/),
+ /// for example, 'virtualMachines'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static TenantResourceIdentifier AppendProviderResource(this TenantResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName)
+ {
+ ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName);
+ return new TenantResourceIdentifier(identifier, providerNamespace, resourceType, resourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The provider namespace of the added resource.
+ /// The simple type of the added resource, without slashes (/),
+ /// for example, 'virtualMachines'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static SubscriptionResourceIdentifier AppendProviderResource(this SubscriptionResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName)
+ {
+ ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName);
+ return new SubscriptionResourceIdentifier(identifier, providerNamespace, resourceType, resourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The provider namespace of the added resource.
+ /// The simple type of the added resource, without slashes (/),
+ /// for example, 'virtualMachines'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static ResourceGroupResourceIdentifier AppendProviderResource(this ResourceGroupResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName)
+ {
+ ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName);
+ return new ResourceGroupResourceIdentifier(identifier, providerNamespace, resourceType, resourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The provider namespace of the added resource.
+ /// The simple type of the added resource, without slashes (/),
+ /// for example, 'virtualMachines'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static LocationResourceIdentifier AppendProviderResource(this LocationResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName)
+ {
+ ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName);
+ return new LocationResourceIdentifier(identifier, providerNamespace, resourceType, resourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The simple type of the child resource, without slashes (/),
+ /// for example, 'subnets'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static TenantResourceIdentifier AppendChildResource(this TenantResourceIdentifier identifier, string childResourceType, string childResourceName)
+ {
+ ValidateChildResourceParameters( childResourceType, childResourceName);
+ return new TenantResourceIdentifier(identifier, childResourceType, childResourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The simple type of the child resource, without slashes (/),
+ /// for example, 'subnets'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static SubscriptionResourceIdentifier AppendChildResource(this SubscriptionResourceIdentifier identifier, string childResourceType, string childResourceName)
+ {
+ ValidateChildResourceParameters(childResourceType, childResourceName);
+ return new SubscriptionResourceIdentifier(identifier, childResourceType, childResourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The simple type of the child resource, without slashes (/),
+ /// for example, 'subnets'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static ResourceGroupResourceIdentifier AppendChildResource(this ResourceGroupResourceIdentifier identifier, string childResourceType, string childResourceName)
+ {
+ ValidateChildResourceParameters(childResourceType, childResourceName);
+ return new ResourceGroupResourceIdentifier(identifier, childResourceType, childResourceName);
+ }
+
+ ///
+ /// Add a provider resource to an existing resource id.
+ ///
+ /// The id to append to.
+ /// The simple type of the child resource, without slashes (/),
+ /// for example, 'subnets'.
+ /// The name of the resource.
+ /// The combined resource id.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static LocationResourceIdentifier AppendChildResource(this LocationResourceIdentifier identifier, string childResourceType, string childResourceName)
+ {
+ ValidateChildResourceParameters(childResourceType, childResourceName);
+ return new LocationResourceIdentifier(identifier, childResourceType, childResourceName);
+ }
+
+ internal static void ValidateProviderResourceParameters(string providerNamespace, string resourceType, string resourceName)
+ {
+ ValidatePathSegment(providerNamespace, nameof(providerNamespace));
+ ValidatePathSegment(resourceType, nameof(resourceType));
+ ValidatePathSegment(resourceName, nameof(resourceName));
+ }
+
+ internal static void ValidateChildResourceParameters(string childResourceType, string childResourceName)
+ {
+ ValidatePathSegment(childResourceType, nameof(childResourceType));
+ ValidatePathSegment(childResourceName, nameof(childResourceName));
+ }
+
+ internal static void ValidatePathSegment(string segment, string parameterName)
+ {
+ if (string.IsNullOrWhiteSpace(segment))
+ throw new ArgumentNullException(parameterName);
+ if (segment.Contains("/"))
+ throw new ArgumentOutOfRangeException(parameterName, $"{parameterName} must be a single path segment");
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs
index ecba2a9905c8..9102f5db7b4d 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs
@@ -30,14 +30,14 @@ public ResourceIdentity()
///
/// Dictionary with a key and a object value.
/// Flag for using or not.
- public ResourceIdentity(Dictionary user, bool useSystemAssigned)
+ public ResourceIdentity(Dictionary user, bool useSystemAssigned)
{
// check for combination of user and system on the impact to type value
SystemAssignedIdentity = useSystemAssigned ? new SystemAssignedIdentity() : null;
- UserAssignedIdentities = new Dictionary();
+ UserAssignedIdentities = new Dictionary();
if (user != null)
{
- foreach (KeyValuePair id in user)
+ foreach (KeyValuePair id in user)
{
UserAssignedIdentities.Add(id.Key, id.Value);
}
@@ -49,13 +49,13 @@ public ResourceIdentity(Dictionary use
///
/// The to use.
/// Dictionary with a key and a object value.
- public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary user)
+ public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary user)
{
// TODO: remove this constructor later
SystemAssignedIdentity = systemAssigned;
if (user == null)
{
- UserAssignedIdentities = new Dictionary();
+ UserAssignedIdentities = new Dictionary();
}
else
{
@@ -71,7 +71,7 @@ public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary
/// Gets a dictionary of the User Assigned Identities.
///
- public IDictionary UserAssignedIdentities { get; private set; }
+ public IDictionary UserAssignedIdentities { get; private set; }
///
/// Converts a into an object.
@@ -86,7 +86,7 @@ internal static ResourceIdentity Deserialize(JsonElement element)
}
Optional systemAssignedIdentity = default;
- IDictionary userAssignedIdentities = new Dictionary();
+ IDictionary userAssignedIdentities = new Dictionary();
string type = string.Empty;
foreach (var property in element.EnumerateObject())
{
@@ -103,7 +103,7 @@ internal static ResourceIdentity Deserialize(JsonElement element)
{
resourceId = keyValuePair.Name;
var userAssignedIdentity = UserAssignedIdentity.Deserialize(keyValuePair.Value);
- userAssignedIdentities.Add(resourceId, userAssignedIdentity);
+ userAssignedIdentities.Add(new ResourceGroupResourceIdentifier(resourceId), userAssignedIdentity);
}
continue;
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs
index 62b71bc4907b..c48d43adf896 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs
@@ -8,15 +8,14 @@
namespace Azure.ResourceManager.Core
{
///
- /// Structure representing a resource type
+ /// Structure representing a resource type.
///
- public sealed class ResourceType : IEquatable, IEquatable, IComparable,
- IComparable
+ public sealed class ResourceType : IEquatable, IComparable
{
///
- /// The "none" resource type
+ /// The resource type for the root of the resource hierarchy.
///
- public static readonly ResourceType None = new ResourceType { Namespace = string.Empty, Type = string.Empty };
+ public static ResourceType RootResourceType => new ResourceType(string.Empty, string.Empty);
///
/// Initializes a new instance of the class.
@@ -28,6 +27,29 @@ public ResourceType(string resourceIdOrType)
throw new ArgumentException($"{nameof(resourceIdOrType)} cannot be null or whitespace", nameof(resourceIdOrType));
Parse(resourceIdOrType);
+ Types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ ///
+ /// Create a resource type given the namespace and typename components.
+ ///
+ ///
+ ///
+ internal ResourceType(string providerNamespace, string name)
+ {
+ Namespace = providerNamespace;
+ Type = name;
+ Types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ ///
+ /// Create child resource type using parent resource type
+ ///
+ ///
+ ///
+ internal ResourceType(ResourceType parent, string childType)
+ : this(parent.Namespace, $"{parent.Type}/{childType}")
+ {
}
private ResourceType()
@@ -44,23 +66,28 @@ private ResourceType()
///
public string Type { get; private set; }
+ internal IList Types { get; } = new List();
+
///
- /// Gets the resource type Parent.
+ /// Determines if this resource type is the parent of the given resource.
///
- public ResourceType Parent
+ ///
+ ///
+ public bool IsParentOf(ResourceType child)
{
- get
+ if (!string.Equals(Namespace, child.Namespace, StringComparison.InvariantCultureIgnoreCase))
+ return false;
+ var types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ var childTypes = child.Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ if (types.Length >= childTypes.Length)
+ return false;
+ for (int i = 0; i < types.Length; ++i)
{
- var parts = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
-
- if (parts.Length < 2)
- return None;
-
- var list = new List(parts);
- list.RemoveAt(list.Count - 1);
-
- return new ResourceType($"{Namespace}/{string.Join("/", list.ToArray())}");
+ if (!string.Equals(types[i], childTypes[i], StringComparison.InvariantCultureIgnoreCase))
+ return false;
}
+
+ return true;
}
///
@@ -75,46 +102,6 @@ public static implicit operator ResourceType(string other)
return new ResourceType(other);
}
- ///
- /// Implicit operator for initializing a string instance from a ResourceType.
- ///
- /// to be converted into a string object.
- public static implicit operator string(ResourceType other)
- {
- if (other is null)
- return null;
-
- return other.ToString();
- }
-
- ///
- /// Compares a object with a .
- ///
- /// object.
- /// String.
- /// True if they are equal, otherwise False.
- public static bool operator ==(ResourceType source, string target)
- {
- if (source is null)
- return target is null;
-
- return source.Equals(target);
- }
-
- ///
- /// Compares a with a object.
- ///
- /// String representation of a ResourceType.
- /// object.
- /// True if they are equal, otherwise False.
- public static bool operator ==(string source, ResourceType target)
- {
- if (target is null)
- return source is null;
-
- return target.Equals(source);
- }
-
///
/// Compares two objects.
///
@@ -129,34 +116,6 @@ public static implicit operator string(ResourceType other)
return source.Equals(target);
}
- ///
- /// Compares a object with a .
- ///
- /// object.
- /// String representation of a ResourceType.
- /// False if they are equal, otherwise True.
- public static bool operator !=(ResourceType source, string target)
- {
- if (source is null)
- return !(target is null);
-
- return !source.Equals(target);
- }
-
- ///
- /// Compares a with a object.
- ///
- /// String.
- /// object.
- /// False if they are equal, otherwise True.
- public static bool operator !=(string source, ResourceType target)
- {
- if (target is null)
- return !(source is null);
-
- return !target.Equals(source);
- }
-
///
/// Compares two objects.
///
@@ -184,30 +143,15 @@ public int CompareTo(ResourceType other)
if (ReferenceEquals(this, other))
return 0;
- int compareResult = 0;
- if ((compareResult = string.Compare(Namespace, other.Namespace, StringComparison.InvariantCultureIgnoreCase)) == 0 &&
- (compareResult = string.Compare(Type, other.Type, StringComparison.InvariantCultureIgnoreCase)) == 0 &&
- (!(other.Parent is null)))
+ int compareResult = string.Compare(Namespace, other.Namespace, StringComparison.InvariantCultureIgnoreCase);
+ if (compareResult == 0)
{
- return Parent.CompareTo(other.Parent);
+ compareResult = string.Compare(Type, other.Type, StringComparison.InvariantCultureIgnoreCase);
}
-
+
return compareResult;
}
- ///
- /// Compares this with a resource type representation as a string.
- ///
- /// String to compare.
- /// -1 for less than, 0 for equals, 1 for greater than.
- public int CompareTo(string other)
- {
- if (other is null)
- return 1;
-
- return CompareTo(new ResourceType(other));
- }
-
///
/// Compares this instance with another object and determines if they are equals.
///
@@ -221,19 +165,6 @@ public bool Equals(ResourceType other)
return string.Equals(ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
- ///
- /// Compares this instance with a string and determines if they are equals.
- ///
- /// String to compare.
- /// True if they are equals, otherwise false.
- public bool Equals(string other)
- {
- if (other is null)
- return false;
-
- return string.Equals(ToString(), other, StringComparison.InvariantCultureIgnoreCase);
- }
-
///
public override string ToString()
{
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs
new file mode 100644
index 000000000000..1d5d412c6a88
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// A resource Id representing the root of the resource hierarchy.
+ ///
+ public sealed class RootResourceIdentifier : ResourceIdentifier
+ {
+ internal RootResourceIdentifier()
+ : base(ResourceType.RootResourceType, string.Empty)
+ {
+ }
+
+ internal override string ToResourceString()
+ {
+ return string.Empty;
+ }
+
+ ///
+ public override bool TryGetParent(out ResourceIdentifier containerId)
+ {
+ containerId = default(ResourceIdentifier);
+ return false;
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs
new file mode 100644
index 000000000000..9ea234562109
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs
@@ -0,0 +1,125 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// The identifier of a resource that is contained in a subscription.
+ ///
+ public class SubscriptionResourceIdentifier : TenantResourceIdentifier
+ {
+ ///
+ /// Internal use only.
+ ///
+ internal SubscriptionResourceIdentifier()
+ {
+ }
+
+ ///
+ /// Internal use only.
+ ///
+ /// The subscription GUID.
+ internal SubscriptionResourceIdentifier(Guid id)
+ {
+ Name = id.ToString();
+ ResourceType = ResourceIdentifier.SubscriptionType;
+ Parent = ResourceIdentifier.RootResourceIdentifier;
+ IsChild = false;
+ SubscriptionId = Name;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for resources in the sanem namespace as their parent resource.
+ ///
+ /// The resource id of the parent resource.
+ /// The simple type of this resource, for example 'subnets'.
+ /// The name of this resource.
+ /// The resource identifier for the given child resource.
+ internal SubscriptionResourceIdentifier(SubscriptionResourceIdentifier parent, string childResourceType, string childResourceName)
+ : base(parent, childResourceType, childResourceName)
+ {
+ SubscriptionId = parent.SubscriptionId;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for resources in a different namespace than their parent resource.
+ ///
+ /// The resource id of the parent resource.
+ /// The namespace of this resource, for example 'Microsoft.Compute'.
+ /// The simple tyoe of this resource, with no slashes. For example, 'virtualMachines'.
+ /// Thge name of this resource.
+ /// The resource identifier for the given resource.
+ internal SubscriptionResourceIdentifier(SubscriptionResourceIdentifier parent, string providerNamespace, string resourceType, string resourceName)
+ : base(parent, providerNamespace, resourceType, resourceName)
+ {
+ SubscriptionId = parent.SubscriptionId;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The string representation of the subscription id. This can be in the form of a GUID,
+ /// or a full resource id like '/subscriptions/xxxxx-yyyy-zzzz-wwwwww'.
+ public SubscriptionResourceIdentifier(string resourceIdOrSubscriptionId)
+ {
+ Guid subscriptionGuid;
+ if (Guid.TryParse(resourceIdOrSubscriptionId, out subscriptionGuid))
+ {
+ Name = resourceIdOrSubscriptionId;
+ ResourceType = ResourceIdentifier.SubscriptionType;
+ Parent = ResourceIdentifier.RootResourceIdentifier;
+ IsChild = false;
+ SubscriptionId = resourceIdOrSubscriptionId;
+ }
+ else
+ {
+ ResourceIdentifier rawId = ResourceIdentifier.Create(resourceIdOrSubscriptionId);
+ SubscriptionResourceIdentifier id = rawId as SubscriptionResourceIdentifier;
+ if (id is null || rawId.TryGetLocation(out _) || rawId.TryGetResourceGroupName(out _))
+ throw new ArgumentException("Not a valid subscription level resource", nameof(resourceIdOrSubscriptionId));
+ Name = id.Name;
+ ResourceType = id.ResourceType;
+ Parent = id.Parent;
+ IsChild = id.IsChild;
+ SubscriptionId = id.SubscriptionId;
+ }
+ }
+
+ ///
+ /// The subscription id (Guid) for this resource.
+ ///
+ public string SubscriptionId { get; internal set; }
+
+ ///
+ public override bool TryGetSubscriptionId(out string subscriptionId)
+ {
+ subscriptionId = SubscriptionId;
+ return true;
+ }
+
+ ///
+ /// Convert a string resource id into a subscription resource identifier.
+ ///
+ /// The string representation of a resource identifier.
+ public static implicit operator SubscriptionResourceIdentifier(string other)
+ {
+ if (other is null)
+ return null;
+ SubscriptionResourceIdentifier id = ResourceIdentifier.Create(other) as SubscriptionResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid subscription level resource", nameof(other));
+ return id;
+ }
+
+ internal override string ToResourceString()
+ {
+ if (Parent is RootResourceIdentifier)
+ return $"/subscriptions/{SubscriptionId}";
+ return base.ToResourceString();
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs
new file mode 100644
index 000000000000..0743da2cf2d5
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs
@@ -0,0 +1,86 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Linq;
+
+namespace Azure.ResourceManager.Core
+{
+ ///
+ /// The identifier of any resource
+ ///
+ public class TenantResourceIdentifier : ResourceIdentifier
+ {
+ internal TenantResourceIdentifier()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// The resource type (including namespace and type).
+ /// The name of the resource.
+ internal TenantResourceIdentifier(ResourceType resourceType, string name) : base(resourceType, name)
+ {
+ Parent = ResourceIdentifier.RootResourceIdentifier;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for resources in the same namespace as their parent.
+ ///
+ /// The parent resource id.
+ /// The simple type name of the resource without slashes (/), for example 'virtualMachines'.
+ /// The name of the resource.
+ internal TenantResourceIdentifier(TenantResourceIdentifier parent, string typeName, string resourceName)
+ : base(new ResourceType(parent.ResourceType, typeName), resourceName)
+ {
+ Parent = parent;
+ IsChild = true;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// for resources in a different namespace than their parent.
+ ///
+ /// The parent resource id.
+ /// The namespace of the resource type, for example, 'Microsoft.Compute'.
+ /// The simple type name of the resource, without slashes (/). For example, 'virtualMachines'.
+ /// The name of the resource.
+ internal TenantResourceIdentifier(TenantResourceIdentifier parent, string providerNamespace, string typeName, string resourceName)
+ : base(new ResourceType(providerNamespace, typeName), resourceName)
+ {
+ Parent = parent;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The string representation of a resource identifier.
+ public TenantResourceIdentifier(string resourceId)
+ {
+ var rawId = ResourceIdentifier.Create(resourceId);
+ TenantResourceIdentifier id = rawId as TenantResourceIdentifier;
+ if (id is null || rawId.TryGetSubscriptionId(out _))
+ throw new ArgumentException("Not a valid tenant level resource", nameof(resourceId));
+ Name = id.Name;
+ ResourceType = id.ResourceType;
+ Parent = id.Parent;
+ IsChild = id.IsChild;
+ }
+
+ ///
+ /// Convert a string resource identifier into a TenantResourceIdentifier.
+ ///
+ /// The string representation of a subscription resource identifier.
+ public static implicit operator TenantResourceIdentifier(string other)
+ {
+ if (other is null)
+ return null;
+ TenantResourceIdentifier id = ResourceIdentifier.Create(other) as TenantResourceIdentifier;
+ if (id is null)
+ throw new ArgumentException("Not a valid tenant level resource", nameof(other));
+ return id;
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs
index a8639060c3bf..af6de769670b 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs
@@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core
/// Generic representation of a tracked resource. All tracked resources should extend this class
///
[ReferenceType]
- public abstract class TrackedResource : Resource
+ public abstract class TrackedResource : Resource where TIdentifier : TenantResourceIdentifier
{
///
/// Gets the tags.
@@ -26,6 +26,6 @@ public abstract class TrackedResource : Resource
///
/// Gets or sets the identifier for the resource.
///
- public override ResourceIdentifier Id { get; protected set; }
+ public override TIdentifier Id { get; protected set; }
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs
index 388fdfa3a4a8..161526d14919 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs
@@ -12,7 +12,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing collection of Subscription and their operations
///
- public class SubscriptionContainer : ContainerBase
+ public class SubscriptionContainer : ContainerBase
{
///
/// Initializes a new instance of the class.
@@ -79,8 +79,8 @@ protected override void Validate(ResourceIdentifier identifier)
/// Get an instance of the operations this container holds.
///
/// The guid of the subscription to be found.
- /// An instance of .
- protected override ResourceOperationsBase GetOperation(string subscriptionGuid)
+ /// An instance of .
+ protected override ResourceOperationsBase GetOperation(string subscriptionGuid)
{
return new SubscriptionOperations(ClientOptions, subscriptionGuid, Credential, BaseUri);
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs
index e9dd7bfb220d..bfba8c412628 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs
@@ -12,7 +12,7 @@ namespace Azure.ResourceManager.Core
///
/// A class representing the operations that can be performed over a specific subscription.
///
- public class SubscriptionOperations : ResourceOperationsBase
+ public class SubscriptionOperations : ResourceOperationsBase
{
///
/// The resource type for subscription
@@ -34,7 +34,7 @@ protected SubscriptionOperations()
/// A credential used to authenticate to an Azure Service.
/// The base URI of the service.
internal SubscriptionOperations(AzureResourceManagerClientOptions options, string subscriptionId, TokenCredential credential, Uri baseUri)
- : base(options, $"/subscriptions/{subscriptionId}", credential, baseUri)
+ : base(options, new SubscriptionResourceIdentifier(subscriptionId), credential, baseUri)
{
}
@@ -43,7 +43,7 @@ internal SubscriptionOperations(AzureResourceManagerClientOptions options, strin
///
/// The subscription operations to copy client options from.
/// The identifier of the subscription.
- protected SubscriptionOperations(SubscriptionOperations subscription, ResourceIdentifier id)
+ protected SubscriptionOperations(SubscriptionOperations subscription, SubscriptionResourceIdentifier id)
: base(subscription.ClientOptions, id, subscription.Credential, subscription.BaseUri)
{
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs
index 556ef04683bf..fa108fa44a13 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs
@@ -18,7 +18,7 @@ public class TenantOperations : OperationsBase
///
/// The resource type for subscription
///
- public static readonly ResourceType ResourceType = "/tenants"; // placeholder pending on the outcome of ADO #5199
+ public static readonly ResourceType ResourceType = ResourceType.RootResourceType;
///
/// Initializes a new instance of the class.
@@ -27,7 +27,7 @@ public class TenantOperations : OperationsBase
/// A credential used to authenticate to an Azure Service.
/// The base URI of the service.
internal TenantOperations(AzureResourceManagerClientOptions options, TokenCredential credential, Uri baseUri)
- : base(options, "/tenants", credential, baseUri)
+ : base(options, ResourceIdentifier.RootResourceIdentifier, credential, baseUri)
{
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs
new file mode 100644
index 000000000000..83a474b67d38
--- /dev/null
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Azure.ResourceManager.Core
+{
+ internal static class ListExtensions
+ {
+ ///
+ /// Trims the first n elements from a list, and returns the altered list.
+ ///
+ /// The type of element in the list.
+ /// The list to trim.
+ /// The number of elements to remove from the front of the list.
+ /// The altered input list.
+ internal static List Trim(this List list, int numberToTrim)
+ {
+ if (list is null)
+ throw new ArgumentNullException(nameof(list));
+ if (numberToTrim < 0 || numberToTrim > list.Count)
+ throw new ArgumentOutOfRangeException(nameof(numberToTrim));
+ list.RemoveRange(0, numberToTrim);
+ return list;
+ }
+ }
+}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs
index 7da80a8261b1..73bfcbdfb4e5 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs
@@ -75,9 +75,9 @@ public async Task GetGenericsBadNameSpace()
[RecordedTest]
public async Task GetGenericsBadApiVersion()
{
- ResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}";
+ ResourceGroupResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}";
AzureResourceManagerClientOptions options = new AzureResourceManagerClientOptions();
- options.ApiVersions.SetApiVersion(rgid.Type, "1500-10-10");
+ options.ApiVersions.SetApiVersion(rgid.ResourceType, "1500-10-10");
var client = GetArmClient(options);
var subOp = client.GetSubscriptionOperations(TestEnvironment.SubscriptionId);
var genericResourceOperations = new GenericResourceOperations(subOp, rgid);
@@ -96,7 +96,7 @@ public async Task GetGenericsBadApiVersion()
[RecordedTest]
public async Task GetGenericsGoodApiVersion()
{
- ResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}";
+ ResourceGroupResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}";
AzureResourceManagerClientOptions options = new AzureResourceManagerClientOptions();
var client = GetArmClient(options);
var subOp = client.GetSubscriptionOperations(TestEnvironment.SubscriptionId);
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs
index ab93a2e95525..db593a539454 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs
@@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core.Tests
public class ResourceGroupOperationsTests : ResourceManagerTestBase
{
public ResourceGroupOperationsTests(bool isAsync)
- : base(isAsync)//, RecordedTestMode.Record)
+ : base(isAsync) //, RecordedTestMode.Record)
{
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs
index 0a22285167d9..aed0fd78d91c 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs
@@ -21,7 +21,7 @@ public SubscriptionOperationsTests(bool isAsync)
public void GetSubscriptionOperation()
{
var sub = Client.GetSubscriptionOperations(TestEnvironment.SubscriptionId);
- Assert.AreEqual(sub.Id.Subscription, TestEnvironment.SubscriptionId);
+ Assert.AreEqual(sub.Id.SubscriptionId, TestEnvironment.SubscriptionId);
}
[TestCase(null)]
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs
index 7974378fe618..a725b9130f75 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs
@@ -27,7 +27,7 @@ public void CheckNoParamConstructor()
[TestCase (null, true)]
public void CheckUserTrueConstructor(string resourceID, bool invalidParameter)
{
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
if (invalidParameter)
{
@@ -55,7 +55,7 @@ public void CheckUserTrueConstructor(string resourceID, bool invalidParameter)
[TestCase(null, true)]
public void CheckUserFalseConstructor(string resourceID, bool invalidParameter)
{
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
if(invalidParameter)
{
@@ -97,8 +97,8 @@ public void EqualsNullOtherTest()
[TestCase]
public void EqualsReferenceTestTrue()
{
- var dict1 = new Dictionary();
- dict1["/subscriptions/6b085460-5vbg-477e-ba44-1035046e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict1 = new Dictionary();
+ dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity = new ResourceIdentity(system, dict1);
ResourceIdentity identity1 = identity;
@@ -108,12 +108,12 @@ public void EqualsReferenceTestTrue()
[TestCase]
public void EqualsTestTrue()
{
- var dict1 = new Dictionary();
- dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9000/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict1 = new Dictionary();
+ dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity = new ResourceIdentity(system, dict1);
- var dict2 = new Dictionary();
- dict2["/subscriptions/6b085460-5f21-477e-ba44-1035046e9000/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict2 = new Dictionary();
+ dict2["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity1 = new ResourceIdentity(system2, dict2);
Assert.IsTrue(identity.Equals(identity1));
@@ -122,12 +122,12 @@ public void EqualsTestTrue()
[TestCase]
public void EqualsTestFalse()
{
- var dict1 = new Dictionary();
- dict1["/subscriptions/6b085460-5f21-477e-ba44-1035nbhs9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict1 = new Dictionary();
+ dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity = new ResourceIdentity(system, dict1);
- var dict2 = new Dictionary();
- dict2["/subscriptions/6b08dfsg-5f21-475e-ba44-1035046e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict2 = new Dictionary();
+ dict2["/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity1 = new ResourceIdentity(system2, dict2);
Assert.IsFalse(identity.Equals(identity1));
@@ -136,12 +136,12 @@ public void EqualsTestFalse()
[TestCase]
public void EqualsTestFalseSameKey()
{
- var dict1 = new Dictionary();
- dict1["/subscriptions/6b085460-5f21-477e-ba44-10ancd6e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
+ var dict1 = new Dictionary();
+ dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty);
var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity = new ResourceIdentity(system, dict1);
- var dict2 = new Dictionary();
- dict2["/subscriptions/6b085460-5f21-477e-ba44-10ancd6e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), Guid.Empty);
+ var dict2 = new Dictionary();
+ dict2["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), Guid.Empty);
var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty);
ResourceIdentity identity1 = new ResourceIdentity(system2, dict2);
Assert.IsFalse(identity.Equals(identity1));
@@ -188,7 +188,7 @@ public void TestDeserializerInvalidType()
var identityJsonProperty = DeserializerHelper("InvalidType.json");
ResourceIdentity back = ResourceIdentity.Deserialize(identityJsonProperty.Value);
var user = back.UserAssignedIdentities;
- Assert.AreEqual("/subscriptions/db1ab6f0-4769-tgds-930e-01e2ef9c123c/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity", user.Keys.First().ToString());
+ Assert.AreEqual("/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity", user.Keys.First().ToString());
Assert.AreEqual("9a2eaa6a-b49c-4a63-afb5-3b72e3e65422", user.Values.First().ClientId.ToString());
Assert.AreEqual("77563a98-c9d9-4f7b-a7af-592d21fa2153", user.Values.First().PrincipalId.ToString());
}
@@ -243,10 +243,10 @@ public void TestDeserializerValidSystemAndMultUser()
Assert.IsTrue("22fddec1-8b9f-49dc-bd72-ddaf8f215570".Equals(back.SystemAssignedIdentity.PrincipalId.ToString()));
Assert.IsTrue("72f988bf-86f1-41af-91ab-2d7cd011db40".Equals(back.SystemAssignedIdentity.TenantId.ToString()));
var user = back.UserAssignedIdentities;
- Assert.AreEqual("/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9c123z/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0", user.Keys.First().ToString());
+ Assert.AreEqual("/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0", user.Keys.First().ToString());
Assert.AreEqual("9a2eaa6a-b49c-4c63-afb5-3b72e3e65422", user.Values.First().ClientId.ToString());
Assert.AreEqual("77563a98-c9d9-477b-a7af-592d21fa2153", user.Values.First().PrincipalId.ToString());
- Assert.AreEqual("/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9cfrgh/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1", user.Keys.ElementAt(1).ToString());
+ Assert.AreEqual("/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1", user.Keys.ElementAt(1).ToString());
Assert.AreEqual("9a2eaa6a-b49c-4c63-afb5-3b72e3c65420", user.Values.ElementAt(1).ClientId.ToString());
Assert.AreEqual("77563a98-c9d9-477b-a7af-592d2bfa2150", user.Values.ElementAt(1).PrincipalId.ToString());
}
@@ -278,7 +278,7 @@ public void TestSerializerValidSystemAndUser()
{
SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity;
ResourceIdentity identity = new ResourceIdentity(systemAssignedIdentity, dict1);
string system = "\"principalId\":\"de29bab1-49e1-4705-819b-4dfddceaaa98\",\"tenantId\":\"72f988bf-86f1-41af-91ab-2d7cd011db47\"";
@@ -309,7 +309,7 @@ public void TestSerializerValidSystemAndMultUser()
SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
UserAssignedIdentity userAssignedIdentity1 = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
UserAssignedIdentity userAssignedIdentity2 = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011cb47"), new Guid("de29bab1-49e1-4705-819b-4dfddcebaa98"));
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport1"] = userAssignedIdentity1;
dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport2"] = userAssignedIdentity2;
ResourceIdentity identity = new ResourceIdentity(systemAssignedIdentity, dict1);
@@ -365,7 +365,7 @@ public void TestSerializerValidSystemOnly()
public void TestSerializerValidUserEmptySystem()
{
UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity;
ResourceIdentity identity = new ResourceIdentity(dict1, true);
string system = "\"principalId\":\"null\",\"tenantId\":\"null\"";
@@ -394,7 +394,7 @@ public void TestSerializerValidUserEmptySystem()
public void TestSerializerValidUserNullSystem()
{
UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98"));
- var dict1 = new Dictionary();
+ var dict1 = new Dictionary();
dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity;
ResourceIdentity identity = new ResourceIdentity(dict1, false);
string user = "{\"clientId\":\"72f988bf-86f1-41af-91ab-2d7cd011db47\",\"principalId\":\"de29bab1-49e1-4705-819b-4dfddceaaa98\"}";
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs
index 8bb221bae37e..84393ffb3bbb 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs
@@ -4,13 +4,13 @@
namespace Azure.ResourceManager.Core.Tests
{
- public class TestResource : Resource
+ public class TestResource : Resource where TIdentifier : TenantResourceIdentifier
{
public TestResource(string id)
{
- Id = id;
+ Id = ResourceIdentifier.Create(id) as TIdentifier;
}
- public override ResourceIdentifier Id { get; protected set; }
+ public override TIdentifier Id { get; protected set; }
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs
index abb6af7b7757..ab392e77bb3a 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs
@@ -24,8 +24,8 @@ public void Setup()
public void CanParseTenant(string id)
{
ResourceIdentifier asIdentifier = id;
- Assert.AreEqual(asIdentifier.Type.Namespace, "Microsoft.Billing");
- Assert.AreEqual(asIdentifier.Type.Type, "billingAccounts");
+ Assert.AreEqual(asIdentifier.ResourceType.Namespace, "Microsoft.Billing");
+ Assert.AreEqual(asIdentifier.ResourceType.Type, "billingAccounts");
Assert.AreEqual(asIdentifier.Name, "3984c6f4-2d2a-4b04-93ce-43cf4824b698%3Ae2f1492a-a492-468d-909f-bf7fe6662c01_2019-05-31");
}
@@ -49,7 +49,7 @@ public void InvalidTenantID(string id)
public void InvalidRPIds(string invalidID)
{
Assert.Throws(() => { ResourceIdentifier subject = invalidID; });
- Assert.Throws(() => { ResourceIdentifier subject = new ResourceIdentifier(invalidID); });
+ Assert.Throws(() => { ResourceIdentifier subject = ResourceIdentifier.Create(invalidID); });
}
[TestCase (null)]
@@ -88,11 +88,11 @@ public void PublicConstructor(string resourceProviderID)
{
if (resourceProviderID is null)
{
- Assert.Throws(() => { ResourceIdentifier myResource = new ResourceIdentifier(resourceProviderID); });
+ Assert.Throws(() => { ResourceIdentifier myResource = ResourceIdentifier.Create(resourceProviderID); });
}
else
{
- ResourceIdentifier myResource = new ResourceIdentifier(resourceProviderID);
+ ResourceIdentifier myResource = ResourceIdentifier.Create(resourceProviderID);
Assert.AreEqual(myResource.ToString(), resourceProviderID);
}
}
@@ -103,12 +103,12 @@ public void PublicConstructor(string resourceProviderID)
public void CanParseRPIds(string subscription, string resourceGroup, string provider, string type, string name)
{
var resourceId = $"/subscriptions/{subscription}/resourceGroups/{Uri.EscapeDataString(resourceGroup)}/providers/{provider}/{type}/{Uri.EscapeDataString(name)}";
- ResourceIdentifier subject = resourceId;
+ ResourceGroupResourceIdentifier subject = resourceId;
Assert.AreEqual(subject.ToString(), resourceId);
- Assert.AreEqual(subject.Subscription, subscription);
- Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroup), resourceGroup);
- Assert.AreEqual(subject.Type.Namespace, provider);
- Assert.AreEqual(subject.Type.Type, type);
+ Assert.AreEqual(subject.SubscriptionId, subscription);
+ Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroupName), resourceGroup);
+ Assert.AreEqual(subject.ResourceType.Namespace, provider);
+ Assert.AreEqual(subject.ResourceType.Type, type);
Assert.AreEqual(Uri.UnescapeDataString(subject.Name), name);
}
@@ -122,8 +122,8 @@ public void CanParseExtensionResourceIds(string baseId, string extensionNamespac
ResourceIdentifier targetResourceId = baseId;
ResourceIdentifier subject = $"{baseId}/providers/{extensionNamespace}/{extensionType}/{extensionName}";
ResourceType expectedType = $"{extensionNamespace}/{extensionType}";
- Assert.AreNotEqual(targetResourceId.Type, subject.Type);
- Assert.AreEqual(expectedType, subject.Type);
+ Assert.AreNotEqual(targetResourceId.ResourceType, subject.ResourceType);
+ Assert.AreEqual(expectedType, subject.ResourceType);
Assert.NotNull(subject.Parent);
Assert.AreEqual(targetResourceId, subject.Parent);
}
@@ -132,32 +132,32 @@ public void CanParseExtensionResourceIds(string baseId, string extensionNamespac
public void CanParseProxyResource(string subscription, string rg, string resourceNamespace, string resource, string type)
{
string id = $"/subscriptions/{subscription}/resourceGroups/{rg}/providers/{resourceNamespace}/{resource}";
- ResourceIdentifier subject = id;
+ ResourceGroupResourceIdentifier subject = id;
Assert.AreEqual(subject.ToString(), id);
- Assert.AreEqual(subject.Subscription, subscription);
- Assert.AreEqual(subject.Type.Namespace, resourceNamespace);
- Assert.AreEqual(subject.Type.Type, type);
+ Assert.AreEqual(subject.SubscriptionId, subscription);
+ Assert.AreEqual(subject.ResourceType.Namespace, resourceNamespace);
+ Assert.AreEqual(subject.ResourceType.Type, type);
}
[Test]
public void CanParseSubscriptions()
{
- ResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575";
+ SubscriptionResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575";
Assert.AreEqual(subject.ToString(), "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575");
- Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
- Assert.AreEqual(subject.Type.Namespace, "Microsoft.Resources");
- Assert.AreEqual(subject.Type.Type, "subscriptions");
+ Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
+ Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Resources");
+ Assert.AreEqual(subject.ResourceType.Type, "subscriptions");
}
[Test]
public void CanParseResourceGroups()
{
- ResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg";
+ ResourceGroupResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg";
Assert.AreEqual(subject.ToString(), "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg");
- Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
- Assert.AreEqual(subject.ResourceGroup, "myRg");
- Assert.AreEqual(subject.Type.Namespace, "Microsoft.Resources");
- Assert.AreEqual(subject.Type.Type, "resourceGroups");
+ Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
+ Assert.AreEqual(subject.ResourceGroupName, "myRg");
+ Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Resources");
+ Assert.AreEqual(subject.ResourceType.Type, "subscriptions/resourceGroups");
}
[TestCase("MyVnet", "MySubnet")]
@@ -166,34 +166,75 @@ public void CanParseResourceGroups()
public void CanParseChildResources(string parentName, string name)
{
var resourceId = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}/subnets/{Uri.EscapeDataString(name)}";
- ResourceIdentifier subject = resourceId;
+ ResourceGroupResourceIdentifier subject = resourceId;
Assert.AreEqual(subject.ToString(), resourceId);
- Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
- Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroup), "myRg");
- Assert.AreEqual(subject.Type.Namespace, "Microsoft.Network");
- Assert.AreEqual(subject.Type.Parent.Type, "virtualNetworks");
- Assert.AreEqual(subject.Type.Type, "virtualNetworks/subnets");
+ Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
+ Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroupName), "myRg");
+ Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Network");
+ Assert.AreEqual(subject.Parent.ResourceType.Type, "virtualNetworks");
+ Assert.AreEqual(subject.ResourceType.Type, "virtualNetworks/subnets");
Assert.AreEqual(Uri.UnescapeDataString(subject.Name), name);
// check parent type parsing
- var parentResource = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}";
+ ResourceGroupResourceIdentifier parentResource = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}";
Assert.AreEqual(subject.Parent, parentResource);
- Assert.AreEqual(subject.Parent.ToString(), parentResource);
- Assert.AreEqual(subject.Parent.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
- Assert.AreEqual(Uri.UnescapeDataString(subject.Parent.ResourceGroup), "myRg");
- Assert.AreEqual(subject.Parent.Type.Namespace, "Microsoft.Network");
- Assert.AreEqual(subject.Parent.Type.Type, "virtualNetworks");
+ Assert.AreEqual(subject.Parent.ToString(), parentResource.ToString());
+ Assert.AreEqual(((ResourceGroupResourceIdentifier)subject.Parent).SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575");
+ Assert.AreEqual(Uri.UnescapeDataString(((ResourceGroupResourceIdentifier)subject.Parent).ResourceGroupName), "myRg");
+ Assert.AreEqual(subject.Parent.ResourceType.Namespace, "Microsoft.Network");
+ Assert.AreEqual(subject.Parent.ResourceType.Type, "virtualNetworks");
Assert.AreEqual(Uri.UnescapeDataString(subject.Parent.Name), parentName);
}
[TestCase("UnformattedString", Description ="Too Few Elements")]
[TestCase("/subs/sub1/rgs/rg1/", Description = "No known parts")]
- [TestCase("/subscriptions/sub1/resourceGroups", Description = "Too few parts")]
+ [TestCase("/subscriptions/sub1/rgs/rg1/", Description = "Subscription not a Guid")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups", Description = "Too few parts")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets", Description = "Subscription resource with too few parts")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/widgets/myWidget", Description = "Subscription resource with invalid child")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/widgets", Description = "ResourceGroup ID with Too few parts")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/widgets/myWidget", Description = "ResourceGroup ID with invalid child")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/providers/Microsoft.Widgets/widgets", Description = "ResourceGroup provider ID with Too few parts")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/incomplete", Description = "Too few parts for location resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/incomplete", Description = "Too few parts for location resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResource/myResourceName/providers/incomplete", Description = "Too few parts for location resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for resource group resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for subscription resource")]
+ [TestCase("/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for tenant resource")]
public void ThrowsOnInvalidUri(string resourceId)
{
Assert.Throws(new TestDelegate(() => ConvertToResourceId(resourceId)));
}
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/myResourceType/myResourceName", Description = "location child resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/myResourceType/myResourceName/mySingletonResource", Description = "location child singleton resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName", Description = "location provider resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName/myChildResource/myChildResourceName", Description = "location provider child resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName/providers/mySecondNamespace/myChildResource/myChildResourceName", Description = "location extension resource")]
+ public void CanParseValidLocationResource(string resourceId)
+ {
+ var id = ConvertToResourceId(resourceId);
+ Assert.AreEqual(id.ToString(), resourceId);
+ }
+
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/configuration", Description ="singleton homed in a subscription resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/providers/Contoso.Extensions/extensions/myExtension", Description = "Extension over a subscription resource")]
+ [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/flanges/myFlange", Description = "Child of a subscription resource")]
+ public void CanParseValidSubscriptionResource( string resourceId)
+ {
+ SubscriptionResourceIdentifier subscription = resourceId;
+ Assert.AreEqual(resourceId.ToString(), resourceId);
+ }
+
+ [TestCase("/providers/Contoso.Widgets/widgets/myWidget/configuration", Description = "singleton homed in a tenant resource")]
+ [TestCase("/providers/Contoso.Widgets/widgets/myWidget/providers/Contoso.Extensions/extensions/myExtension", Description = "Extension over a subscription resource")]
+ [TestCase("/providers/Contoso.Widgets/widgets/myWidget/flanges/myFlange", Description = "Child of a subscription resource")]
+ public void CanParseValidTenantResource(string resourceId)
+ {
+ TenantResourceIdentifier tenant = resourceId;
+ Assert.AreEqual(resourceId.ToString(), resourceId);
+ }
+
public ResourceIdentifier ConvertToResourceId(string resourceId)
{
ResourceIdentifier subject = resourceId;
@@ -205,8 +246,8 @@ public ResourceIdentifier ConvertToResourceId(string resourceId)
[TestCase(false, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport", "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test")]
public void CheckHashCode(bool expected, string resourceId1, string resourceId2)
{
- ResourceIdentifier resourceIdentifier1 = new ResourceIdentifier(resourceId1);
- ResourceIdentifier resourceIdentifier2 = new ResourceIdentifier(resourceId2);
+ ResourceIdentifier resourceIdentifier1 = new ResourceGroupResourceIdentifier(resourceId1);
+ ResourceIdentifier resourceIdentifier2 = new ResourceGroupResourceIdentifier(resourceId2);
Assert.AreEqual(expected, resourceIdentifier1.GetHashCode() == resourceIdentifier2.GetHashCode());
}
@@ -215,6 +256,7 @@ public void CheckHashCode(bool expected, string resourceId1, string resourceId2)
[TestCase(null, null, true)]
[TestCase(TrackedResourceId, ChildResourceId, false)]
[TestCase(ChildResourceId, TrackedResourceId, false)]
+ [TestCase(TrackedResourceId, null, false)]
[TestCase(null, TrackedResourceId, false)]
public void Equals(string resourceProviderID1, string resourceProviderID2, bool expected)
{
@@ -226,6 +268,144 @@ public void Equals(string resourceProviderID1, string resourceProviderID2, bool
Assert.AreEqual(expected, ResourceIdentifier.Equals(a,b));
}
+ [Test]
+ public void EqualsObj()
+ {
+ object input = TrackedResourceId;
+ ResourceIdentifier resource = new ResourceGroupResourceIdentifier(TrackedResourceId);
+ Assert.AreEqual(true, resource.Equals(input));
+ Assert.IsFalse(resource.Equals(new object()));
+ }
+
+ [Test]
+ public void TryGetPropertiesForTenantResource()
+ {
+ TenantResourceIdentifier id1 = "/providers/Contoso.Widgets/widgets/myWidget";
+ Assert.AreEqual(false, id1.TryGetSubscriptionId(out _));
+ Assert.AreEqual(false, id1.TryGetLocation(out _));
+ Assert.AreEqual(false, id1.TryGetResourceGroupName(out _));
+ Assert.AreEqual(false, id1.TryGetParent(out _));
+ TenantResourceIdentifier id2 = "/providers/Contoso.Widgets/widgets/myWidget/flages/myFlange";
+ ResourceIdentifier parent;
+ Assert.AreEqual(true, id2.TryGetParent(out parent));
+ Assert.AreEqual(true, id1.Equals(parent));
+ }
+
+ [Test]
+ public void TryGetPropertiesForSubscriptionResource()
+ {
+ SubscriptionResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers/Contoso.Widgets/widgets/myWidget";
+ string subscription;
+ Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription));
+ Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription);
+ Assert.AreEqual(false, id1.TryGetLocation(out _));
+ Assert.AreEqual(false, id1.TryGetResourceGroupName(out _));
+ ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101";
+ ResourceIdentifier parentId;
+ Assert.AreEqual(true, id1.TryGetParent(out parentId));
+ Assert.IsTrue(expectedId.Equals(parentId));
+ }
+
+ [Test]
+ public void TryGetPropertiesForLocationResource()
+ {
+ LocationResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2/providers/Contoso.Widgets/widgets/myWidget";
+ string subscription;
+ Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription));
+ Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription);
+ LocationData location;
+ Assert.AreEqual(true, id1.TryGetLocation(out location));
+ Assert.AreEqual(LocationData.WestUS2, location);
+ Assert.AreEqual(false, id1.TryGetResourceGroupName(out _));
+ ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2";
+ ResourceIdentifier parentId;
+ Assert.AreEqual(true, id1.TryGetParent(out parentId));
+ Assert.IsTrue(expectedId.Equals(parentId));
+ }
+
+ [Test]
+ public void TryGetPropertiesForResourceGroupResource()
+ {
+ ResourceGroupResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget";
+ string subscription;
+ Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription));
+ Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription);
+ Assert.AreEqual(false, id1.TryGetLocation(out _));
+ string resourceGroupName;
+ Assert.AreEqual(true, id1.TryGetResourceGroupName(out resourceGroupName));
+ Assert.AreEqual("myRg", resourceGroupName);
+ ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg";
+ ResourceIdentifier parentId;
+ Assert.AreEqual(true, id1.TryGetParent(out parentId));
+ Assert.IsTrue(expectedId.Equals(parentId));
+ }
+
+ [TestCase("/providers/Contoso.Widgets/widgets/myWidget", null, null, null, null, Description = "TenantResourceIdentifier")]
+ [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers/Contoso.Widgets/widgets/myWidget",
+ "6b085460-5f21-477e-ba44-1035046e9101", null, null, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101",
+ Description = "SubscriptionResourceIdentifier")]
+ [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2/providers/Contoso.Widgets/widgets/myWidget",
+ "6b085460-5f21-477e-ba44-1035046e9101", "westus2", null, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2",
+ Description = "LocationResourceIdentifier")]
+ [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget",
+ "6b085460-5f21-477e-ba44-1035046e9101", null, "myRg", "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg",
+ Description = "ResourceGroupResourceIdentifier")]
+ public void TryGetPropertiesForGenericResource(string resourceId, string subscription, string location, string resourceGroup, string parent)
+ {
+ ResourceIdentifier id1 = resourceId;
+ string outputSubscription;
+ Assert.AreEqual(!(subscription is null), id1.TryGetSubscriptionId(out outputSubscription));
+ if (!(subscription is null))
+ Assert.AreEqual(subscription, outputSubscription);
+ LocationData outputLocation;
+ Assert.AreEqual(!(location is null), id1.TryGetLocation(out outputLocation));
+ if (!(location is null))
+ Assert.AreEqual(location, outputLocation.Name);
+ string outputResourceGroup;
+ Assert.AreEqual(!(resourceGroup is null), id1.TryGetResourceGroupName(out outputResourceGroup));
+ if (!(resourceGroup is null))
+ Assert.AreEqual(resourceGroup, outputResourceGroup);
+ ResourceIdentifier outputParent;
+ Assert.AreEqual(!(parent is null), id1.TryGetParent(out outputParent));
+ if (!(parent is null))
+ Assert.AreEqual(parent, outputParent.ToString());
+ }
+
+ [TestCase("/providers/Contoso.Widgets//widgets/myWidget", Description = "TenantResourceIdentifier")]
+ [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers//Contoso.Widgets/widgets/myWidget",
+ Description = "SubscriptionResourceIdentifier")]
+ [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101//locations/westus2/providers/Contoso.Widgets/widgets/myWidget",
+ Description = "LocationResourceIdentifier")]
+ [TestCase("/subscriptions//6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget",
+ Description = "ResourceGroupResourceIdentifier")]
+ public void ResourceIdRetainsOriginalInput(string resourceId)
+ {
+ ResourceIdentifier id = resourceId;
+ Assert.AreEqual(id.ToString(), resourceId);
+ }
+
+ [Test]
+ public void ThrowOnMistypedResource()
+ {
+ TenantResourceIdentifier tenant;
+ Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101"));
+ Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2"));
+ Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg"));
+ Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101");
+ Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2");
+ Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg");
+ SubscriptionResourceIdentifier subscription;
+ Assert.Throws(() => subscription = "/providers/Contoso.Widgets/widgets/myWidget");
+ Assert.Throws(() => subscription = new SubscriptionResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2"));
+ Assert.Throws(() => subscription = new SubscriptionResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg"));
+ Assert.DoesNotThrow(() => subscription = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2");
+ Assert.DoesNotThrow(() => subscription = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg");
+ ResourceGroupResourceIdentifier group;
+ Assert.Throws(() => group = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101");
+ LocationResourceIdentifier location;
+ Assert.Throws(() => location = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101");
+ }
+
[TestCase(TrackedResourceId, TrackedResourceId, 0)]
[TestCase(TrackedResourceId, ChildResourceId, -1)]
[TestCase(ChildResourceId, TrackedResourceId, 1)]
@@ -235,11 +415,10 @@ public void Equals(string resourceProviderID1, string resourceProviderID2, bool
public void CompareToResourceProvider(string resourceProviderID1, string resourceProviderID2, int expected)
{
ResourceIdentifier a = resourceProviderID1;
- ResourceIdentifier b = resourceProviderID2;
+ ResourceIdentifier b = (ResourceIdentifier)resourceProviderID2;
if (a != null)
Assert.AreEqual(expected, a.CompareTo(b));
- Assert.AreEqual(expected, ResourceIdentifier.CompareTo(a, b));
}
[TestCase(TrackedResourceId, TrackedResourceId, 0)]
@@ -254,8 +433,209 @@ public void CompareToString(string resourceProviderID1, string resourceProviderI
string b = resourceProviderID2;
if (a != null)
Assert.AreEqual(expected, a.CompareTo(b));
+ }
+
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget", "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", null, "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", null, "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", null)]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", " ", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")]
- Assert.AreEqual(expected, ResourceIdentifier.CompareTo(a, b));
+ public void TestAppendTenantProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName)
+ {
+ TenantResourceIdentifier resource = resourceId;
+ if (providerNamespace is null || resourceTypeName is null || resourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else
+ {
+ var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}";
+ Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString());
+ }
+ }
+
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget", "wheels", "Wheel1")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", "Wheel2")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", null, "wheel2")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", null)]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "", "wheel2")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", " ")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels/spokes", "wheel2")]
+ [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", "wheel1/wheel2")]
+ public void TestAppendTenantChildResource(string resourceId, string childTypeName, string childResourceName)
+ {
+ TenantResourceIdentifier resource = resourceId;
+ if (childTypeName is null || childResourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (childTypeName.Contains("/") || childResourceName.Contains("/") )
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else
+ {
+ var expected = $"{resourceId}/{childTypeName}/{childResourceName}";
+ Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString());
+ }
+ }
+
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, null, "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", null)]
+ [TestCase(SubscriptionResourceId, "", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "")]
+ [TestCase(SubscriptionResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")]
+ [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")]
+
+ public void TestAppendSubscriptionProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName)
+ {
+ SubscriptionResourceIdentifier resource = resourceId;
+ if (providerNamespace is null || resourceTypeName is null || resourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else
+ {
+ var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}";
+ Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString());
+ }
+ }
+
+ [TestCase(SubscriptionResourceId, "wheels", "Wheel2")]
+ [TestCase(SubscriptionResourceId, null, "wheel2")]
+ [TestCase(SubscriptionResourceId, "wheels", null)]
+ [TestCase(SubscriptionResourceId, "", "wheel2")]
+ [TestCase(SubscriptionResourceId, "wheels", " ")]
+ [TestCase(SubscriptionResourceId, "wheels/spokes", "wheel2")]
+ [TestCase(SubscriptionResourceId, "wheels", "wheel1/wheel2")]
+ public void TestAppendSubscriptionChildResource(string resourceId, string childTypeName, string childResourceName)
+ {
+ SubscriptionResourceIdentifier resource = resourceId;
+ if (childTypeName is null || childResourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (childTypeName.Contains("/") || childResourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else
+ {
+ var expected = $"{resourceId}/{childTypeName}/{childResourceName}";
+ Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString());
+ }
+ }
+
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, null, "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", null)]
+ [TestCase(ResourceGroupResourceId, "", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "")]
+ [TestCase(ResourceGroupResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")]
+ [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")]
+
+ public void TestAppendResourceGroupProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName)
+ {
+ ResourceGroupResourceIdentifier resource = resourceId;
+ if (providerNamespace is null || resourceTypeName is null || resourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else
+ {
+ var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}";
+ Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString());
+ }
+ }
+
+ [TestCase(ResourceGroupResourceId, "wheels", "Wheel1")]
+ [TestCase(ResourceGroupResourceId, "wheels", "Wheel2")]
+ [TestCase(ResourceGroupResourceId, null, "wheel2")]
+ [TestCase(ResourceGroupResourceId, "wheels", null)]
+ [TestCase(ResourceGroupResourceId, "", "wheel2")]
+ [TestCase(ResourceGroupResourceId, "wheels", " ")]
+ [TestCase(ResourceGroupResourceId, "wheels/spokes", "wheel2")]
+ [TestCase(ResourceGroupResourceId, "wheels", "wheel1/wheel2")]
+ public void TestAppendResourceGroupChildResource(string resourceId, string childTypeName, string childResourceName)
+ {
+ ResourceGroupResourceIdentifier resource = resourceId;
+ if (childTypeName is null || childResourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (childTypeName.Contains("/") || childResourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else
+ {
+ var expected = $"{resourceId}/{childTypeName}/{childResourceName}";
+ Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString());
+ }
+ }
+
+ [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, null, "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", null)]
+ [TestCase(LocationResourceId, "", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "")]
+ [TestCase(LocationResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")]
+ [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")]
+
+ public void TestAppendLocationProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName)
+ {
+ LocationResourceIdentifier resource = resourceId;
+ if (providerNamespace is null || resourceTypeName is null || resourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName));
+ else
+ {
+ var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}";
+ Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString());
+ }
+ }
+
+ [TestCase(LocationResourceId, "wheels", "Wheel1")]
+ [TestCase(LocationResourceId, null, "wheel2")]
+ [TestCase(LocationResourceId, "wheels", null)]
+ [TestCase(LocationResourceId, "", "wheel2")]
+ [TestCase(LocationResourceId, "wheels", " ")]
+ [TestCase(LocationResourceId, "wheels/spokes", "wheel2")]
+ [TestCase(LocationResourceId, "wheels", "wheel1/wheel2")]
+ public void TestAppendLocationChildResource(string resourceId, string childTypeName, string childResourceName)
+ {
+ LocationResourceIdentifier resource = resourceId;
+ if (childTypeName is null || childResourceName is null)
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName))
+ Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else if (childTypeName.Contains("/") || childResourceName.Contains("/"))
+ Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName));
+ else
+ {
+ var expected = $"{resourceId}/{childTypeName}/{childResourceName}";
+ Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString());
+ }
}
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs
index 594d64f300eb..a3ea91900e7c 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs
@@ -107,7 +107,7 @@ private static ResourceGroupOperations GetResourceGroupOperations()
private static GenericResourceExpanded GetGenericResource()
{
- return GetGenereicResource(
+ return GetGenericResource(
new Dictionary { { "tag1", "value1" } },
GetSku(),
GetPlan(),
@@ -116,7 +116,7 @@ private static GenericResourceExpanded GetGenericResource()
"Japan East");
}
- private static GenericResourceExpanded GetGenereicResource(
+ private static GenericResourceExpanded GetGenericResource(
Dictionary tags,
ResourceManager.Resources.Models.Sku sku,
ResourceManager.Resources.Models.Plan plan,
@@ -126,14 +126,16 @@ private static GenericResourceExpanded GetGenereicResource(
{
var resource = new GenericResourceExpanded();
+ // See TODO in GenericResourceOperations.Valide().
+ //resource.Id = "/subscriptions/{subscription-id}/resourceGroups/myResourceGroup";
+ var field = typeof(Resource).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
+ field.SetValue(resource, $"/subscriptions/{Guid.NewGuid().ToString()}/resourceGroups/myResourceGroup/providers/Microsoft.Widgets/widgets/myWidget");
resource.Location = location;
resource.Tags.ReplaceWith(tags ?? new Dictionary());
resource.Sku = sku;
resource.Plan = plan;
resource.Kind = kind;
resource.ManagedBy = managedBy;
- var field = typeof(GenericResourceExpanded).BaseType.BaseType.GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
- field.SetValue(resource, "/subscriptions/{subscription-id}/resourceGroups/myResourceGroup");
return resource;
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs
index f66207971f3e..4bb596b7c7ed 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs
@@ -22,8 +22,8 @@ public class ResourceTests
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account2")]
public void CompareToObject(int expected, string id1, string id2)
{
- TestResource resource1 = new TestResource(id1);
- TestResource resource2 = new TestResource(id2);
+ TestResource resource1 = new TestResource(id1);
+ TestResource resource2 = new TestResource(id2);
Assert.AreEqual(expected, resource1.CompareTo(resource2));
}
@@ -41,15 +41,15 @@ public void CompareToObject(int expected, string id1, string id2)
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account2")]
public void CompareToString(int expected, string id1, string id2)
{
- TestResource resource1 = new TestResource(id1);
+ TestResource resource1 = new TestResource(id1);
Assert.AreEqual(expected, resource1.CompareTo(id2));
}
[Test]
public void CompareToNull()
{
- TestResource resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1");
- TestResource resource2 = null;
+ var resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1");
+ TestResource resource2 = null;
Assert.AreEqual(1, resource1.CompareTo(resource2));
Assert.AreEqual(1, resource1.CompareTo((string)null));
}
@@ -57,8 +57,8 @@ public void CompareToNull()
[Test]
public void CompareToSame()
{
- TestResource resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1");
- TestResource resource2 = resource1;
+ var resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1");
+ var resource2 = resource1;
Assert.AreEqual(0, resource1.CompareTo(resource2));
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json
index 88dc49b9af0e..a2328a4b92fa 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json
@@ -4,10 +4,10 @@
"tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"type": "Test",
"userAssignedIdentities": {
- "/subscriptions/db1ab6f0-4769-tgds-930e-01e2ef9c123c/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity": {
- "clientId": "9a2eaa6a-b49c-4a63-afb5-3b72e3e65422",
- "principalId": "77563a98-c9d9-4f7b-a7af-592d21fa2153"
- }
+ "/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity": {
+ "clientId": "9a2eaa6a-b49c-4a63-afb5-3b72e3e65422",
+ "principalId": "77563a98-c9d9-4f7b-a7af-592d21fa2153"
+ }
}
}
}
diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json
index 660ab014dee5..f8084ae97d51 100644
--- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json
+++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json
@@ -4,14 +4,14 @@
"tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db40",
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
- "/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9c123z/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0": {
- "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3e65422",
- "principalId": "77563a98-c9d9-477b-a7af-592d21fa2153"
- },
- "/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9cfrgh/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1": {
- "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3c65420",
- "principalId": "77563a98-c9d9-477b-a7af-592d2bfa2150"
- }
+ "/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0": {
+ "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3e65422",
+ "principalId": "77563a98-c9d9-477b-a7af-592d21fa2153"
+ },
+ "/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1": {
+ "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3c65420",
+ "principalId": "77563a98-c9d9-477b-a7af-592d2bfa2150"
+ }
}
}
}
diff --git a/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs b/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs
index ca7cf83f03df..bf330f41a280 100644
--- a/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs
+++ b/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs
@@ -51,7 +51,7 @@ public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this Subs
/// The subscription containign the role assignment
/// The target of the role assignment
/// A that allows creating and listing RoleAssignments
- public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this SubscriptionOperations subscription, Resource scope)
+ public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this SubscriptionOperations subscription, Resource scope)
{
return new RoleAssignmentContainer(subscription, scope.Id);
}
diff --git a/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs b/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs
index f5a5b143bad7..ddb0d859acc5 100644
--- a/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs
+++ b/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs
@@ -9,7 +9,7 @@ namespace Proto.Authorization
///
/// Placholder class containing Role assignment POCO properties.
///
- public class RoleAssignmentData : Resource
+ public class RoleAssignmentData : Resource
{
private Azure.ResourceManager.Authorization.Models.RoleAssignment _model;
@@ -20,7 +20,7 @@ public class RoleAssignmentData : Resource
public RoleAssignmentData(Azure.ResourceManager.Authorization.Models.RoleAssignment assign)
{
_model = assign;
- Id = assign.Id;
+ Id = new TenantResourceIdentifier(assign.Id);
Scope = assign.Scope;
RoleDefinitionId = assign.RoleDefinitionId;
PrincipalId = assign.PrincipalId;
@@ -61,7 +61,7 @@ public RoleAssignmentData(Azure.ResourceManager.Authorization.Models.RoleAssignm
///
/// Gets or sets the identifier of the RoleAssignment.
///
- public override ResourceIdentifier Id { get; protected set; }
+ public override TenantResourceIdentifier Id { get; protected set; }
///
/// Gets the Track2 Management model associated with the data object.
diff --git a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs
index 91fc04b98669..04a6be91b5ac 100644
--- a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs
+++ b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs
@@ -3,6 +3,7 @@
using Azure.ResourceManager.Authorization;
using Azure.ResourceManager.Core;
+using System;
using System.Threading;
using System.Threading.Tasks;
@@ -20,6 +21,14 @@ public class RoleAssignmentContainer : ExtensionResourceContainer
@@ -30,6 +39,14 @@ internal RoleAssignmentContainer(OperationsBase operations)
internal RoleAssignmentContainer(OperationsBase operations, ResourceIdentifier scope)
: base(operations, scope)
{
+ // TODO: Remove this once we nio longer need to create management clients
+ string subscriptionId;
+ if (!operations.Id.TryGetSubscriptionId(out subscriptionId))
+ {
+ subscriptionId = Guid.Empty.ToString();
+ }
+
+ Operations = new AuthorizationManagementClient(subscriptionId, BaseUri, Credential).RoleAssignments;
}
///
@@ -38,7 +55,7 @@ internal RoleAssignmentContainer(OperationsBase operations, ResourceIdentifier s
///
/// Gets the resource type of the resource being created.
///
- private RoleAssignmentsOperations Operations => new AuthorizationManagementClient(Id.Subscription, BaseUri, Credential).RoleAssignments;
+ private RoleAssignmentsOperations Operations { get; }
///
/// Create a role assignment. This method blocks until the RoleAssignment is created on the service.
diff --git a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs
index 555de7279a9a..adc08ef924d5 100644
--- a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs
+++ b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs
@@ -4,6 +4,7 @@
using Azure;
using Azure.ResourceManager.Authorization;
using Azure.ResourceManager.Core;
+using System;
using System.Threading;
using System.Threading.Tasks;
@@ -27,6 +28,14 @@ public class RoleAssignmentOperations : ExtensionResourceOperationsBase
@@ -37,16 +46,20 @@ internal RoleAssignmentOperations(GenericResourceOperations genericOperations)
internal RoleAssignmentOperations(OperationsBase operation, ResourceIdentifier id)
: base(operation, id)
{
+ string subscriptionId;
+ if (!Id.TryGetSubscriptionId(out subscriptionId))
+ {
+ // TODO: Remove this once we have swapped in the REST client
+ subscriptionId = Guid.Empty.ToString();
+ }
+
+ Operations = new AuthorizationManagementClient(subscriptionId, BaseUri, Credential).RoleAssignments;
}
///
protected override ResourceType ValidResourceType => ResourceType;
- private RoleAssignmentsOperations Operations => new AuthorizationManagementClient(
- Id.Subscription,
- BaseUri,
- Credential,
- ClientOptions.Convert()).RoleAssignments;
+ private RoleAssignmentsOperations Operations { get; }
///
public ArmResponse Delete(CancellationToken cancellationToken = default)
diff --git a/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs b/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs
index cb84ce0b36b7..4290c1278e7f 100644
--- a/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs
+++ b/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs
@@ -13,7 +13,7 @@ namespace Proto.Billing
///
/// A class representing the operations that can be performed over a specific availability set.
///
- public class BillingAccountOperations : ResourceOperationsBase
+ public class BillingAccountOperations : ResourceOperationsBase
{
///
/// Initializes a new instance of the class.
diff --git a/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs b/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs
index 8524744289da..5ce6b2ff31bc 100644
--- a/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs
+++ b/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs
@@ -8,7 +8,7 @@ namespace Proto.Billing
///
/// A class representing the availability set data model.
///
- public class BillingAccountData : TrackedResource
+ public class BillingAccountData : TrackedResource
{
///
diff --git a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs
index f8c42bf617ee..7c7685105398 100644
--- a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs
@@ -10,7 +10,7 @@ namespace Proto.Compute
///
/// A class representing collection of availability set and their operations over a resource group.
///
- public class AvailabilitySetContainer : ResourceContainerBase
+ public class AvailabilitySetContainer : ResourceContainerBase
{
///
/// Initializes a new instance of the class.
@@ -24,10 +24,15 @@ internal AvailabilitySetContainer(ResourceGroupOperations resourceGroup)
///
protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType;
+ ///
+ /// Typed Resource Identifier for the container.
+ ///
+ public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier;
+
///
public override ArmResponse CreateOrUpdate(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default)
{
- var response = Operations.CreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model);
+ var response = Operations.CreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model);
return new PhArmResponse(
response,
a => new AvailabilitySet(Parent, new AvailabilitySetData(a)));
@@ -36,7 +41,8 @@ public override ArmResponse CreateOrUpdate(string name, Availab
///
public async override Task> CreateOrUpdateAsync(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default)
{
- var response = await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false);
+ var containerId = Id as ResourceGroupResourceIdentifier;
+ var response = await Operations.CreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false);
return new PhArmResponse(
response,
a => new AvailabilitySet(Parent, new AvailabilitySetData(a)));
@@ -46,7 +52,7 @@ public async override Task> CreateOrUpdateAsync(str
public override ArmOperation StartCreateOrUpdate(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- Operations.CreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken),
+ Operations.CreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken),
a => new AvailabilitySet(Parent, new AvailabilitySetData(a)));
}
@@ -54,7 +60,7 @@ public override ArmOperation StartCreateOrUpdate(string name, A
public async override Task> StartCreateOrUpdateAsync(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false),
+ await Operations.CreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false),
a => new AvailabilitySet(Parent, new AvailabilitySetData(a)));
}
@@ -64,9 +70,9 @@ await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Mod
/// The sku name of the resource.
/// The location of the resource.
/// A builder with and .
- public ArmBuilder Construct(string skuName, LocationData location = null)
+ public ArmBuilder Construct(string skuName, LocationData location = null)
{
- var parent = GetParentResource();
+ var parent = GetParentResource();
var availabilitySet = new Azure.ResourceManager.Compute.Models.AvailabilitySet(location ?? parent.Data.Location)
{
PlatformUpdateDomainCount = 5,
@@ -74,7 +80,7 @@ public ArmBuilder Construct(string skuName
Sku = new Azure.ResourceManager.Compute.Models.Sku() { Name = skuName }
};
- return new ArmBuilder(this, new AvailabilitySetData(availabilitySet));
+ return new ArmBuilder(this, new AvailabilitySetData(availabilitySet));
}
///
@@ -135,7 +141,7 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nu
private AvailabilitySetsOperations Operations => new ComputeManagementClient(
BaseUri,
- Id.Subscription,
+ Id.SubscriptionId,
Credential,
ClientOptions.Convert()).AvailabilitySets;
@@ -143,14 +149,14 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nu
///
public override ArmResponse Get(string availabilitySetName, CancellationToken cancellationToken = default)
{
- return new PhArmResponse(Operations.Get(Id.ResourceGroup, availabilitySetName),
+ return new PhArmResponse(Operations.Get(Id.ResourceGroupName, availabilitySetName),
g => new AvailabilitySet(Parent, new AvailabilitySetData(g)));
}
///
public override async Task> GetAsync(string availabilitySetName, CancellationToken cancellationToken = default)
{
- return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, availabilitySetName, cancellationToken),
+ return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, availabilitySetName, cancellationToken),
g => new AvailabilitySet(Parent, new AvailabilitySetData(g)));
}
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs
index 35db75c5c344..430270006a0a 100644
--- a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs
@@ -12,7 +12,7 @@ namespace Proto.Compute
///
/// A class representing the operations that can be performed over a specific availability set.
///
- public class AvailabilitySetOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
+ public class AvailabilitySetOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
{
///
/// Initializes a new instance of the class.
@@ -29,7 +29,7 @@ internal AvailabilitySetOperations(GenericResourceOperations genericOperations)
/// The client parameters to use in these operations.
/// The name of the availability set to use.
internal AvailabilitySetOperations(ResourceGroupOperations resourceGroup, string availabilitySetName)
- : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Compute/availabilitySets/{availabilitySetName}")
+ : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, availabilitySetName))
{
}
@@ -38,7 +38,7 @@ internal AvailabilitySetOperations(ResourceGroupOperations resourceGroup, string
///
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
- protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceIdentifier id)
+ protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceGroupResourceIdentifier id)
: base(options, id)
{
}
@@ -53,39 +53,39 @@ protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceIden
private AvailabilitySetsOperations Operations => new ComputeManagementClient(
BaseUri,
- Id.Subscription,
+ Id.SubscriptionId,
Credential,
ClientOptions.Convert()).AvailabilitySets;
///
public ArmResponse Delete(CancellationToken cancellationToken = default)
{
- return new ArmResponse(Operations.Delete(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmResponse(Operations.Delete(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
public async Task> DeleteAsync(CancellationToken cancellationToken = default)
{
- return new ArmResponse(await Operations.DeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmResponse(await Operations.DeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
public ArmOperation StartDelete(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(Operations.Delete(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmVoidOperation(Operations.Delete(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
public async Task> StartDeleteAsync(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(await Operations.DeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmVoidOperation(await Operations.DeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
public override ArmResponse Get(CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- Operations.Get(Id.ResourceGroup, Id.Name),
+ Operations.Get(Id.ResourceGroupName, Id.Name),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
@@ -93,7 +93,7 @@ public override ArmResponse Get(CancellationToken cancellationT
public async override Task> GetAsync(CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken),
+ await Operations.GetAsync(Id.ResourceGroupName, Id.Name, cancellationToken),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
@@ -105,7 +105,7 @@ await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken),
public ArmResponse Update(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- Operations.Update(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ Operations.Update(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
@@ -118,7 +118,7 @@ public ArmResponse Update(AvailabilitySetUpdate patchable, Canc
public async Task> UpdateAsync(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ await Operations.UpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
@@ -130,7 +130,7 @@ await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationT
public ArmOperation StartUpdate(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- Operations.Update(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ Operations.Update(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
@@ -143,7 +143,7 @@ public ArmOperation StartUpdate(AvailabilitySetUpdate patchable
public async Task> StartUpdateAsync(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ await Operations.UpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
a => new AvailabilitySet(this, new AvailabilitySetData(a)));
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs
index 79a31fecf2cf..2a9ebfaabcc4 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs
@@ -25,7 +25,7 @@ public VirtualMachineModelBuilder(VirtualMachineContainer containerOperations, V
///
/// The disk to attach.
/// An instance of
- public VirtualMachineModelBuilderBase AttachDataDisk(TrackedResource azureEntity)
+ public VirtualMachineModelBuilderBase AttachDataDisk(TrackedResource azureEntity)
{
throw new NotImplementedException();
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs
index b3ee5ee648f8..013100e0a95d 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs
@@ -5,7 +5,7 @@ namespace Proto.Compute.Convenience
///
/// A class representing the base for a builder object to help create a virtual machine.
///
- public abstract class VirtualMachineModelBuilderBase : ArmBuilder
+ public abstract class VirtualMachineModelBuilderBase : ArmBuilder
{
///
/// Initializes a new instance of .
diff --git a/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs b/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs
index 1601ce928cc8..e283e86aba45 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs
@@ -17,14 +17,14 @@ public static class ArmClientExtensions
/// Returns an object representing the operations that can be performed over a specific .
/// ResourceIdentifier provided is not for an AvailabilitySet.
/// ResourceIdentifier cannot be null.
- public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId)
+ public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId)
{
if (resourceId is null)
throw new ArgumentNullException(nameof(resourceId));
- if (resourceId.Type != AvailabilitySetOperations.ResourceType)
- throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for an AvailabilitySet.", nameof(resourceId.Type));
+ if (resourceId.ResourceType != AvailabilitySetOperations.ResourceType)
+ throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for an AvailabilitySet.", nameof(resourceId.ResourceType));
- return client.GetSubscriptionOperations(resourceId.Subscription).GetResourceGroupOperations(resourceId.ResourceGroup).GetAvailabilitySetOperations(resourceId.Name);
+ return client.GetSubscriptionOperations(resourceId.SubscriptionId).GetResourceGroupOperations(resourceId.ResourceGroupName).GetAvailabilitySetOperations(resourceId.Name);
}
///
@@ -35,14 +35,14 @@ public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureR
/// Returns an object representing the operations that can be performed over a specific .
/// ResourceIdentifier provided is not for a VirtualMachine.
/// ResourceIdentifier cannot be null.
- public static VirtualMachineOperations GetVirtualMachineOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId)
+ public static VirtualMachineOperations GetVirtualMachineOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId)
{
if (resourceId is null)
throw new ArgumentNullException(nameof(resourceId));
- if (resourceId.Type != VirtualMachineOperations.ResourceType)
- throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a VirtualMachine.", nameof(resourceId.Type));
+ if (resourceId.ResourceType != VirtualMachineOperations.ResourceType)
+ throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a VirtualMachine.", nameof(resourceId.ResourceType));
- return client.GetSubscriptionOperations(resourceId.Subscription).GetResourceGroupOperations(resourceId.ResourceGroup).GetVirtualMachineOperations(resourceId.Name);
+ return client.GetSubscriptionOperations(resourceId.SubscriptionId).GetResourceGroupOperations(resourceId.ResourceGroupName).GetVirtualMachineOperations(resourceId.Name);
}
}
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs b/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs
index 8a9c3d619395..d9fb321f546c 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs
@@ -32,7 +32,7 @@ private static ComputeManagementClient GetComputeClient(SubscriptionOperations s
{
return new ComputeManagementClient(
subscription.BaseUri,
- subscription.Id.Subscription,
+ subscription.Id.SubscriptionId,
subscription.Credential,
subscription.ClientOptions.Convert());
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs b/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs
index 57b1f66a3602..63e6354d9f5a 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs
@@ -8,7 +8,7 @@ namespace Proto.Compute
///
/// A class representing the availability set data model.
///
- public class AvailabilitySetData : TrackedResource
+ public class AvailabilitySetData : TrackedResource
{
///
/// Gets the resource type definition for an availability set.
diff --git a/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs b/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs
index 65f46a4961fc..1f047c7a58e3 100644
--- a/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs
@@ -8,7 +8,7 @@ namespace Proto.Compute
///
/// A class representing the VirtualMachine data model.
///
- public class VirtualMachineData : TrackedResource
+ public class VirtualMachineData : TrackedResource
{
///
/// Initializes a new instance of the class.
@@ -136,12 +136,12 @@ public ResourceIdentity Identity
private ResourceIdentity VmIdentityToIdentity(VirtualMachineIdentity vmIdentity)
{
SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid(vmIdentity.TenantId), new Guid(vmIdentity.PrincipalId));
- var userAssignedIdentities = new Dictionary();
+ var userAssignedIdentities = new Dictionary();
if (vmIdentity.UserAssignedIdentities != null)
{
foreach (var entry in vmIdentity.UserAssignedIdentities)
{
- ResourceIdentifier resourceId = new ResourceIdentifier(entry.Key);
+ var resourceId = new ResourceGroupResourceIdentifier(entry.Key);
var userAssignedIdentity = new UserAssignedIdentity(new Guid(entry.Value.ClientId), new Guid(entry.Value.PrincipalId));
userAssignedIdentities[resourceId] = userAssignedIdentity;
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs
index 249d9a077064..47b755470a5f 100644
--- a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs
@@ -13,7 +13,7 @@ namespace Proto.Compute
///
/// A class representing collection of VirtualMachine and their operations over a ResourceGroup.
///
- public class VirtualMachineContainer : ResourceContainerBase
+ public class VirtualMachineContainer : ResourceContainerBase
{
///
/// Initializes a new instance of the class.
@@ -24,9 +24,14 @@ internal VirtualMachineContainer(ResourceGroupOperations resourceGroup)
{
}
+ ///
+ /// Typed Resource Identifier for the container.
+ ///
+ public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier;
+
private VirtualMachinesOperations Operations => new ComputeManagementClient(
BaseUri,
- Id.Subscription,
+ Id.SubscriptionId,
Credential,
ClientOptions.Convert()).VirtualMachines;
@@ -44,7 +49,7 @@ internal VirtualMachineContainer(ResourceGroupOperations resourceGroup)
/// A response with the operation for this resource.
public override ArmResponse CreateOrUpdate(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default)
{
- var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken);
+ var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken);
return new PhArmResponse(
operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
@@ -59,7 +64,7 @@ public override ArmResponse CreateOrUpdate(string name, VirtualM
/// A that on completion returns a response with the operation for this resource.
public async override Task> CreateOrUpdateAsync(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default)
{
- var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false);
+ var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false);
return new PhArmResponse(
await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
@@ -78,7 +83,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false),
public override ArmOperation StartCreateOrUpdate(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken),
+ Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
}
@@ -95,7 +100,7 @@ public override ArmOperation StartCreateOrUpdate(string name, Vi
public async override Task> StartCreateOrUpdateAsync(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false),
+ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
}
@@ -111,7 +116,7 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail
/// Object used to create a .
public VirtualMachineModelBuilder Construct(string hostName, string adminUser, string adminPassword, ResourceIdentifier networkInterfaceId, ResourceIdentifier availabilitySetId, LocationData location = null)
{
- var parent = GetParentResource();
+ var parent = GetParentResource();
var vm = new Azure.ResourceManager.Compute.Models.VirtualMachine(location ?? parent.Data.Location)
{
NetworkProfile = new NetworkProfile(),
@@ -225,14 +230,14 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nul
///
public override ArmResponse Get(string virtualMachineName, CancellationToken cancellationToken = default)
{
- return new PhArmResponse(Operations.Get(Id.ResourceGroup, virtualMachineName, cancellationToken),
+ return new PhArmResponse(Operations.Get(Id.ResourceGroupName, virtualMachineName, cancellationToken),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
}
///
public override async Task> GetAsync(string virtualMachineName, CancellationToken cancellationToken = default)
{
- return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, virtualMachineName, cancellationToken),
+ return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, virtualMachineName, cancellationToken),
v => new VirtualMachine(Parent, new VirtualMachineData(v)));
}
}
diff --git a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs
index a0e07d582341..503bb80275f1 100644
--- a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs
+++ b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs
@@ -12,7 +12,7 @@ namespace Proto.Compute
///
/// A class representing the operations that can be performed over a specific VirtualMachine.
///
- public class VirtualMachineOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
+ public class VirtualMachineOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource
{
///
/// Initializes a new instance of the class.
@@ -29,7 +29,7 @@ internal VirtualMachineOperations(GenericResourceOperations genericOperations)
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
internal VirtualMachineOperations(ResourceGroupOperations resourceGroup, string vmName)
- : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Compute/virtualMachines/{vmName}")
+ : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, vmName))
{
}
@@ -38,7 +38,7 @@ internal VirtualMachineOperations(ResourceGroupOperations resourceGroup, string
///
/// The client parameters to use in these operations.
/// The identifier of the resource that is the target of operations.
- protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceIdentifier id)
+ protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceGroupResourceIdentifier id)
: base(operation, id)
{
}
@@ -55,7 +55,7 @@ protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceIde
private VirtualMachinesOperations Operations => new ComputeManagementClient(
BaseUri,
- Id.Subscription,
+ Id.SubscriptionId,
Credential,
ClientOptions.Convert()).VirtualMachines;
@@ -72,25 +72,25 @@ public static VirtualMachineOperations FromGeneric(GenericResourceOperations gen
///
public ArmResponse Delete(CancellationToken cancellationToken = default)
{
- return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
+ return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}
///
public async Task> DeleteAsync(CancellationToken cancellationToken = default)
{
- return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
+ return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}
///
public ArmOperation StartDelete(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
public async Task> StartDeleteAsync(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken));
}
#region PowerOn
@@ -101,7 +101,7 @@ public async Task> StartDeleteAsync(CancellationToken can
/// A response with the operation for this resource.
public ArmResponse PowerOn(CancellationToken cancellationToken = default)
{
- var operation = Operations.StartStart(Id.ResourceGroup, Id.Name, cancellationToken);
+ var operation = Operations.StartStart(Id.ResourceGroupName, Id.Name, cancellationToken);
return new ArmResponse(operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}
@@ -112,7 +112,7 @@ public ArmResponse PowerOn(CancellationToken cancellationToken = defau
/// A that on completion returns a response with the operation for this resource.
public async Task> PowerOnAsync(CancellationToken cancellationToken = default)
{
- var operation = await Operations.StartStartAsync(Id.ResourceGroup, Id.Name, cancellationToken).ConfigureAwait(false);
+ var operation = await Operations.StartStartAsync(Id.ResourceGroupName, Id.Name, cancellationToken).ConfigureAwait(false);
return new ArmResponse(await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false));
}
@@ -123,7 +123,7 @@ public async Task> PowerOnAsync(CancellationToken cancella
/// An that allows polling for completion of the operation.
public ArmOperation StartPowerOn(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(Operations.StartStart(Id.ResourceGroup, Id.Name, cancellationToken));
+ return new ArmVoidOperation(Operations.StartStart(Id.ResourceGroupName, Id.Name, cancellationToken));
}
///
@@ -133,7 +133,7 @@ public ArmOperation StartPowerOn(CancellationToken cancellationToken =
/// A that on completion returns an that allows polling for completion of the operation.
public async Task> StartPowerOnAsync(CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(await Operations.StartStartAsync(Id.ResourceGroup, Id.Name, cancellationToken).ConfigureAwait(false));
+ return new ArmVoidOperation(await Operations.StartStartAsync(Id.ResourceGroupName, Id.Name, cancellationToken).ConfigureAwait(false));
}
#endregion
@@ -146,7 +146,7 @@ public async Task> StartPowerOnAsync(CancellationToken ca
/// A response with the operation for this resource.
public ArmResponse PowerOff(bool? skipShutdown = null, CancellationToken cancellationToken = default)
{
- var operation = Operations.StartPowerOff(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken);
+ var operation = Operations.StartPowerOff(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken);
return new ArmResponse(operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}
@@ -158,7 +158,7 @@ public ArmResponse PowerOff(bool? skipShutdown = null, CancellationTok
/// A that on completion returns a response with the operation for this resource.
public async Task> PowerOffAsync(bool? skipShutdown = null, CancellationToken cancellationToken = default)
{
- var operation = await Operations.StartPowerOffAsync(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false);
+ var operation = await Operations.StartPowerOffAsync(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false);
return new ArmResponse(await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false));
}
@@ -170,7 +170,7 @@ public async Task> PowerOffAsync(bool? skipShutdown = null
/// An that allows polling for completion of the operation.
public ArmOperation StartPowerOff(bool? skipShutdown = null, CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(Operations.StartPowerOff(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken));
+ return new ArmVoidOperation(Operations.StartPowerOff(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken));
}
///
@@ -181,7 +181,7 @@ public ArmOperation StartPowerOff(bool? skipShutdown = null, Cancellat
/// A that on completion returns an that allows polling for completion of the operation.
public async Task> StartPowerOffAsync(bool? skipShutdown = null, CancellationToken cancellationToken = default)
{
- return new ArmVoidOperation(await Operations.StartPowerOffAsync(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false));
+ return new ArmVoidOperation(await Operations.StartPowerOffAsync(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false));
}
#endregion
@@ -189,7 +189,7 @@ public async Task> StartPowerOffAsync(bool? skipShutdown
public override ArmResponse Get(CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken),
+ Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -197,7 +197,7 @@ public override ArmResponse Get(CancellationToken cancellationTo
public override async Task> GetAsync(CancellationToken cancellationToken = default)
{
return new PhArmResponse(
- await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken),
+ await Operations.GetAsync(Id.ResourceGroupName, Id.Name, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -209,7 +209,7 @@ await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken),
public ArmOperation StartUpdate(VirtualMachineUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -222,7 +222,7 @@ public ArmOperation StartUpdate(VirtualMachineUpdate patchable,
public async Task> StartUpdateAsync(VirtualMachineUpdate patchable, CancellationToken cancellationToken = default)
{
return new PhArmOperation(
- await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -235,7 +235,7 @@ public ArmResponse AddTag(string key, string value, Cancellation
patchable.Tags[key] = value;
return new PhArmResponse(
- Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
+ Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -248,7 +248,7 @@ public async Task> AddTagAsync(string key, string va
patchable.Tags[key] = value;
return new PhArmResponse(
- await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(),
+ await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -261,7 +261,7 @@ public ArmOperation StartAddTag(string key, string value, Cancel
patchable.Tags[key] = value;
return new PhArmOperation(
- Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -274,7 +274,7 @@ public async Task> StartAddTagAsync(string key, str
patchable.Tags[key] = value;
return new PhArmOperation(
- await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken),
+ await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -285,7 +285,7 @@ public ArmResponse SetTags(IDictionary tags, Can
patchable.Tags.ReplaceWith(tags);
return new PhArmResponse(
- Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
+ Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -296,7 +296,7 @@ public async Task> SetTagsAsync(IDictionary(
- await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken),
+ await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -307,7 +307,7 @@ public ArmOperation StartSetTags(IDictionary tag
patchable.Tags.ReplaceWith(tags);
return new PhArmOperation(
- Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
+ Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(),
v => new VirtualMachine(this, new VirtualMachineData(v)));
}
@@ -318,7 +318,7 @@ public async Task