Skip to content

Commit 910d7db

Browse files
committed
Merge pull request #562 from chadiel/dev
Makes the ARM cmdlets even more generic
2 parents fa229bb + 1559dc7 commit 910d7db

13 files changed

+128
-22
lines changed

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/LongRunningOperationHelper.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ internal LongRunningOperationHelper(string activityName, Func<ResourceManagerRes
7676
/// Waits for the operation to complete.
7777
/// </summary>
7878
/// <param name="operationResult">The operation result.</param>
79-
internal JToken WaitOnOperation(OperationResult operationResult)
79+
internal string WaitOnOperation(OperationResult operationResult)
8080
{
8181
// TODO: Re-factor this mess.
8282
this.ProgressTrackerObject.UpdateProgress("Starting", 0);
8383

8484
var trackingResult = this.HandleOperationResponse(operationResult, this.IsResourceCreateOrUpdate ? operationResult.OperationUri : operationResult.LocationUri);
8585

86-
while (trackingResult.ShouldWait)
86+
while (trackingResult != null && trackingResult.ShouldWait)
8787
{
8888
operationResult =
8989
this.GetResourcesClient()
@@ -161,10 +161,11 @@ private TrackingOperationResult HandleOperationResponse(OperationResult operatio
161161
/// <param name="operationResult">The result of the operation.</param>
162162
private TrackingOperationResult HandleCreateOrUpdateResponse(OperationResult operationResult)
163163
{
164-
var resource = operationResult.Value == null
165-
? null
166-
: operationResult.Value
167-
.ToObject<Resource<InsensitiveDictionary<JToken>>>(JsonExtensions.JsonObjectTypeSerializer);
164+
Resource<InsensitiveDictionary<JToken>> resource;
165+
if (!operationResult.Value.TryConvertTo<Resource<InsensitiveDictionary<JToken>>>(out resource))
166+
{
167+
return null;
168+
}
168169

169170
if(resource == null && operationResult.HttpStatusCode == HttpStatusCode.Created)
170171
{
@@ -444,11 +445,12 @@ private string GetAzureAsyncOperationState(OperationResult operationResult)
444445
/// <param name="operationResult">The operation result.</param>
445446
private static string GetResourceState(OperationResult operationResult)
446447
{
447-
var resource = operationResult.Value == null
448-
? null
449-
: operationResult.Value
450-
.ToObject<Resource<InsensitiveDictionary<JToken>>>(JsonExtensions.JsonObjectTypeSerializer);
451-
448+
Resource<InsensitiveDictionary<JToken>> resource;
449+
if (!operationResult.Value.TryConvertTo<Resource<InsensitiveDictionary<JToken>>>(out resource))
450+
{
451+
return null;
452+
}
453+
452454
if (resource == null)
453455
{
454456
return null;

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/OperationResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ public class OperationResult
5656
/// <summary>
5757
/// Gets or sets the value.
5858
/// </summary>
59-
public JObject Value { get; set; }
59+
public string Value { get; set; }
6060
}
6161
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/ResourceIdUtility.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static string GetResourceId(string resourceId, string extensionResourceTy
4040
resourceIdBuilder.Append(ResourceIdUtility.ProcessResourceTypeAndName(resourceType: extensionResourceType, resourceName: extensionResourceName));
4141
}
4242

43-
return resourceId.ToString();
43+
return resourceIdBuilder.ToString();
4444
}
4545

4646
/// <summary>

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Extensions/ErrorResponseMessageExceptionExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions
1616
{
17+
using System;
1718
using System.Management.Automation;
1819
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.ErrorResponses;
1920

@@ -31,5 +32,25 @@ internal static ErrorRecord ToErrorRecord(this ErrorResponseMessageException exc
3132
// TODO: Improve this.
3233
return new ErrorRecord(exception, exception.ErrorResponseMessage == null ? exception.HttpStatus.ToString() : exception.ErrorResponseMessage.Error.Code, ErrorCategory.CloseError, null);
3334
}
35+
36+
/// <summary>
37+
/// Converts <see cref="Exception"/> objects into <see cref="ErrorRecord"/>
38+
/// </summary>
39+
/// <param name="exception">The exception</param>
40+
internal static ErrorRecord ToErrorRecord(this Exception exception)
41+
{
42+
// TODO: Improve this.
43+
return new ErrorRecord(exception, exception.Message, ErrorCategory.CloseError, null);
44+
}
45+
46+
/// <summary>
47+
/// Converts <see cref="AggregateException"/> objects into <see cref="ErrorRecord"/>
48+
/// </summary>
49+
/// <param name="exception">The exception</param>
50+
internal static ErrorRecord ToErrorRecord(this AggregateException aggregateException)
51+
{
52+
// TODO: Improve this.
53+
return new ErrorRecord(aggregateException, aggregateException.ToString(), ErrorCategory.CloseError, null);
54+
}
3455
}
3556
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Extensions/HttpMessageExtensions.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,35 @@ public static async Task<T> ReadContentAsJsonAsync<T>(this HttpResponseMessage m
5050
}
5151
}
5252
}
53+
54+
/// <summary>
55+
/// Reads the JSON content from the http response message.
56+
/// </summary>
57+
/// <typeparam name="T">The type of object contained in the JSON.</typeparam>
58+
/// <param name="message">The response message to be read.</param>
59+
/// <param name="rewindContentStream">Rewind content stream if set to true.</param>
60+
/// <returns>An object of type T instantiated from the response message's body.</returns>
61+
public static async Task<string> ReadContentAsStringAsync(this HttpResponseMessage message, bool rewindContentStream = false)
62+
{
63+
using (var stream = await message.Content
64+
.ReadAsStreamAsync()
65+
.ConfigureAwait(continueOnCapturedContext: false))
66+
using (var streamReader = new StreamReader(stream))
67+
{
68+
var streamPosition = stream.Position;
69+
try
70+
{
71+
72+
return streamReader.ReadToEnd();
73+
}
74+
finally
75+
{
76+
if (stream.CanSeek && streamPosition != stream.Position && rewindContentStream)
77+
{
78+
stream.Seek(streamPosition, SeekOrigin.Begin);
79+
}
80+
}
81+
}
82+
}
5383
}
5484
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Extensions/JsonExtensions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,39 @@ public static bool CanConvertTo<TType>(this JToken jobject)
147147
return jobject.TryConvertTo(out ignored);
148148
}
149149

150+
/// <summary>
151+
/// Checks if a conversion from the supplied <see cref="JToken"/> to a <typeparamref name="TType"/> can be made.
152+
/// </summary>
153+
/// <typeparam name="TType">The type to convert to.</typeparam>
154+
/// <param name="str">The string.</param>
155+
/// <param name="result">The result.</param>
156+
public static bool TryConvertTo<TType>(this string str, out TType result)
157+
{
158+
if (string.IsNullOrWhiteSpace(str))
159+
{
160+
result = default(TType);
161+
return true;
162+
}
163+
164+
try
165+
{
166+
result = str.FromJson<TType>();
167+
return !object.Equals(result, default(TType));
168+
}
169+
catch (FormatException)
170+
{
171+
}
172+
catch (ArgumentException)
173+
{
174+
}
175+
catch (JsonException)
176+
{
177+
}
178+
179+
result = default(TType);
180+
return false;
181+
}
182+
150183
/// <summary>
151184
/// Checks if a conversion from the supplied <see cref="JToken"/> to a <typeparamref name="TType"/> can be made.
152185
/// </summary>

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/InvokeAzureResourceActionCmdlet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ protected override void OnProcessRecord()
8080
odataQuery: this.ODataQuery);
8181

8282
var activity = string.Format("POST {0}", managementUri.PathAndQuery);
83-
var result = this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: false)
83+
var resultString = this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: false)
8484
.WaitOnOperation(operationResult: operationResult);
8585

