Skip to content

Commit 1fad4e4

Browse files
author
Hovsep
committed
Merge pull request #2298 from wastoresh/dev
RDBug 6413346:[PSH] Get-AzureStorageAccount failed with TooManyRequests when there are 85+ accounts in a subscription
2 parents 9e54c8c + 3260d8f commit 1fad4e4

File tree

5 files changed

+129
-46
lines changed

5 files changed

+129
-46
lines changed

src/Common/Commands.Common.Storage/AzureStorageContext.cs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,42 @@ public class AzureStorageContext
2828
/// <summary>
2929
/// Storage account name used in this context
3030
/// </summary>
31-
public string StorageAccountName { get; private set; }
31+
public string StorageAccountName { get; protected set; }
3232

3333
/// <summary>
3434
/// Blob end point of the storage context
3535
/// </summary>
36-
public string BlobEndPoint { get; private set; }
36+
public virtual string BlobEndPoint { get; protected set; }
3737

3838
/// <summary>
3939
/// Table end point of the storage context
4040
/// </summary>
41-
public string TableEndPoint { get; private set; }
41+
public virtual string TableEndPoint { get; protected set; }
4242

4343
/// <summary>
4444
/// Queue end point of the storage context
4545
/// </summary>
46-
public string QueueEndPoint { get; private set; }
46+
public virtual string QueueEndPoint { get; protected set; }
47+
48+
/// <summary>
49+
/// File end point of the storage context
50+
/// </summary>
51+
public virtual string FileEndPoint { get; protected set; }
4752

4853
/// <summary>
4954
/// Self reference, it could enable New-AzureStorageContext can be used in pipeline
5055
/// </summary>
51-
public AzureStorageContext Context { get; private set; }
56+
public AzureStorageContext Context { get; protected set; }
5257

5358
/// <summary>
5459
/// Name place holder, and force pipeline to ignore this property
5560
/// </summary>
56-
public string Name { get; private set; }
61+
public virtual string Name { get; protected set; }
5762

5863
/// <summary>
5964
/// Storage account in context
6065
/// </summary>
61-
public CloudStorageAccount StorageAccount { get; private set; }
66+
public virtual CloudStorageAccount StorageAccount { get; protected set; }
6267

6368
/// <summary>
6469
/// Endpoint suffix (everything after "table.", "blob." or "queue.")
@@ -70,41 +75,31 @@ public string EndPointSuffix
7075
{
7176
get
7277
{
73-
if (string.IsNullOrEmpty(BlobEndPoint) || string.IsNullOrEmpty(TableEndPoint))
78+
if (!string.IsNullOrEmpty(BlobEndPoint))
7479
{
75-
return string.Empty;
80+
string blobSpliter = "blob.";
81+
if (BlobEndPoint.LastIndexOf(blobSpliter) >= 0)
82+
return BlobEndPoint.Substring(BlobEndPoint.LastIndexOf(blobSpliter) + blobSpliter.Length);
7683
}
77-
78-
string suffix;
79-
80-
if (StorageAccountName.EndsWith("blob", StringComparison.InvariantCultureIgnoreCase))
84+
if (!string.IsNullOrEmpty(TableEndPoint))
8185
{
82-
// Cannot use the blob endpoint if the account name ends with blob...
83-
// However it is OK if "blob" is in the account name but not as a suffix
84-
int tableIndex = TableEndPoint.IndexOf("table.", 0, StringComparison.InvariantCultureIgnoreCase);
85-
if (tableIndex <= 0)
86-
{
87-
suffix = string.Empty;
88-
}
89-
else
90-
{
91-
suffix = TableEndPoint.Substring(tableIndex + "table.".Length);
92-
}
86+
string tableSpliter = "table.";
87+
if (TableEndPoint.LastIndexOf(tableSpliter) >= 0)
88+
return TableEndPoint.Substring(TableEndPoint.LastIndexOf(tableSpliter) + tableSpliter.Length);
9389
}
94-
else
90+
if (!string.IsNullOrEmpty(QueueEndPoint))
9591
{
96-
int blobIndex = BlobEndPoint.IndexOf("blob.", 0, StringComparison.InvariantCultureIgnoreCase);
97-
if (blobIndex <= 0)
98-
{
99-
suffix = string.Empty;
100-
}
101-
else
102-
{
103-
suffix = BlobEndPoint.Substring(blobIndex + "blob.".Length);
104-
}
92+
string queueSpliter = "queue.";
93+
if (QueueEndPoint.LastIndexOf(queueSpliter) >= 0)
94+
return QueueEndPoint.Substring(QueueEndPoint.LastIndexOf(queueSpliter) + queueSpliter.Length);
10595
}
106-
107-
return suffix;
96+
if (!string.IsNullOrEmpty(FileEndPoint))
97+
{
98+
string fileSpliter = "file.";
99+
if (FileEndPoint.LastIndexOf(fileSpliter) >= 0)
100+
return FileEndPoint.Substring(FileEndPoint.LastIndexOf(fileSpliter) + fileSpliter.Length);
101+
}
102+
return string.Empty;
108103
}
109104
}
110105

