Skip to content

Commit ce56adb

Browse files
dolauliGeorge NdunguTim MullenderVeryEarlyisra-fel
authored
M4 master merge (#695)
* Emit Signal method and delegate to provide a hook into events * Update Az.Accounts dependency to 1.8.4 * Adding target attribute to nuspec file elements * Using backslash path separator in nuspec for cross platform compatability * Remove Init method constructor call. * Revert "Emit Signal method and delegate to provide a hook into events" * Emit Signal method and delegate to provide hook into events for Non-Azure scenarios. * Update ISendAsync.cs (#662) * Update ISendAsync.cs pass only Authorization to next header for long running operations. * Update ISendAsync.cs * Update ISendAsync.cs fix potential null reference * Update ISendAsync.cs * Update ISendAsync.cs * Update ISendAsync.cs * update gitignore (#670) * Add scan pipelines (#681) * Update development.md - add how to debug (#683) * Update development.md * Update development.md * Fix some merging issues Co-authored-by: George Ndungu <[email protected]> Co-authored-by: Tim Mullender <[email protected]> Co-authored-by: Yabo Hu <[email protected]> Co-authored-by: Yeming Liu <[email protected]> Co-authored-by: Dingmeng Xue <[email protected]>
1 parent ac262b1 commit ce56adb

File tree

92 files changed

+2332
-2021
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+2332
-2021
lines changed

.azure-pipelines/credscan-suppressions.json

Whitespace-only changes.

.azure-pipelines/daily-build.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Please don't use ADO UI defined scheduled triggers because it takes precedence over YAML scheduled triggers.
2+
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/scheduled-triggers
3+
schedules:
4+
- cron: "0 0 * * *"
5+
displayName: Daily Midnight Build
6+
branches:
7+
include:
8+
- master
9+
10+
trigger: none
11+
pr: none
12+
13+
pool:
14+
name: Hosted VS2017
15+
demands: npm
16+
17+
steps:
18+
- task: NodeTool@0
19+
displayName: 'Use Node 10.16.0'
20+
inputs:
21+
versionSpec: 10.16.0
22+
23+
- task: Npm@1
24+
displayName: 'Install autorest@beta'
25+
inputs:
26+
command: custom
27+
verbose: false
28+
customCommand: 'install -g "@autorest/autorest"'
29+
30+
- task: Npm@1
31+
displayName: 'Install @microsoft/rush'
32+
inputs:
33+
command: custom
34+
verbose: false
35+
customCommand: 'install -g @microsoft/[email protected]'
36+
37+
- task: CmdLine@2
38+
displayName: 'Rush sync-versions'
39+
inputs:
40+
script: 'rush sync-versions'
41+
42+
- task: CmdLine@2
43+
displayName: 'Rush Update'
44+
inputs:
45+
script: 'rush update'
46+
47+
- task: CmdLine@2
48+
displayName: 'Rush Rebuild'
49+
inputs:
50+
script: 'rush rebuild'

.azure-pipelines/security-scan.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trigger:
2+
branches:
3+
include:
4+
- '*'
5+
6+
pool:
7+
vmImage: "windows-2019"
8+
9+
steps:
10+
- task: ms-codeanalysis.vss-microsoft-security-code-analysis-devops.build-task-credscan.CredScan@2
11+
displayName: 'Run CredScan'
12+
continueOnError: true
13+
inputs:
14+
toolMajorVersion: "V2"
15+
suppressionsFile: .azure-pipelines\credscan-suppressions.json

docs/development.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ To use the locally built version of the plugin, add `--use:<path>` to the comman
7171

7272
### Debugging
7373

74-
COMING SOON.
74+
1. Start generating: `autorest-beta --use:C:\path\to\local\autorest.powershell --powershell.debugger`. It will wait for debugger to attach.
75+
1. Start debugging: open autorest.powershell repo in vscode; press `F5`. You will see "Debugger attached." in your autorest console, then you can start debugging.
7576

7677
### Testing
7778

powershell/cmdlets/class.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,10 @@ export class CmdletClass extends Class {
10911091
// in azure mode, we signal the AzAccount module with every event that makes it here.
10921092
yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, ${$this.correlationId.value}, ${$this.processRecordId.value}, null );`;
10931093
yield If(`${token.value}.IsCancellationRequested`, Return());
1094+
} else {
1095+
// In Non-Azure Modes, emit the Signal method without coorelation and processrecordid
1096+
yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, null );`;
1097+
yield If(`${token.value}.IsCancellationRequested`, Return());
10941098
}
10951099
yield `WriteDebug($"{id}: {(messageData().Message ?? ${System.String.Empty})}");`;
10961100
// any handling of the signal on our side...
@@ -2310,6 +2314,10 @@ export class NewCmdletClass extends Class {
23102314
// in azure mode, we signal the AzAccount module with every event that makes it here.
23112315
yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, ${$this.correlationId.value}, ${$this.processRecordId.value}, null );`;
23122316
yield If(`${token.value}.IsCancellationRequested`, Return());
2317+
} else {
2318+
// In Non-Azure Modes, emit the Signal method without coorelation and processrecordid
2319+
yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, null );`;
2320+
yield If(`${token.value}.IsCancellationRequested`, Return());
23132321
}
23142322
yield `WriteDebug($"{id}: {(messageData().Message ?? ${System.String.Empty})}");`;
23152323
// any handling of the signal on our side...

