Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit 7a8f321

Browse files
authored
Add New-ServiceClient utility function in generated module to enable mock testing (#325)
* Add Get-ServiceClient utility function in generated module to enable mock testing. Resolves #298 * Added documentation * Updated New-ServiceClient uility to set ServiceCredentials, SubscriptionId, BaseUri, HttpClientHandler and global parameter properties on the service client object.
1 parent 37d8618 commit 7a8f321

File tree

8 files changed

+227
-89
lines changed

8 files changed

+227
-89
lines changed

PSSwagger/GeneratedHelpers.ps1

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ function Get-AzSubscriptionId
5050
param()
5151

5252
$AzureContext = & "Get-AzureRmContext" -ErrorAction Stop
53-
if(Get-Member -InputObject $AzureContext.Subscription -Name SubscriptionId)
53+
if($AzureContext)
5454
{
55-
return $AzureContext.Subscription.SubscriptionId
56-
}
57-
else
58-
{
59-
return $AzureContext.Subscription.Id
55+
if(Get-Member -InputObject $AzureContext.Subscription -Name SubscriptionId)
56+
{
57+
return $AzureContext.Subscription.SubscriptionId
58+
}
59+
else
60+
{
61+
return $AzureContext.Subscription.Id
62+
}
6063
}
6164
}
6265

PSSwagger/New-ServiceClient.ps1

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Microsoft.PowerShell.Core\Set-StrictMode -Version Latest
2+
3+
<#
4+
.DESCRIPTION
5+
Creates Service Client object.
6+
7+
.PARAMETER FullClientTypeName
8+
Client type full name.
9+
10+
.PARAMETER AddHttpClientHandler
11+
Switch to determine whether the client type constructor expects the HttpClientHandler object.
12+
13+
.PARAMETER Credential
14+
Credential is required for for creating the HttpClientHandler object.
15+
16+
.PARAMETER AuthenticationCommand
17+
Command that should return a Microsoft.Rest.ServiceClientCredentials object that implements custom authentication logic.
18+
19+
.PARAMETER AuthenticationCommandArgumentList
20+
Arguments to the AuthenticationCommand, if any.
21+
22+
.PARAMETER HostOverrideCommand
23+
Command should return a custom hostname string.
24+
Overrides the default host in the specification.
25+
26+
.PARAMETER SubscriptionIdCommand
27+
Custom command get SubscriptionId value.
28+
29+
.PARAMETER GlobalParameterHashtable
30+
Global parameters to be set on client object.
31+
#>
32+
function New-ServiceClient {
33+
[CmdletBinding()]
34+
param(
35+
[Parameter(Mandatory = $true)]
36+
[string]
37+
$FullClientTypeName,
38+
39+
[Parameter(Mandatory = $false)]
40+
[switch]
41+
$AddHttpClientHandler,
42+
43+
[Parameter(Mandatory = $false)]
44+
[pscredential]
45+
$Credential,
46+
47+
[Parameter(Mandatory = $true)]
48+
[string]
49+
$AuthenticationCommand,
50+
51+
[Parameter(Mandatory = $false)]
52+
[Object[]]
53+
$AuthenticationCommandArgumentList,
54+
55+
[Parameter(Mandatory = $false)]
56+
[string]
57+
$HostOverrideCommand,
58+
59+
[Parameter(Mandatory = $false)]
60+
[string]
61+
$SubscriptionIdCommand,
62+
63+
[Parameter(Mandatory = $false)]
64+
[PSCustomObject]
65+
$GlobalParameterHashtable
66+
)
67+
68+
$ClientArgumentList = @()
69+
$InvokeCommand_parameters = @{
70+
ScriptBlock = [scriptblock]::Create($AuthenticationCommand)
71+
}
72+
if ($AuthenticationCommandArgumentList) {
73+
$InvokeCommand_parameters['ArgumentList'] = $AuthenticationCommandArgumentList
74+
}
75+
$ClientArgumentList += Invoke-Command @InvokeCommand_parameters
76+
77+
if ($AddHttpClientHandler) {
78+
$httpClientHandler = New-HttpClientHandler -Credential $Credential
79+
$ClientArgumentList += $httpClientHandler
80+
}
81+
82+
$delegatingHandler = New-Object -TypeName System.Net.Http.DelegatingHandler[] -ArgumentList 0
83+
$ClientArgumentList += $delegatingHandler
84+
85+
$Client = New-Object -TypeName $FullClientTypeName -ArgumentList $ClientArgumentList
86+
87+
if ($HostOverrideCommand) {
88+
$Client.BaseUri = Invoke-Command -ScriptBlock [scriptblock]::Create($HostOverrideCommand)
89+
}
90+
91+
if ($GlobalParameterHashtable) {
92+
$GlobalParameterHashtable.GetEnumerator() | ForEach-Object {
93+
if (Get-Member -InputObject $Client -Name $_.Key -MemberType Property) {
94+
if ((-not $_.Value) -and ($_.Key -eq 'SubscriptionId')) {
95+
if($SubscriptionIdCommand) {
96+
$Client.SubscriptionId = Invoke-Command -ScriptBlock [scriptblock]::Create($SubscriptionIdCommand)
97+
}
98+
else {
99+
$Client.SubscriptionId = Get-AzSubscriptionId
100+
}
101+
}
102+
else {
103+
$Client."$($_.Key)" = $_.Value
104+
}
105+
}
106+
}
107+
}
108+
109+
return $Client
110+
}

