Skip to content

Proper Success Response Handling #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 15, 2020
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

namespace Microsoft.Graph.PowerShell
{
using System.Management.Automation;
public static class PSCmdletExtensions
{
/// <summary>
/// Overrides OnDefault method in the generated cmdlets.
/// </summary>
/// <param name="cmdlet">The calling <see cref="PSCmdlet"/></param>
/// <param name="responseMessage">The HTTP response message from the service.</param>
/// <param name="returnNow">Determines whether the caller should return after OverrideOnDefault is called, or not. </param>
public static void OverrideOnDefault(this PSCmdlet cmdlet, global::System.Net.Http.HttpResponseMessage responseMessage, ref global::System.Threading.Tasks.Task<bool> returnNow)
{
if (responseMessage.IsSuccessStatusCode)
{
if (cmdlet.MyInvocation?.BoundParameters?.ContainsKey("PassThru") == true)
{
cmdlet.WriteObject(true);
}
returnNow = global::System.Threading.Tasks.Task<bool>.FromResult(true);
}
}
}
}
24 changes: 19 additions & 5 deletions src/readme.graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ directive:
- where:
parameter-name: Top
set:
parameter-name: PageSize
alias:
- Top
- Limit
- where:
parameter-name: Select
Expand Down Expand Up @@ -380,22 +378,38 @@ directive:
}
return $;
}
# Add custom -All parameter to *_List cmdlets that support Odata next link.
# Override OnDefault to handle all success, 2xx responses, as success and not error.
- from: source-file-csharp
where: $
transform: >
if (!$documentPath.match(/generated%2Fcmdlets%2FGet\w*_List.cs/gm))
if (!$documentPath.match(/generated%2Fcmdlets%2F\w*.cs/gm))
{
return $;
} else {
let overrideOnDefaultRegex = /(\s*)(partial\s*void\s*overrideOnDefault)/gmi
let overrideOnDefaultImplementation = "$1partial void overrideOnDefault(global::System.Net.Http.HttpResponseMessage responseMessage, global::System.Threading.Tasks.Task<Microsoft.Graph.PowerShell.Models.IOdataError> response, ref global::System.Threading.Tasks.Task<bool> returnNow) => this.OverrideOnDefault(responseMessage,ref returnNow);$1$2"
$ = $.replace(overrideOnDefaultRegex, overrideOnDefaultImplementation);

return $;
}