86-
this.WriteObject(result, ResourceObjectFormat.New);
86+
this.TryConvertAndWriteObject(resultString, ResourceObjectFormat.New);
8787
});
8888
}
8989

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/MoveAzureResourceCmdlet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ private void RunCmdlet()
173173
isResourceCreateOrUpdate: false)
174174
.WaitOnOperation(operationResult: operationResult);
175175

176-
this.WriteObject(result, ResourceObjectFormat.New);
176+
this.TryConvertAndWriteObject(result, ResourceObjectFormat.New);
177177
}
178178
else
179179
{

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/NewAzureResourceCmdlet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ protected override void OnProcessRecord()
129129
var result = this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: true)
130130
.WaitOnOperation(operationResult: operationResult);
131131

132-
this.WriteObject(result.ToResource().ToPsObject(this.OutputObjectFormat.Value));
132+
this.TryConvertAndWriteObject(result, this.OutputObjectFormat.Value);
133133
});
134134
}
135135

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/RemoveAzureResourceCmdlet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ protected override void OnProcessRecord()
5858

5959
var activity = string.Format("DELETE {0}", managementUri.PathAndQuery);
6060

61-
var result = this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: false)
61+
this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: false)
6262
.WaitOnOperation(operationResult: operationResult);
6363

6464
this.WriteObject(true);

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/ResourceManagerCmdletBase.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,24 @@ public ResourceManagerRestRestClient GetResourcesClient()
259259
headerValues: AzureSession.ClientFactory.UserAgents));
260260
}
261261

