createAzureInitAndPipeline()

in powershell/module/module-class.ts [220:408]


  createAzureInitAndPipeline(namespace: Namespace) {
    const $this = this;

    const sendAsyncStep = namespace.add(new Alias('SendAsyncStepDelegate',
      System.Func(
        System.Net.Http.HttpRequestMessage,
        ...this.IEventListenerExpanded,
        this.nextStep,                                  /* Next( ...) */
        /* returns */ this.TaskOfHttpResponseMessage)));

    const isDataPlane = !!this.state.project.endpointResourceIdKeyName;

    const pipelineChangeDelegate = namespace.add(new Alias('PipelineChangeDelegate', System.Action(sendAsyncStep.fullDefinition)));

    const getParameterDelegate = namespace.add(new Alias('GetParameterDelegate', System.Func(
      dotnet.String, /* resourceId */
      dotnet.String, /* moduleName */
      InvocationInfo, /* invocationInfo */
      dotnet.String, /* correlationId */
      dotnet.String, /* parameterName */
      /* returns */ dotnet.Object)));

    const moduleLoadPipelineDelegate = namespace.add(new Alias('ModuleLoadPipelineDelegate', System.Action(
      dotnet.String, /* resourceId */
      dotnet.String, /* moduleName */
      pipelineChangeDelegate.fullDefinition, /* prependStep */
      pipelineChangeDelegate.fullDefinition))); /* appendStep */

    const newRequestPipelineDelegate = new Alias('NewRequestPipelineDelegate', System.Action(
      InvocationInfo,  /* invocationInfo */
      dotnet.String,   /* correlationId */
      dotnet.String,  /* processRecordId */
      pipelineChangeDelegate.fullDefinition,    /* prependStep */
      pipelineChangeDelegate.fullDefinition)); /* appendStep */

    const argumentCompleterDelegate = namespace.add(new Alias('ArgumentCompleterDelegate', System.Func(
      dotnet.String, /* completerName */
      InvocationInfo, /* invocationInfo */
      dotnet.String, /* correlationId */
      dotnet.StringArray, /* resourceTypes */
      dotnet.StringArray, /* parentResourceParameterNames */
      /* returns */ dotnet.StringArray,
    )));
    const getTelemetryIdDelegate = namespace.add(new Alias('GetTelemetryIdDelegate', System.Func(
      /* returns */ dotnet.String,
    )));
    const telemetryDelegate = namespace.add(new Alias('TelemetryDelegate', System.Action(
      dotnet.String, /* operation name */
      InvocationInfo, /* invocationInfo */
      dotnet.String, /* parameter set name */
      PSCmdlet, /* pscmdlet */
    )));

    const sanitizerDelegate = new Alias('SanitizerDelegate', System.Action(
      dotnet.Object, /* sendToPipeline */
      dotnet.String  /* telemetryId */
    ));
    const getTelemetryInfoDelegate = new Alias('GetTelemetryInfoDelegate', System.Func(
      dotnet.String /* telemetryId */,
      /* returns */ System.Collections.Generic.Dictionary(System.String, System.String)
    ));

    const tokenAudienceConverterDelegate = new Alias('TokenAudienceConverterDelegate',
      System.Func(
        dotnet.String,
        dotnet.String,
        dotnet.String,
        dotnet.String,
        System.Uri,
        /* returns */ dotnet.String));
    const authorizeRequestDelegate = new Alias('AuthorizeRequestDelegate',
      System.Action(
        InvocationInfo,
        dotnet.String,
        dotnet.String,
        System.Action(sendAsyncStep.fullDefinition),
        System.Action(sendAsyncStep.fullDefinition),
        tokenAudienceConverterDelegate.fullDefinition,
        System.Collections.Generic.IDictionary(dotnet.String, dotnet.Object)
      ));

    if (isDataPlane) {
      namespace.add(tokenAudienceConverterDelegate);
      namespace.add(authorizeRequestDelegate);
      namespace.add(new ImportDirective('System.Collections.Generic'));
    }

    namespace.add(newRequestPipelineDelegate);

    const incomingSignalDelegate = namespace.add(new Alias('SignalDelegate', this.incomingSignalFunc));
    const eventListenerDelegate = namespace.add(new Alias('EventListenerDelegate', this.eventListenerFunc));

    namespace.add(new Alias('NextDelegate', this.nextStep));

    /* AzAccounts VTable properties  */
    const OnModuleLoad = this.add(new Property('OnModuleLoad', moduleLoadPipelineDelegate, { description: 'The delegate to call when this module is loaded (supporting a commmon module).' }));
    const OnNewRequest = new Property('OnNewRequest', newRequestPipelineDelegate, { description: 'The delegate to call before each new request (supporting a commmon module).' });
    const AddRequestUserAgentHandler = new Property('AddRequestUserAgentHandler', newRequestPipelineDelegate, { description: 'The delegate to call before each new request to add request user agent.' });
    const AddPatchRequestUriHandler = new Property('AddPatchRequestUriHandler', newRequestPipelineDelegate, { description: 'The delegate to call before each new request to patch request uri.' });
    const AddAuthorizeRequestHandler = new Property('AddAuthorizeRequestHandler', authorizeRequestDelegate, { description: 'The delegate to call before each new request to add authorization.' });
    this.add(new Property('GetTelemetryId', getTelemetryIdDelegate, { description: 'The delegate to get the telemetry Id.' }));
    this.add(new Property('Telemetry', telemetryDelegate, { description: 'The delegate for creating a telemetry.' }));
    const SanitizeOutput = this.add(new Property('SanitizeOutput', sanitizerDelegate, { description: 'The delegate to call in WriteObject to sanitize the output object.' }));
    namespace.add(sanitizerDelegate);
    const GetTelemetryInfo = this.add(new Property('GetTelemetryInfo', getTelemetryInfoDelegate, { description: 'The delegate to get the telemetry info.' }));
    namespace.add(getTelemetryInfoDelegate);
    if (isDataPlane) {
      this.add(AddRequestUserAgentHandler);
      this.add(AddPatchRequestUriHandler);
      this.add(AddAuthorizeRequestHandler);
    } else {
      this.add(OnNewRequest);
    }
    const GetParameterValue = this.add(new Property('GetParameterValue', getParameterDelegate, { description: 'The delegate to call to get parameter data from a common module.' }));
    const EventListener = this.add(new Property('EventListener', eventListenerDelegate, { description: 'A delegate that gets called for each signalled event' }));
    const ArgumentCompleter = this.add(new Property('ArgumentCompleter', argumentCompleterDelegate, { description: 'Gets completion data for azure specific fields' }));
    const ProfileName = this.add(new Property('ProfileName', System.String, { description: 'The name of the currently selected Azure profile' }));

    const moduleIdentity = this.add(new LambdaProperty('Name', dotnet.String, new StringExpression(this.state.project.moduleName), { description: 'The Name of this module ' }));
    const currentProfile = this.add(new Field('Profile', dotnet.String, { initialValue: System.String.Empty, description: 'The currently selected profile.' }));
    const moduleResourceId = this.add(new LambdaProperty('ResourceId', dotnet.String, new StringExpression(this.state.project.moduleName), { description: 'The ResourceID for this module (azure arm).' }));

    /* get parameter method (calls azAccounts) */
    this.add(new LambdaMethod('GetParameter', dotnet.Object, new LiteralExpression(`${GetParameterValue.value}?.Invoke( ${moduleResourceId.value}, ${moduleIdentity.value}, ${$this.pInvocationInfo.value}, ${$this.pCorrelationId.value},${$this.pParameterName.value} )`), {
      parameters: [this.pInvocationInfo, this.pCorrelationId, this.pParameterName],
      description: 'Gets parameters from a common module.',
      returnsDescription: 'The parameter value from the common module. (Note: this should be type converted on the way back)'
    }));

    /* signal method (calls azAccounts) */
    const pSignal = new Parameter('signal', incomingSignalDelegate, { description: 'The callback for the event dispatcher ' });
    const signalImpl = this.add(new Method('Signal', System.Threading.Tasks.Task(), {
      parameters: [this.pId, this.pToken, this.pGetEventData, pSignal, this.pInvocationInfo, this.pParameterSetName, this.pCorrelationId, this.pProcessRecordId, this.pException], async: Modifier.Async,
      description: 'Called to dispatch events to the common module listener',
      returnsDescription: `A <see cref="${System.Threading.Tasks.Task()}" /> that will be complete when handling of the event is completed.`
    }));

    signalImpl.push(Using('NoSynchronizationContext', ''));
    signalImpl.add(function* () {
      yield `await ${EventListener.value}?.Invoke(${$this.pId.value},${$this.pToken.value},${$this.pGetEventData.value}, ${pSignal.value}, ${$this.pInvocationInfo}, ${$this.pParameterSetName}, ${$this.pCorrelationId},${$this.pProcessRecordId},${$this.pException});`;
    });

    /* init method */
    this.initMethod.add(function* () {
      yield If('_init == false', function* () {
        yield `lock (_initLock) {
    if (_init == false) {
        ${OnModuleLoad.value}?.Invoke( ${moduleResourceId.value}, ${moduleIdentity.value} ,(step)=> { ${$this.fPipeline.value}.Prepend(step); } , (step)=> { ${$this.fPipeline.value}.Append(step); } );
        ${OnModuleLoad.value}?.Invoke( ${moduleResourceId.value}, ${moduleIdentity.value} ,(step)=> { ${$this.fPipelineWithProxy.value}.Prepend(step); } , (step)=> { ${$this.fPipelineWithProxy.value}.Append(step); } );
        CustomInit();
        _init = true;
    }
}`;
      });
    });

    this.createPipelineMethod = this.add(new Method('CreatePipeline', ClientRuntime.HttpPipeline, {
      parameters: [this.pInvocationInfo, this.pCorrelationId, this.pProcessRecordId, this.pParameterSetNameWithDefault, this.pExtensibleParameters],
      description: 'Creates an instance of the HttpPipeline for each call.',
      returnsDescription: `An instance of ${ClientRuntime.HttpPipeline} for the remote call.`
    }));
    /* Add following three fields for data plane */
    const fendpointResourceIdKeyName = new Field('_endpointResourceIdKeyName', dotnet.String, { access: Access.Private, initialValue: new StringExpression(this.state.project.endpointResourceIdKeyName) });
    const fEndpointSuffixKeyName = new Field('_endpointSuffixKeyName', dotnet.String, { access: Access.Private, initialValue: new StringExpression(this.state.project.endpointSuffixKeyName) });
    const fTokenAudienceConverter = new Field('_tokenAudienceConverter', tokenAudienceConverterDelegate, { access: Access.Private, initialValue: 'null' });
    if (isDataPlane) {
      this.add(fendpointResourceIdKeyName);
      this.add(fEndpointSuffixKeyName);
      this.add(fTokenAudienceConverter);
    }

    /* pipeline create method */
    this.createPipelineMethod.add(function* () {
      const pip = new LocalVariable('pipeline', ClientRuntime.HttpPipeline, { initializer: 'null' });
      yield pip.declarationStatement;
      yield `BeforeCreatePipeline(${$this.pInvocationInfo.use}, ref ${pip});`;
      yield pip.assign(`(${pip} ?? (${$this.fUseProxy} ? ${$this.fPipelineWithProxy} : ${$this.fPipeline})).Clone()`);
      yield `AfterCreatePipeline(${$this.pInvocationInfo.use}, ref ${pip});`;
      yield `pipeline.Append(new Runtime.CmdInfoHandler(${$this.pProcessRecordId}, ${$this.pInvocationInfo.use}, ${$this.pParameterSetName}).SendAsync);`;
      if (isDataPlane) {
        yield `${AddRequestUserAgentHandler.value}?.Invoke( ${$this.pInvocationInfo.use}, ${$this.pCorrelationId},${$this.pProcessRecordId}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); } );`;
        yield `${AddPatchRequestUriHandler.value}?.Invoke( ${$this.pInvocationInfo.use}, ${$this.pCorrelationId},${$this.pProcessRecordId}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); } );`;
        yield `${AddAuthorizeRequestHandler.value}?.Invoke( ${$this.pInvocationInfo.use}, ${fendpointResourceIdKeyName},${fEndpointSuffixKeyName}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); }, ${fTokenAudienceConverter}, ${$this.pExtensibleParameters} );`;
      } else {
        yield `${OnNewRequest.value}?.Invoke( ${$this.pInvocationInfo.use}, ${$this.pCorrelationId},${$this.pProcessRecordId}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); } );`;
      }
      yield Return(pip);
    });
  }