@@ -131,6 +126,11 @@ public AzureStorageContext(CloudStorageAccount account)
131126
QueueEndPoint = account.QueueEndpoint.ToString();
132127
}
133128

129+
if (account.FileEndpoint != null)
130+
{
131+
FileEndPoint = account.FileEndpoint.ToString();
132+
}
133+
134134
StorageAccountName = account.Credentials.AccountName;
135135
Context = this;
136136
Name = String.Empty;
@@ -152,7 +152,7 @@ public AzureStorageContext(CloudStorageAccount account)
152152
/// Proivides a private constructor for building empty instance which
153153
/// contains no account information.
154154
/// </summary>
155-
private AzureStorageContext()
155+
protected AzureStorageContext()
156156
{
157157
}
158158

src/Common/Commands.Common.Storage/Commands.Common.Storage.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
<Reference Include="System.Xml" />
155155
</ItemGroup>
156156
<ItemGroup>
157+
<Compile Include="LazyAzureStorageContext.cs" />
157158
<Compile Include="AzureStorageContext.cs" />
158159
<Compile Include="BlobUploadParameters.cs" />
159160
<Compile Include="IStorageClientWrapper.cs" />
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using Microsoft.WindowsAzure.Storage;
17+
18+
namespace Microsoft.WindowsAzure.Commands.Common.Storage
19+
{
20+
public class LazyAzureStorageContext : AzureStorageContext
21+
{
22+
Func<string, CloudStorageAccount> _factory;
23+
CloudStorageAccount _account = null;
24+
public LazyAzureStorageContext(Func<string, CloudStorageAccount> accountFactory, string accountName)
25+
{
26+
_factory = accountFactory;
27+
Name = accountName;
28+
Context = this;
29+
StorageAccountName = accountName;
30+
}
31+
32+
public override string BlobEndPoint
33+
{
34+
get
35+
{
36+
return StorageAccount.BlobEndpoint.ToString();
37+
}
38+
}
39+
public override string TableEndPoint
40+
{
41+
get
42+
{
43+
return StorageAccount.TableEndpoint.ToString();
44+
}
45+
}
46+
47+
public override string QueueEndPoint
48+
{
49+
get
50+
{
51+
return StorageAccount.QueueEndpoint.ToString();
52+
}
53+
}
54+
55+
public override string FileEndPoint
56+
{
57+
get
58+
{
59+
return StorageAccount.FileEndpoint.ToString();
60+
}
61+
}
62+
63+
public override CloudStorageAccount StorageAccount
64+
{
65+
get
66+
{
67+
if (_account == null)
68+
{
69+
_account = _factory(StorageAccountName);
70+
}
71+
72+
return _account;
73+
}
74+
}
75+
}
76+
}
77+

src/ResourceManager/Storage/Commands.Management.Storage/Models/PSStorageAccount.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,16 @@ public PSStorageAccount(StorageModels.StorageAccount storageAccount)
8585
public static PSStorageAccount Create(StorageModels.StorageAccount storageAccount, IStorageManagementClient client)
8686
{
8787
var result = new PSStorageAccount(storageAccount);
88-
var credentials = StorageUtilities.GenerateStorageCredentials(new ARMStorageProvider(client), result.ResourceGroupName, result.StorageAccountName);
89-
CloudStorageAccount account = new CloudStorageAccount(credentials,
90-
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Blob),
91-
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Queue),
92-
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Table),
93-
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.File));
94-
result.Context = new AzureStorageContext(account);
88+
result.Context = new LazyAzureStorageContext((s) =>
89+
{
90+
var credentials = StorageUtilities.GenerateStorageCredentials(new ARMStorageProvider(client), result.ResourceGroupName, s);
91+
return new CloudStorageAccount(credentials,
92+
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Blob),
93+
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Queue),
94+
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.Table),
95+
ARMStorageService.GetUri(storageAccount.PrimaryEndpoints.File));
96+
}, result.StorageAccountName) as AzureStorageContext;
97+
9598
return result;
9699
}
97100

src/ServiceManagement/Compute/Commands.ServiceManagement/Model/PSStorageService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ protected PSStorageService(StorageServicePropertiesOperationContext account, Azu
6666
public static PSStorageService Create(StorageManagementClient client,
6767
StorageServicePropertiesOperationContext account)
6868
{
69-
var cloudStorageAccount = StorageUtilities.GenerateCloudStorageAccount(client, account.StorageAccountName);
70-
return new PSStorageService(account, new AzureStorageContext(cloudStorageAccount));
69+
return new PSStorageService(account, new LazyAzureStorageContext((s) =>
70+
{
71+
return StorageUtilities.GenerateCloudStorageAccount(client, account.StorageAccountName);
72+
}, account.StorageAccountName) as AzureStorageContext);
7173
}
7274

7375
/// <summary>

0 commit comments

Comments
 (0)