262+
/// <summary>
263+
/// Writes the object
264+
/// </summary>
265+
/// <param name="resultString">The result as a string</param>
266+
/// <param name="objectFormat">The <see cref="ResourceObjectFormat"/></param>
267+
protected void TryConvertAndWriteObject(string resultString, ResourceObjectFormat objectFormat)
268+
{
269+
JToken resultJToken;
270+
if (resultString.TryConvertTo<JToken>(out resultJToken))
271+
{
272+
this.WriteObject(resultJToken, objectFormat);
273+
}
274+
else
275+
{
276+
this.WriteObject(resultString);
277+
}
278+
}
279+
262280
/// <summary>
263281
/// Writes a <see cref="JToken"/> object as a <see cref="PSObject"/>.
264282
/// </summary>
@@ -326,10 +344,12 @@ private void HandleException(ExceptionDispatchInfo capturedException)
326344
{
327345
this.ThrowTerminatingError(errorResponseException.ToErrorRecord());
328346
}
347+
348+
this.ThrowTerminatingError(aggregateException.InnerExceptions.Single().ToErrorRecord());
329349
}
330350
else
331351
{
332-
throw aggregateException.Flatten();
352+
this.ThrowTerminatingError(aggregateException.ToErrorRecord());
333353
}
334354
}
335355

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/SetAzureResourceCmdlet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ protected override void OnProcessRecord()
123123
var activity = string.Format("{0} {1}", this.ShouldUsePatchSemantics() ? "PATCH" : "PUT", managementUri.PathAndQuery);
124124
var result = this.GetLongRunningOperationTracker(activityName: activity, isResourceCreateOrUpdate: true)
125125
.WaitOnOperation(operationResult: operationResult);
126-
127-
this.WriteObject(result.ToResource().ToPsObject(this.OutputObjectFormat.Value));
126+
127+
this.TryConvertAndWriteObject(result, this.OutputObjectFormat.Value);
128128
});
129129
}
130130

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/RestClients/ResourceManagerRestClientBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ private async Task<OperationResult> GetOperationResult(HttpResponseMessage respo
293293
var operationResult = new OperationResult
294294
{
295295
Value = await response
296-
.ReadContentAsJsonAsync<JObject>()
296+
.ReadContentAsStringAsync()
297297
.ConfigureAwait(continueOnCapturedContext: false),
298298
};
299299

0 commit comments

Comments
 (0)