# Add custom -PageSize parameter to *_List cmdlets that support Odata next link.
- from: source-file-csharp
where: $
transform: >
if (!$documentPath.match(/generated%2Fcmdlets%2FGet\w*_List\d*.cs/gm))
{
return $;
} else {
let odataNextLinkRegex = /(^\s*)(if\s*\(\s*result.OdataNextLink\s*!=\s*null\s*\))/gmi
if($.match(odataNextLinkRegex)) {
$ = $.replace(odataNextLinkRegex, '$1if (result.OdataNextLink != null && this.ShouldIteratePages(this.InvocationInformation.BoundParameters, result.Value.Length))\n$1');

let psBaseClassImplementationRegex = /(\s*:\s*)(global::System.Management.Automation.PSCmdlet)/gmi
$ = $.replace(psBaseClassImplementationRegex, '$1Microsoft.Graph.PowerShell.Cmdlets.Custom.ListCmdlet');

let beginProcessingRegex = /(^\s*)(protected\s*override\s*void\s*BeginProcessing\(\)\s*{)/gmi
$ = $.replace(beginProcessingRegex, '$1$2\n$1$1if (this.InvocationInformation.BoundParameters.ContainsKey("PageSize")){ InitializePaging(ref this.__invocationInfo, ref this._pageSize); }\n$1');
$ = $.replace(beginProcessingRegex, '$1$2\n$1 if (this.InvocationInformation?.BoundParameters != null){ InitializePaging(ref this.__invocationInfo, ref this._top); }\n$1');

let odataNextLinkCallRegex = /(^\s*)(await\s*this\.Client\.UsersUserListUser_Call\(requestMessage\,\s*onOk\,\s*onDefault\,\s*this\,\s*Pipeline\)\;)/gmi
$ = $.replace(odataNextLinkCallRegex, '$1requestMessage.RequestUri = GetOverflowItemsNextLinkUri(requestMessage.RequestUri);\n$1$2');
Expand Down
70 changes: 42 additions & 28 deletions tools/Custom/ListCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
// ------------------------------------------------------------------------------
namespace Microsoft.Graph.PowerShell.Cmdlets.Custom
{
using System;
using System.Management.Automation;

public partial class ListCmdlet : global::System.Management.Automation.PSCmdlet
{
/// <summary>Backing field for <see cref="All" /> property.</summary>
private global::System.Management.Automation.SwitchParameter _all;

/// <summary>List All pages</summary>
[global::System.Management.Automation.Parameter(Mandatory = false, HelpMessage = "List all pages")]
/// <summary>Backing field for <see cref="PageSize" /> property.</summary>
private int _pageSize;
/// <summary>Sets the page size of results.</summary>
[global::System.Management.Automation.Parameter(Mandatory = false, HelpMessage = "Sets the page size of results.")]
[Microsoft.Graph.PowerShell.Runtime.Info(
Required = false,
ReadOnly = false,
Description = @"List all pages",
SerializedName = @"$all",
Description = @"The page size of results.",
PossibleTypes = new[] { typeof(global::System.Management.Automation.SwitchParameter) })]
[global::Microsoft.Graph.PowerShell.Category(global::Microsoft.Graph.PowerShell.ParameterCategory.Runtime)]
public global::System.Management.Automation.SwitchParameter All { get => this._all; set => this._all = value; }
public int PageSize { get => this._pageSize; set => this._pageSize = value; }

/// <summary>
/// Default number of items per page.
Expand All @@ -30,11 +31,6 @@ public partial class ListCmdlet : global::System.Management.Automation.PSCmdlet
/// </summary>
internal const int MaxPageSize = 999;

/// <summary>
/// Original page size/top/limit passed to Cmdlet via parameter.
/// </summary>
internal int originalPageSize = 0;

/// <summary>
/// Total number of pages required to iterate page collections excluding overflow items.
/// </summary>
Expand All @@ -56,26 +52,47 @@ public partial class ListCmdlet : global::System.Management.Automation.PSCmdlet
/// </summary>
internal int totalFetchedItems = 0;

/// <summary>
/// Total number of items to be fetched.
/// </summary>
internal int limit = default;

/// <summary>
/// Initializes paging values.
/// </summary>
/// <param name="invocationInfo">A reference to <see cref="System.Management.Automation.InvocationInfo"/> object.</param>
/// <param name="PageSize">A reference to page size parameter.</param>
public void InitializePaging(ref global::System.Management.Automation.InvocationInfo invocationInfo, ref int PageSize)
/// <param name="top">A reference to top parameter.</param>
public void InitializePaging(ref global::System.Management.Automation.InvocationInfo invocationInfo, ref int top)
{
if (PageSize > MaxPageSize)
if (invocationInfo.BoundParameters.ContainsKey("PageSize") && (PageSize > MaxPageSize || PageSize == default))
{
invocationInfo.BoundParameters["All"] = true;
originalPageSize = PageSize;
requiredPages = PageSize / DefaultPageSize;
overflowItemsCount = PageSize % DefaultPageSize;
invocationInfo.BoundParameters["PageSize"] = DefaultPageSize;
PageSize = DefaultPageSize;
ThrowTerminatingError(
new ErrorRecord(
new ArgumentException($"Invalid page size specified `{PageSize}`. {nameof(PageSize)} must be between 1 and {MaxPageSize} inclusive."),
Guid.NewGuid().ToString(),
ErrorCategory.InvalidArgument,
null));
}

// Move `-Top` parameter to `limit` parameter.
if (invocationInfo.BoundParameters.ContainsKey("Top"))
{
limit = top;
}

// Explicitly set `-PageSize` as our $top parameter.
invocationInfo.BoundParameters["Top"] = invocationInfo.BoundParameters.ContainsKey("PageSize") ? PageSize : DefaultPageSize;
top = (int)invocationInfo.BoundParameters["Top"];

if (limit != default)
{
requiredPages = limit / top;
overflowItemsCount = limit % top;
}
}

/// <summary>
/// Determines whether the cmdlet should follow the OData next link url.
/// Determines whether the cmdlet should follow the OData next link URI.
/// </summary>
/// <param name="boundParameters">The bound parameters of the cmdlet.</param>
/// <param name="itemsCount">Current page items count.</param>
Expand All @@ -84,11 +101,8 @@ public bool ShouldIteratePages(global::System.Collections.Generic.Dictionary<str
{
iteratedPages++;
totalFetchedItems += itemsCount;
if ((boundParameters.ContainsKey("All") && !boundParameters.ContainsKey("PageSize")) ||
(boundParameters.ContainsKey("PageSize") && totalFetchedItems < originalPageSize))
return true;
else
return false;

return limit == default || totalFetchedItems < limit;
}

/// <summary>
Expand Down