private async Task PublishWithRetryAsync <T>(string source, string subject, T cloudEvent, WorkflowEventSubscription destination)
 {
     try
     {
         await Retriable.RetryAsync(() => this.PublishAsync(source, subject, cloudEvent, destination)).ConfigureAwait(false);
     }
     catch (Exception ex)
     {
         // In this "v1" solution to event publishing, we don't want exceptions to propagate outside the
         // publisher because we don't want failure in event publishing to break anything.
         this.logger.LogError(
             ex,
             "Unexpected exception when trying to a CloudEvent with source '{source}', '{subject}' and destinationUrl '{destinationUrl}' with authentication resource '{msiAuthenticationResource}'.",
             source,
             subject,
             destination?.ExternalUrl,
             destination?.MsiAuthenticationResource);
     }
 }
        private async Task PublishAsync <T>(string source, string subject, T cloudEvent, WorkflowEventSubscription destination)
        {
            this.logger.LogDebug(
                "Initialising event publish request for subject '{subject}' and source '{source}' to external URL '{externalUrl}'",
                subject,
                source,
                destination.ExternalUrl);

            var request = new HttpRequestMessage(HttpMethod.Post, destination.ExternalUrl);

            if (destination.AuthenticateWithManagedServiceIdentity)
            {
                AccessTokenDetail tokenDetails = await this.serviceIdentityTokenSource.GetAccessTokenAsync(
                    new AccessTokenRequest(new[] { $"{destination.MsiAuthenticationResource}/.default" }))
                                                 .ConfigureAwait(false);

                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenDetails.AccessToken);
            }

            request.Content = new StringContent(
                JsonConvert.SerializeObject(cloudEvent, this.serializerSettingsProvider.Instance),
                Encoding.UTF8,
                "application/cloudevents");

            HttpResponseMessage httpResponse = await this.httpClient.SendAsync(request).ConfigureAwait(false);

            if (!httpResponse.IsSuccessStatusCode)
            {
                throw new CloudEventPublisherException(
                          subject,
                          source,
                          destination.ExternalUrl,
                          httpResponse.StatusCode,
                          httpResponse.ReasonPhrase);
            }
        }