powershell/generators/gitignore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ obj
1313
generated
1414
internal
1515
exports
16+
tools
1617
custom/*.psm1
1718
test/*-TestResults.xml
1819
/*.ps1

powershell/generators/nuspec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ export async function generateNuspec(project: Project | NewProject) {
3636
<file src="${removeCd(project.psm1)}" />
3737
<!-- https://github.com/NuGet/Home/issues/3584 -->
3838
<file src="${removeCd(project.dll)}" target="${removeCd(project.binFolder)}" />
39-
<file src="${removeCd(project.binFolder)}/${project.dllName}.deps.json" target="${removeCd(project.binFolder)}" />
40-
<file src="${removeCd(project.internalFolder)}/**/*.*" exclude="${removeCd(project.internalFolder)}/readme.md" />
41-
<file src="${removeCd(project.customFolder)}/**/*.*" exclude="${removeCd(project.customFolder)}/readme.md;${removeCd(project.customFolder)}/**/*.cs" />
42-
<file src="${removeCd(project.docsFolder)}/**/*.md" exclude="${removeCd(project.docsFolder)}/readme.md" />
43-
<file src="${removeCd(project.exportsFolder)}/**/ProxyCmdletDefinitions.ps1" />
44-
<file src="${removeCd(project.utilsFolder)}/**/*.*" />
39+
<file src="${removeCd(project.binFolder)}\\${project.dllName}.deps.json" target="${removeCd(project.binFolder)}" />
40+
<file src="${removeCd(project.internalFolder)}\\**\\*.*" exclude="${removeCd(project.internalFolder)}\\readme.md" target="${removeCd(project.internalFolder)}" />
41+
<file src="${removeCd(project.customFolder)}\\**\\*.*" exclude="${removeCd(project.customFolder)}\\readme.md;${removeCd(project.customFolder)}\\**\\*.cs" target="${removeCd(project.customFolder)}" />
42+
<file src="${removeCd(project.docsFolder)}\\**\\*.md" exclude="${removeCd(project.docsFolder)}\\readme.md" target="${removeCd(project.docsFolder)}" />
43+
<file src="${removeCd(project.exportsFolder)}\\**\\ProxyCmdletDefinitions.ps1" target="${removeCd(project.exportsFolder)}" />
44+
<file src="${removeCd(project.utilsFolder)}\\**\\*.*" target="${removeCd(project.utilsFolder)}" />
4545
</files>
4646
</package>`, undefined, 'source-file-other');
4747
}

powershell/internal/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export class Project extends codeDomProject {
173173
// Values
174174
this.moduleVersion = await this.state.getValue('module-version');
175175
this.profiles = this.model.info.extensions['x-ms-metadata'].profiles || [];
176-
this.accountsVersionMinimum = '1.7.4';
176+
this.accountsVersionMinimum = '1.8.1';
177177
this.helpLinkPrefix = await this.state.getValue('help-link-prefix');
178178
this.metadata = await this.state.getValue<Metadata>('metadata');
179179
this.license = await this.state.getValue('header-text', '');
@@ -335,7 +335,7 @@ export class NewProject extends codeDomProject {
335335
// skip-for-time-being
336336
//this.profiles = this.model.info.extensions['x-ms-metadata'].profiles || [];
337337
this.profiles = [];
338-
this.accountsVersionMinimum = '1.7.4';
338+
this.accountsVersionMinimum = '1.8.1';
339339
this.helpLinkPrefix = await this.state.getValue('help-link-prefix');
340340
this.metadata = await this.state.getValue<Metadata>('metadata');
341341
this.license = await this.state.getValue('header-text', '');

powershell/module/module-class.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,21 @@ export class ModuleClass extends Class {
129129

130130
createInitAndPipeline(namespace: Namespace) {
131131
const $this = this;
132+
// Custom Event Listener without Azure Spefic concepts. (ProcessId and CorelationId)
133+
const customEventListenerFunc = System.Func(
134+
dotnet.String,
135+
System.Threading.CancellationToken,
136+
System.Func(System.EventArgs),
137+
this.incomingSignalFunc,
138+
InvocationInfo,
139+
dotnet.String,
140+
System.Exception,
141+
/* returns */ System.Threading.Tasks.Task());
142+
143+
const incomingSignalDelegate = namespace.add(new Alias('SignalDelegate', this.incomingSignalFunc));
144+
const eventListenerDelegate = namespace.add(new Alias('EventListenerDelegate', customEventListenerFunc));
145+
const EventListener = this.add(new Property('EventListener', eventListenerDelegate, { description: 'A delegate that gets called for each signalled event' }));
146+
132147
// non-azure init method
133148
this.initMethod.add(function* () {
134149
yield '// called at module init time...';
@@ -152,6 +167,22 @@ export class ModuleClass extends Class {
152167
});
153168

154169
this.add(new LambdaProperty('Name', dotnet.String, new StringExpression(this.state.project.moduleName), { description: 'The Name of this module ' }));
170+
171+
// Add Signal extensibility point
172+
const pSignal = new Parameter('signal', incomingSignalDelegate, { description: 'The callback for the event dispatcher ' });
173+
// Emit signal extensibility points that called EventListenerDelegate, allowing us to handle Signals emitted by the Pipeline in the Auth Module
174+
const signalImpl = this.add(new Method('Signal', System.Threading.Tasks.Task(), {
175+
parameters: [this.pId, this.pToken, this.pGetEventData, pSignal, this.pInvocationInfo, this.pParameterSetName, this.pException], async: Modifier.Async,
176+
description: 'Called to dispatch events to the common module listener',
177+
returnsDescription: `A <see cref="${System.Threading.Tasks.Task()}" /> that will be complete when handling of the event is completed.`
178+
}));
179+
180+
signalImpl.push(Using('NoSynchronizationContext', ''));
181+
signalImpl.add(function* () {
182+
// Emit call to EventListener after explicit null check.
183+
// Not using Null-Conditional operator causes Null Reference exception when Func<Task> is null, due to awaiting null Task.
184+
yield If(`${EventListener.value} != null`, `await ${EventListener.value}.Invoke(${$this.pId.value},${$this.pToken.value},${$this.pGetEventData.value}, ${pSignal.value}, ${$this.pInvocationInfo}, ${$this.pParameterSetName},${$this.pException});`)
185+
});
155186
}
156187

157188
createAzureInitAndPipeline(namespace: Namespace) {
@@ -379,6 +410,20 @@ export class NewModuleClass extends Class {
379410

380411
createInitAndPipeline(namespace: Namespace) {
381412
const $this = this;
413+
// Custom Event Listener without Azure Spefic concepts. (ProcessId and CorelationId)
414+
const customEventListenerFunc = System.Func(
415+
dotnet.String,
416+
System.Threading.CancellationToken,
417+
System.Func(System.EventArgs),
418+
this.incomingSignalFunc,
419+
InvocationInfo,
420+
dotnet.String,
421+
System.Exception,
422+
/* returns */ System.Threading.Tasks.Task());
423+
424+
const incomingSignalDelegate = namespace.add(new Alias('SignalDelegate', this.incomingSignalFunc));
425+
const eventListenerDelegate = namespace.add(new Alias('EventListenerDelegate', customEventListenerFunc));
426+
const EventListener = this.add(new Property('EventListener', eventListenerDelegate, { description: 'A delegate that gets called for each signalled event' }));
382427

383428
// non-azure init method
384429
this.initMethod.add(function* () {
@@ -403,6 +448,22 @@ export class NewModuleClass extends Class {
403448
});
404449

405450
this.add(new LambdaProperty('Name', dotnet.String, new StringExpression(this.state.project.moduleName), { description: 'The Name of this module ' }));
451+
452+
// Add Signal extensibility point
453+
const pSignal = new Parameter('signal', incomingSignalDelegate, { description: 'The callback for the event dispatcher ' });
454+
// Emit signal extensibility points that called EventListenerDelegate, allowing us to handle Signals emitted by the Pipeline in the Auth Module
455+
const signalImpl = this.add(new Method('Signal', System.Threading.Tasks.Task(), {
456+
parameters: [this.pId, this.pToken, this.pGetEventData, pSignal, this.pInvocationInfo, this.pParameterSetName, this.pException], async: Modifier.Async,
457+
description: 'Called to dispatch events to the common module listener',
458+
returnsDescription: `A <see cref="${System.Threading.Tasks.Task()}" /> that will be complete when handling of the event is completed.`
459+
}));
460+
461+
signalImpl.push(Using('NoSynchronizationContext', ''));
462+
signalImpl.add(function* () {
463+
// Emit call to EventListener after explicit null check.
464+
// Not using Null-Conditional operator causes Null Reference exception when Func<Task> is null, due to awaiting null Task.
465+
yield If(`${EventListener.value} != null`, `await ${EventListener.value}.Invoke(${$this.pId.value},${$this.pToken.value},${$this.pGetEventData.value}, ${pSignal.value}, ${$this.pInvocationInfo}, ${$this.pParameterSetName},${$this.pException});`)
466+
});
406467
}
407468

408469
createAzureInitAndPipeline(namespace: Namespace) {

powershell/resources/assets/tools/Resources/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This directory contains the PowerShell module for the Resources service.
1717
This module was primarily generated via [AutoRest](https://github.com/Azure/autorest) using the [PowerShell](https://github.com/Azure/autorest.powershell) extension.
1818

1919
## Module Requirements
20-
- [Az.Accounts module](https://www.powershellgallery.com/packages/Az.Accounts/), version 1.7.4 or greater
20+
- [Az.Accounts module](https://www.powershellgallery.com/packages/Az.Accounts/), version 1.8.1 or greater
2121

2222
## Authentication
2323
AutoRest does not generate authentication code for the module. Authentication is handled via Az.Accounts by altering the HTTP payload before it is sent.

0 commit comments

Comments
 (0)