PSSwagger/PSSwagger.Constants.ps1

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ $DynamicAssemblyGenerationCode
5353
`$allDllsPath = Join-Path -Path `$ClrPath -ChildPath '*.dll'
5454
Get-ChildItem -Path `$allDllsPath -File | ForEach-Object { Add-Type -Path `$_.FullName -ErrorAction SilentlyContinue }
5555
56+
. (Join-Path -Path `$PSScriptRoot -ChildPath 'New-ServiceClient.ps1')
5657
. (Join-Path -Path `$PSScriptRoot -ChildPath 'GeneratedHelpers.ps1')
5758
5859
`$allPs1FilesPath = Join-Path -Path `$PSScriptRoot -ChildPath '$GeneratedCommandsName' | Join-Path -ChildPath '*.ps1'
@@ -157,11 +158,49 @@ $constructFlattenedParameter = @'
157158
$functionBodyStr = @'
158159
159160
`$ErrorActionPreference = 'Stop'
160-
$securityBlock
161161
162-
$clientName = New-Object -TypeName $FullClientTypeName -ArgumentList $clientArgumentList$apiVersion
163-
$overrideBaseUriBlock
164-
$GlobalParameterBlock
162+
`$NewServiceClient_params = @{
163+
FullClientTypeName = '$FullClientTypeName'
164+
}
165+
$(
166+
if($AuthenticationCommand){
167+
"
168+
`$NewServiceClient_params['AuthenticationCommand'] = @'
169+
$AuthenticationCommand
170+
`'@ "
171+
if($AuthenticationCommandArgumentName){
172+
"
173+
`$NewServiceClient_params['AuthenticationCommandArgumentList'] = `$$AuthenticationCommandArgumentName"
174+
}
175+
}
176+
if($AddHttpClientHandler){
177+
"
178+
`$NewServiceClient_params['AddHttpClientHandler'] = `$true
179+
`$NewServiceClient_params['Credential'] = `$Credential"
180+
}
181+
if($hostOverrideCommand){
182+
"
183+
`$NewServiceClient_params['HostOverrideCommand'] = @'
184+
$hostOverrideCommand
185+
`'@"
186+
}
187+
if($GlobalParameters) {
188+
'
189+
$GlobalParameterHashtable = @{} '
190+
191+
foreach($parameter in $GlobalParameters) {
192+
"
193+
`$GlobalParameterHashtable['$parameter'] = `$null
194+
if(`$PSBoundParameters.ContainsKey('$parameter')) {
195+
`$GlobalParameterHashtable['$parameter'] = `$PSBoundParameters['$parameter']
196+
}
197+
"
198+
}
199+
"
200+
`$NewServiceClient_params['GlobalParameterHashtable'] = `$GlobalParameterHashtable "
201+
}
202+
)
203+
$clientName = New-ServiceClient @NewServiceClient_params
165204
$oDataExpressionBlock
166205
$parameterGroupsExpressionBlock
167206
$flattenedParametersBlock
@@ -174,16 +213,6 @@ $functionBodyStr = @'
174213
}
175214
'@
176215

177-
$clientArgumentListNoHandler = "`$serviceCredentials,`$delegatingHandler"
178-
$clientArgumentListHttpClientHandler = "`$serviceCredentials,`$httpClientHandler,`$delegatingHandler"
179-
180-
$securityBlockStr = @'
181-
`$serviceCredentials = $authFunctionCall
182-
$azSubscriptionIdBlock
183-
$httpClientHandlerCall
184-
`$delegatingHandler = New-Object -TypeName System.Net.Http.DelegatingHandler[] 0
185-
'@
186-
187216
$parameterSetBasedMethodStrIfCase = @'
188217
if ('$operationId' -eq `$PsCmdlet.ParameterSetName) {
189218
$additionalConditionStart$methodBlock$additionalConditionEnd
@@ -428,23 +457,6 @@ $createObjectStr = @'
428457
return `$Object
429458
'@
430459

431-
$ApiVersionStr = @'
432-
433-
if(Get-Member -InputObject $clientName -Name 'ApiVersion' -MemberType Property)
434-
{
435-
$clientName.ApiVersion = "$infoVersion"
436-
}
437-
'@
438-
439-
$GlobalParameterBlockStr = @'
440-
if(Get-Member -InputObject `$clientName -Name '$globalParameterName' -MemberType Property)
441-
{
442-
`$clientName.$globalParameterName = $globalParameterValue
443-
}
444-
'@
445-
446-
$HostOverrideBlock = '`$ResourceManagerUrl = $hostOverrideCommand`n $clientName.BaseUri = `$ResourceManagerUrl'
447-
448460
$GeneratedCommandsName = 'Generated.PowerShell.Commands'
449461

450462
$FormatViewDefinitionStr = @'

PSSwagger/PSSwagger.psm1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,10 @@ function New-PSSwaggerModule
612612
-PSHeaderComment $PSHeaderComment
613613

614614
$CopyFilesMap = [ordered]@{
615-
'GeneratedHelpers.ps1' = 'GeneratedHelpers.ps1'
615+
'GeneratedHelpers.ps1' = 'GeneratedHelpers.ps1'
616616
'Test-CoreRequirements.ps1' = 'Test-CoreRequirements.ps1'
617617
'Test-FullRequirements.ps1' = 'Test-FullRequirements.ps1'
618+
'New-ServiceClient.ps1' = 'New-ServiceClient.ps1'
618619
}
619620

620621
if (-not $AssemblyFileName) {

PSSwagger/Paths.psm1

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ function New-SwaggerPath
425425
$parametersToAdd = @{}
426426
$flattenedParametersOnPSCmdlet = @{}
427427
$parameterHitCount = @{}
428-
$globalParameterBlock = ''
428+
$globalParameters = @()
429429
$x_ms_pageableObject = $null
430430
foreach ($parameterSetDetail in $parameterSetDetails) {
431431
if ($parameterSetDetail.ContainsKey('x-ms-pageable') -and $parameterSetDetail.'x-ms-pageable' -and (-not $isNextPageOperation)) {
@@ -505,7 +505,7 @@ function New-SwaggerPath
505505
$globalParameterValue = $parameterDetails.ConstantValue
506506
}
507507

508-
$globalParameterBlock += [Environment]::NewLine + $executionContext.InvokeCommand.ExpandString($GlobalParameterBlockStr)
508+
$globalParameters += $globalParameterName
509509
}
510510
}
511511

@@ -609,24 +609,24 @@ function New-SwaggerPath
609609
}
610610

611611
# Process security section
612-
$azSubscriptionIdBlock = ""
613-
$authFunctionCall = ""
614-
$overrideBaseUriBlock = ""
615-
$httpClientHandlerCall = ""
612+
$SubscriptionIdCommand = ""
613+
$AuthenticationCommand = ""
614+
$AuthenticationCommandArgumentName = ''
615+
$hostOverrideCommand = ''
616+
$AddHttpClientHandler = $false
616617
$securityParametersToAdd = @()
617618
$PowerShellCodeGen = $SwaggerMetaDict['PowerShellCodeGen']
618619
if (($PowerShellCodeGen['ServiceType'] -eq 'azure') -or ($PowerShellCodeGen['ServiceType'] -eq 'azure_stack')) {
619-
$azSubscriptionIdBlock = "`$subscriptionId = Get-AzSubscriptionId"
620+
$SubscriptionIdCommand = 'Get-AzSubscriptionId'
620621
}
621622
if ($PowerShellCodeGen['CustomAuthCommand']) {
622-
$authFunctionCall = $PowerShellCodeGen['CustomAuthCommand']
623+
$AuthenticationCommand = $PowerShellCodeGen['CustomAuthCommand']
623624
}
624625
if ($PowerShellCodeGen['HostOverrideCommand']) {
625626
$hostOverrideCommand = $PowerShellCodeGen['HostOverrideCommand']
626-
$overrideBaseUriBlock = $executionContext.InvokeCommand.ExpandString($HostOverrideBlock)
627627
}
628628
# If the auth function hasn't been set by metadata, try to discover it from the security and securityDefinition objects in the spec
629-
if (-not $authFunctionCall) {
629+
if (-not $AuthenticationCommand) {
630630
if ($FunctionDetails.ContainsKey('Security')) {
631631
# For now, just take the first security object
632632
if ($FunctionDetails.Security.Count -gt 1) {
@@ -674,11 +674,12 @@ function New-SwaggerPath
674674
}
675675
# If the service is specified to not issue authentication challenges, we can't rely on HttpClientHandler
676676
if ($PowerShellCodeGen['NoAuthChallenge'] -and ($PowerShellCodeGen['NoAuthChallenge'] -eq $true)) {
677-
$authFunctionCall = 'Get-AutoRestCredential -Credential $Credential'
677+
$AuthenticationCommand = 'param([pscredential]$Credential) Get-AutoRestCredential -Credential $Credential'
678+
$AuthenticationCommandArgumentName = 'Credential'
678679
} else {
679680
# Use an empty service client credentials object because we're using HttpClientHandler instead
680-
$authFunctionCall = 'Get-AutoRestCredential'
681-
$httpClientHandlerCall = '$httpClientHandler = New-HttpClientHandler -Credential $Credential'
681+
$AuthenticationCommand = 'Get-AutoRestCredential'
682+
$AddHttpClientHandler = $true
682683
}
683684
} elseif ($type -eq 'apiKey') {
684685
if (-not (Get-Member -InputObject $securityDefinition -Name 'name')) {
@@ -712,22 +713,18 @@ function New-SwaggerPath
712713
Parameter = $credentialParameter
713714
IsConflictingWithOperationParameter = $false
714715
}
715-
$authFunctionCall = "Get-AutoRestCredential -APIKey `$APIKey -Location '$in' -Name '$name'"
716+
$AuthenticationCommand = "param([string]`$APIKey) Get-AutoRestCredential -APIKey `$APIKey -Location '$in' -Name '$name'"
717+
$AuthenticationCommandArgumentName = 'APIKey'
716718
} else {
717719
Write-Warning -Message ($LocalizedData.UnsupportedAuthenticationType -f ($type))
718720
}
719721
}
720722
}
721723
}
722724

723-
if (-not $authFunctionCall) {
725+
if (-not $AuthenticationCommand) {
724726
# At this point, there was no supported security object or overridden auth function, so assume no auth
725-
$authFunctionCall = 'Get-AutoRestCredential'
726-
}
727-
728-
$clientArgumentList = $clientArgumentListNoHandler
729-
if ($httpClientHandlerCall) {
730-
$clientArgumentList = $clientArgumentListHttpClientHandler
727+
$AuthenticationCommand = 'Get-AutoRestCredential'
731728
}
732729

733730
$nonUniqueParameterSets = @()
@@ -961,18 +958,22 @@ function New-SwaggerPath
961958
}
962959

963960
$functionBodyParams = @{
964-
ParameterSetDetails = $parameterSetDetails
965-
ODataExpressionBlock = $oDataExpressionBlock
966-
ParameterGroupsExpressionBlock = $parameterGroupsExpressionBlock
967-
GlobalParameterBlock = $GlobalParameterBlock
968-
SwaggerDict = $SwaggerDict
969-
SwaggerMetaDict = $SwaggerMetaDict
970-
SecurityBlock = $executionContext.InvokeCommand.ExpandString($securityBlockStr)
971-
OverrideBaseUriBlock = $overrideBaseUriBlock
972-
ClientArgumentList = $clientArgumentList
973-
FlattenedParametersOnPSCmdlet = $flattenedParametersOnPSCmdlet
974-
}
975-
961+
ParameterSetDetails = $parameterSetDetails
962+
ODataExpressionBlock = $oDataExpressionBlock
963+
ParameterGroupsExpressionBlock = $parameterGroupsExpressionBlock
964+
SwaggerDict = $SwaggerDict
965+
SwaggerMetaDict = $SwaggerMetaDict
966+
AddHttpClientHandler = $AddHttpClientHandler
967+
HostOverrideCommand = $hostOverrideCommand
968+
AuthenticationCommand = $AuthenticationCommand
969+
AuthenticationCommandArgumentName = $AuthenticationCommandArgumentName
970+
SubscriptionIdCommand = $SubscriptionIdCommand
971+
FlattenedParametersOnPSCmdlet = $flattenedParametersOnPSCmdlet
972+
}
973+
if($globalParameters) {
974+
$functionBodyParams['GlobalParameters'] = $globalParameters
975+
}
976+
976977
$pathGenerationPhaseResult = Get-PathFunctionBody @functionBodyParams
977978
$bodyObject = $pathGenerationPhaseResult.BodyObject
978979

0 commit comments

Comments
 (0)