diff --git a/samples/ingestion/ingestion-client/FetchTranscription/Config/AppConfig.cs b/samples/ingestion/ingestion-client/FetchTranscription/Config/AppConfig.cs
new file mode 100644
index 000000000..e7602d7d6
--- /dev/null
+++ b/samples/ingestion/ingestion-client/FetchTranscription/Config/AppConfig.cs
@@ -0,0 +1,109 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace FetchTranscription
+{
+ using System;
+ using Connector.Constants;
+ using Connector.Enums;
+ using Connector.Serializable.Language.Conversations;
+
+ public class AppConfig
+ {
+ private ConversationSummarizationOptions conversationSummarizationOptions;
+
+ private int initialPollingDelayInMinutes = Constants.DefaultInitialPollingDelayInMinutes;
+
+ private int retryLimit = Constants.DefaultRetryLimit;
+ private int maxPollingDelayInMinutes = Constants.DefaultMaxPollingDelayInMinutes;
+
+ public SentimentAnalysisSetting SentimentAnalysisSetting { get; set; } = SentimentAnalysisSetting.None;
+
+ public PiiRedactionSetting PiiRedactionSetting { get; set; } = PiiRedactionSetting.None;
+
+ public bool CreateHtmlResultFile { get; set; }
+
+ public ConversationPiiSetting ConversationPiiSetting { get; set; } = ConversationPiiSetting.None;
+
+ public string ConversationPiiCategories { get; set; }
+
+ public string ConversationPiiInferenceSource { get; set; }
+
+ public int ConversationPiiMaxChunkSize { get; set; } = Constants.DefaultConversationAnalysisMaxChunkSize;
+
+ public ConversationSummarizationOptions ConversationSummarizationOptions
+ {
+ get
+ {
+ if (this.conversationSummarizationOptions == null)
+ {
+ var envVarValue = Environment.GetEnvironmentVariable(nameof(this.ConversationSummarizationOptions), EnvironmentVariableTarget.Process);
+ this.conversationSummarizationOptions = string.IsNullOrEmpty(envVarValue)
+ ? new ConversationSummarizationOptions()
+ : System.Text.Json.JsonSerializer.Deserialize(envVarValue);
+ }
+
+ return this.conversationSummarizationOptions;
+ }
+
+ set
+ {
+ this.conversationSummarizationOptions = value;
+ }
+ }
+
+ public bool UseSqlDatabase { get; set; }
+
+ public int InitialPollingDelayInMinutes
+ {
+ get => this.initialPollingDelayInMinutes;
+ set => this.initialPollingDelayInMinutes = Math.Clamp(value, 2, Constants.MaxInitialPollingDelayInMinutes);
+ }
+
+ public int MaxPollingDelayInMinutes { get; set; } = Constants.DefaultMaxPollingDelayInMinutes;
+
+ public int RetryLimit
+ {
+ get => this.retryLimit;
+ set => this.retryLimit = Math.Clamp(value, 1, Constants.MaxRetryLimit);
+ }
+
+ public string AudioInputContainer { get; set; }
+
+ public string AzureSpeechServicesKey { get; set; }
+
+ public string AzureWebJobsStorage { get; set; }
+
+ public string DatabaseConnectionString { get; set; }
+
+ public string ErrorFilesOutputContainer { get; set; }
+
+ public string ErrorReportOutputContainer { get; set; }
+
+ public string FetchTranscriptionServiceBusConnectionString { get; set; }
+
+ public string CompletedServiceBusConnectionString { get; set; }
+
+ public string HtmlResultOutputContainer { get; set; }
+
+ public string JsonResultOutputContainer { get; set; }
+
+ public string StartTranscriptionServiceBusConnectionString { get; set; }
+
+ public string TextAnalyticsKey { get; set; }
+
+ public string TextAnalyticsEndpoint { get; set; }
+
+ public string PiiCategories { get; set; }
+
+ public bool CreateConsolidatedOutputFiles { get; set; }
+
+ public string ConsolidatedFilesOutputContainer { get; set; }
+
+ public bool CreateAudioProcessedContainer { get; set; }
+
+ public string AudioProcessedContainer { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscription.cs b/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscription.cs
index 5b0e49004..b48112db2 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscription.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscription.cs
@@ -16,6 +16,7 @@ namespace FetchTranscription
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
///
/// Fetch Transcription class.
@@ -26,6 +27,7 @@ public class FetchTranscription
private readonly IStorageConnector storageConnector;
private readonly IAzureClientFactory serviceBusClientFactory;
private readonly ILogger logger;
+ private readonly AppConfig appConfig;
///
/// Initializes a new instance of the class.
@@ -34,16 +36,19 @@ public class FetchTranscription
/// The FetchTranscription logger.
/// Storage Connector dependency
/// Azure client factory for service bus clients
+ /// Environment configuration
public FetchTranscription(
IServiceProvider serviceProvider,
ILogger logger,
IStorageConnector storageConnector,
- IAzureClientFactory serviceBusClientFactory)
+ IAzureClientFactory serviceBusClientFactory,
+ IOptions appConfig)
{
this.serviceProvider = serviceProvider;
this.logger = logger;
this.storageConnector = storageConnector;
this.serviceBusClientFactory = serviceBusClientFactory;
+ this.appConfig = appConfig?.Value;
}
///
@@ -65,9 +70,9 @@ public async Task Run([ServiceBusTrigger("fetch_transcription_queue", Connection
var serviceBusMessage = TranscriptionStartedMessage.DeserializeMessage(message);
- var databaseContext = FetchTranscriptionEnvironmentVariables.UseSqlDatabase ? this.serviceProvider.GetRequiredService() : null;
+ var databaseContext = this.appConfig.UseSqlDatabase ? this.serviceProvider.GetRequiredService() : null;
- var transcriptionProcessor = new TranscriptionProcessor(this.storageConnector, this.serviceBusClientFactory, databaseContext);
+ var transcriptionProcessor = new TranscriptionProcessor(this.storageConnector, this.serviceBusClientFactory, databaseContext, Options.Create(this.appConfig));
await transcriptionProcessor.ProcessTranscriptionJobAsync(serviceBusMessage, this.serviceProvider, this.logger).ConfigureAwait(false);
}
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscriptionEnvironmentVariables.cs b/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscriptionEnvironmentVariables.cs
deleted file mode 100644
index 724982ae6..000000000
--- a/samples/ingestion/ingestion-client/FetchTranscription/FetchTranscriptionEnvironmentVariables.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
-//
-
-namespace FetchTranscription
-{
- using System;
- using Connector;
- using Connector.Constants;
- using Connector.Enums;
- using Connector.Serializable.Language.Conversations;
-
- public static class FetchTranscriptionEnvironmentVariables
- {
- public static readonly SentimentAnalysisSetting SentimentAnalysisSetting = Enum.TryParse(Environment.GetEnvironmentVariable(nameof(SentimentAnalysisSetting), EnvironmentVariableTarget.Process), out SentimentAnalysisSetting) ? SentimentAnalysisSetting : SentimentAnalysisSetting.None;
-
- public static readonly PiiRedactionSetting PiiRedactionSetting = Enum.TryParse(Environment.GetEnvironmentVariable(nameof(PiiRedactionSetting), EnvironmentVariableTarget.Process), out PiiRedactionSetting) ? PiiRedactionSetting : PiiRedactionSetting.None;
-
- public static readonly bool CreateHtmlResultFile = bool.TryParse(Environment.GetEnvironmentVariable(nameof(CreateHtmlResultFile), EnvironmentVariableTarget.Process), out CreateHtmlResultFile) && CreateHtmlResultFile;
-
- public static readonly ConversationPiiSetting ConversationPiiSetting = Enum.TryParse(Environment.GetEnvironmentVariable(nameof(ConversationPiiSetting), EnvironmentVariableTarget.Process), out ConversationPiiSetting) ? ConversationPiiSetting : ConversationPiiSetting.None;
-
- public static readonly string ConversationPiiCategories = Environment.GetEnvironmentVariable(nameof(ConversationPiiCategories), EnvironmentVariableTarget.Process);
-
- public static readonly string ConversationPiiInferenceSource = Environment.GetEnvironmentVariable(nameof(ConversationPiiInferenceSource), EnvironmentVariableTarget.Process);
-
- public static readonly int ConversationPiiMaxChunkSize = int.TryParse(Environment.GetEnvironmentVariable(nameof(ConversationPiiMaxChunkSize), EnvironmentVariableTarget.Process), out ConversationPiiMaxChunkSize) ? ConversationPiiMaxChunkSize : Constants.DefaultConversationAnalysisMaxChunkSize;
-
- public static readonly ConversationSummarizationOptions ConversationSummarizationOptions = string.IsNullOrEmpty(Environment.GetEnvironmentVariable(nameof(ConversationSummarizationOptions), EnvironmentVariableTarget.Process)) ? new ConversationSummarizationOptions() : System.Text.Json.JsonSerializer.Deserialize(Environment.GetEnvironmentVariable(nameof(ConversationSummarizationOptions), EnvironmentVariableTarget.Process));
-
- public static readonly bool UseSqlDatabase = bool.TryParse(Environment.GetEnvironmentVariable(nameof(UseSqlDatabase), EnvironmentVariableTarget.Process), out UseSqlDatabase) && UseSqlDatabase;
-
- public static readonly int InitialPollingDelayInMinutes = int.TryParse(Environment.GetEnvironmentVariable(nameof(InitialPollingDelayInMinutes), EnvironmentVariableTarget.Process), out InitialPollingDelayInMinutes) ? InitialPollingDelayInMinutes.ClampInt(2, Constants.MaxInitialPollingDelayInMinutes) : Constants.DefaultInitialPollingDelayInMinutes;
-
- public static readonly int MaxPollingDelayInMinutes = int.TryParse(Environment.GetEnvironmentVariable(nameof(MaxPollingDelayInMinutes), EnvironmentVariableTarget.Process), out MaxPollingDelayInMinutes) ? MaxPollingDelayInMinutes : Constants.DefaultMaxPollingDelayInMinutes;
-
- public static readonly int RetryLimit = int.TryParse(Environment.GetEnvironmentVariable(nameof(RetryLimit), EnvironmentVariableTarget.Process), out RetryLimit) ? RetryLimit.ClampInt(1, Constants.MaxRetryLimit) : Constants.DefaultRetryLimit;
-
- public static readonly string AudioInputContainer = Environment.GetEnvironmentVariable(nameof(AudioInputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string AzureSpeechServicesKey = Environment.GetEnvironmentVariable(nameof(AzureSpeechServicesKey), EnvironmentVariableTarget.Process);
-
- public static readonly string AzureWebJobsStorage = Environment.GetEnvironmentVariable(nameof(AzureWebJobsStorage), EnvironmentVariableTarget.Process);
-
- public static readonly string DatabaseConnectionString = Environment.GetEnvironmentVariable(nameof(DatabaseConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string ErrorFilesOutputContainer = Environment.GetEnvironmentVariable(nameof(ErrorFilesOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string ErrorReportOutputContainer = Environment.GetEnvironmentVariable(nameof(ErrorReportOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string FetchTranscriptionServiceBusConnectionString = Environment.GetEnvironmentVariable(nameof(FetchTranscriptionServiceBusConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string CompletedServiceBusConnectionString = Environment.GetEnvironmentVariable(nameof(CompletedServiceBusConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string HtmlResultOutputContainer = Environment.GetEnvironmentVariable(nameof(HtmlResultOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string JsonResultOutputContainer = Environment.GetEnvironmentVariable(nameof(JsonResultOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string StartTranscriptionServiceBusConnectionString = Environment.GetEnvironmentVariable(nameof(StartTranscriptionServiceBusConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string TextAnalyticsKey = Environment.GetEnvironmentVariable(nameof(TextAnalyticsKey), EnvironmentVariableTarget.Process);
-
- public static readonly string TextAnalyticsEndpoint = Environment.GetEnvironmentVariable(nameof(TextAnalyticsEndpoint), EnvironmentVariableTarget.Process);
-
- public static readonly string PiiCategories = Environment.GetEnvironmentVariable(nameof(PiiCategories), EnvironmentVariableTarget.Process);
-
- public static readonly bool CreateConsolidatedOutputFiles = bool.TryParse(Environment.GetEnvironmentVariable(nameof(CreateConsolidatedOutputFiles), EnvironmentVariableTarget.Process), out CreateConsolidatedOutputFiles) && CreateConsolidatedOutputFiles;
-
- public static readonly string ConsolidatedFilesOutputContainer = Environment.GetEnvironmentVariable(nameof(ConsolidatedFilesOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly bool CreateAudioProcessedContainer = bool.TryParse(Environment.GetEnvironmentVariable(nameof(CreateAudioProcessedContainer), EnvironmentVariableTarget.Process), out CreateAudioProcessedContainer) && CreateAudioProcessedContainer;
-
- public static readonly string AudioProcessedContainer = Environment.GetEnvironmentVariable(nameof(AudioProcessedContainer), EnvironmentVariableTarget.Process);
- }
-}
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/Program.cs b/samples/ingestion/ingestion-client/FetchTranscription/Program.cs
index 0ab3f5f4d..a07a6f477 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/Program.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/Program.cs
@@ -5,7 +5,7 @@
namespace FetchTranscription
{
- using System;
+ using System.IO;
using Azure.Storage;
using Azure.Storage.Blobs;
@@ -16,55 +16,68 @@ namespace FetchTranscription
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Azure;
+ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+ using Microsoft.Extensions.Options;
public static class Program
{
public static void Main(string[] args)
{
- var useSqlDatabase = FetchTranscriptionEnvironmentVariables.UseSqlDatabase;
- var storageConnectionString = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
- var blobServiceClient = new BlobServiceClient(storageConnectionString);
- var storageCredential = new StorageSharedKeyCredential(
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", storageConnectionString),
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", storageConnectionString));
-
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
- .ConfigureServices(s =>
+ .ConfigureAppConfiguration((context, config) =>
+ {
+ config.SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
+ .AddEnvironmentVariables();
+ })
+ .ConfigureServices((context, services) =>
{
+ var configuration = context.Configuration;
+ var config = new AppConfig();
+ configuration.GetSection("Values").Bind(config);
+
+ var blobServiceClient = new BlobServiceClient(config.AzureWebJobsStorage);
+ var storageCredential = new StorageSharedKeyCredential(
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", config.AzureWebJobsStorage),
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", config.AzureWebJobsStorage));
+
// This is a unified way to configure logging filter for all functions.
- s.ConfigureIngestionClientLogging();
+ services.ConfigureIngestionClientLogging();
- if (useSqlDatabase)
+ if (config.UseSqlDatabase)
{
- s.AddDbContext(
- options => SqlServerDbContextOptionsExtensions.UseSqlServer(options, FetchTranscriptionEnvironmentVariables.DatabaseConnectionString));
+ services.AddDbContext(
+ options => SqlServerDbContextOptionsExtensions.UseSqlServer(options, config.DatabaseConnectionString));
}
- s.AddSingleton(blobServiceClient);
- s.AddSingleton(storageCredential);
- s.AddTransient();
+ services.AddSingleton(blobServiceClient);
+ services.AddSingleton(storageCredential);
+ services.AddTransient();
- s.AddAzureClients(clientBuilder =>
+ services.AddAzureClients(clientBuilder =>
{
- clientBuilder.AddServiceBusClient(FetchTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.StartTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
- clientBuilder.AddServiceBusClient(FetchTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.FetchTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
- if (!string.IsNullOrWhiteSpace(FetchTranscriptionEnvironmentVariables.CompletedServiceBusConnectionString))
+ if (!string.IsNullOrWhiteSpace(config.CompletedServiceBusConnectionString))
{
- clientBuilder.AddServiceBusClient(FetchTranscriptionEnvironmentVariables.CompletedServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.CompletedServiceBusConnectionString)
.WithName(ServiceBusClientName.CompletedTranscriptionServiceBusClient.ToString());
}
});
+ services.Configure(configuration.GetSection("Values"));
})
.Build();
+ var config = host.Services.GetService>().Value;
+
// apply database migrations once during startup (not with every function execution):
- if (useSqlDatabase)
+ if (config.UseSqlDatabase)
{
using var scope = host.Services.CreateScope();
var ingestionClientDbContext = scope.ServiceProvider.GetRequiredService();
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/Language/AnalyzeConversationsProvider.cs b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/Language/AnalyzeConversationsProvider.cs
index 8633a7632..bef69644a 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/Language/AnalyzeConversationsProvider.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/Language/AnalyzeConversationsProvider.cs
@@ -23,6 +23,7 @@ namespace FetchTranscription
using Connector.Serializable.TranscriptionStartedServiceBusMessage;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
using Newtonsoft.Json;
@@ -39,25 +40,28 @@ public class AnalyzeConversationsProvider : ITranscriptionAnalyticsProvider
private readonly string locale;
private readonly ILogger log;
- public AnalyzeConversationsProvider(string locale, string subscriptionKey, string endpoint, ILogger log)
+ private readonly AppConfig appConfig;
+
+ public AnalyzeConversationsProvider(string locale, string subscriptionKey, string endpoint, ILogger log, IOptions appConfig)
{
this.conversationAnalysisClient = new ConversationAnalysisClient(new Uri(endpoint), new AzureKeyCredential(subscriptionKey));
this.locale = locale;
this.log = log;
+ this.appConfig = appConfig?.Value;
}
- public static bool IsConversationalPiiEnabled()
+ public bool IsConversationalPiiEnabled()
{
- return FetchTranscriptionEnvironmentVariables.ConversationPiiSetting != ConversationPiiSetting.None;
+ return this.appConfig.ConversationPiiSetting != ConversationPiiSetting.None;
}
- public static bool IsConversationalSummarizationEnabled()
- => FetchTranscriptionEnvironmentVariables.ConversationSummarizationOptions.Enabled;
+ public bool IsConversationalSummarizationEnabled()
+ => this.appConfig.ConversationSummarizationOptions.Enabled;
///
public async Task GetTranscriptionAnalyticsJobStatusAsync(IEnumerable audioFileInfos)
{
- if (!IsConversationalPiiEnabled() && !IsConversationalSummarizationEnabled())
+ if (!this.IsConversationalPiiEnabled() && !this.IsConversationalSummarizationEnabled())
{
return TranscriptionAnalyticsJobStatus.Completed;
}
@@ -299,7 +303,7 @@ private async Task> AddConversationalEntitiesAsync(
speechTranscript = speechTranscript ?? throw new ArgumentNullException(nameof(speechTranscript));
var errors = new List();
- if (!(IsConversationalPiiEnabled() || IsConversationalSummarizationEnabled()))
+ if (!(this.IsConversationalPiiEnabled() || this.IsConversationalSummarizationEnabled()))
{
return new List();
}
@@ -327,7 +331,7 @@ private async Task> AddConversationalEntitiesAsync(
private void PrepareSummarizationRequest(SpeechTranscript speechTranscript, List data)
{
- if (!IsConversationalSummarizationEnabled())
+ if (!this.IsConversationalSummarizationEnabled())
{
this.log.LogInformation("Skip prepare summarization request because disabled");
return;
@@ -360,7 +364,7 @@ private void PrepareSummarizationRequest(SpeechTranscript speechTranscript, List
Tasks = new List(),
};
- foreach (var aspect in FetchTranscriptionEnvironmentVariables.ConversationSummarizationOptions.Aspects)
+ foreach (var aspect in this.appConfig.ConversationSummarizationOptions.Aspects)
{
summarizationData.Tasks.Add(new AnalyzeConversationsTask
{
@@ -402,7 +406,7 @@ private void PrepareSummarizationRequest(SpeechTranscript speechTranscript, List
})
};
- var stratergy = FetchTranscriptionEnvironmentVariables.ConversationSummarizationOptions.Stratergy;
+ var stratergy = this.appConfig.ConversationSummarizationOptions.Stratergy;
var roleKey = stratergy.Key switch
{
RoleAssignmentMappingKey.Channel => recognizedPhrase.Channel,
@@ -414,7 +418,7 @@ private void PrepareSummarizationRequest(SpeechTranscript speechTranscript, List
role = stratergy.FallbackRole;
}
- if (role != Role.None && count + utterance.Text.Length < FetchTranscriptionEnvironmentVariables.ConversationSummarizationOptions.InputLengthLimit)
+ if (role != Role.None && count + utterance.Text.Length < this.appConfig.ConversationSummarizationOptions.InputLengthLimit)
{
utterance.Role = utterance.ParticipantId = role.ToString();
summarizationData.AnalysisInput.Conversations[0].ConversationItems.Add(utterance);
@@ -430,7 +434,7 @@ private void PrepareSummarizationRequest(SpeechTranscript speechTranscript, List
private void PreparePiiRequest(SpeechTranscript speechTranscript, List data)
{
- if (!IsConversationalPiiEnabled())
+ if (!this.IsConversationalPiiEnabled())
{
this.log.LogInformation("Skip prepare pii request");
return;
@@ -447,7 +451,7 @@ private void PreparePiiRequest(SpeechTranscript speechTranscript, List FetchTranscriptionEnvironmentVariables.ConversationPiiMaxChunkSize)
+ if (count == -1 || (count + textCount) > this.appConfig.ConversationPiiMaxChunkSize)
{
count = 0;
jobCount++;
@@ -473,13 +477,13 @@ private void PreparePiiRequest(SpeechTranscript speechTranscript, List
{
{
- "piiCategories", FetchTranscriptionEnvironmentVariables.ConversationPiiCategories.ToList()
+ "piiCategories", this.appConfig.ConversationPiiCategories.ToList()
},
{
- "redactionSource", FetchTranscriptionEnvironmentVariables.ConversationPiiInferenceSource ?? DefaultInferenceSource
+ "redactionSource", this.appConfig.ConversationPiiInferenceSource ?? DefaultInferenceSource
},
{
- "includeAudioRedaction", FetchTranscriptionEnvironmentVariables.ConversationPiiSetting == ConversationPiiSetting.IncludeAudioRedaction
+ "includeAudioRedaction", this.appConfig.ConversationPiiSetting == ConversationPiiSetting.IncludeAudioRedaction
}
}
}
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TextAnalytics/TextAnalyticsProvider.cs b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TextAnalytics/TextAnalyticsProvider.cs
index 68d66c909..0857fee03 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TextAnalytics/TextAnalyticsProvider.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TextAnalytics/TextAnalyticsProvider.cs
@@ -19,6 +19,7 @@ namespace FetchTranscription
using Connector.Serializable.TranscriptionStartedServiceBusMessage;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
using static Connector.Serializable.TranscriptionStartedServiceBusMessage.TextAnalyticsRequest;
@@ -34,23 +35,26 @@ public class TextAnalyticsProvider : ITranscriptionAnalyticsProvider
private readonly ILogger log;
- public TextAnalyticsProvider(string locale, string subscriptionKey, string endpoint, ILogger log)
+ private readonly AppConfig appConfig;
+
+ public TextAnalyticsProvider(string locale, string subscriptionKey, string endpoint, ILogger log, IOptions appConfig)
{
this.textAnalyticsClient = new TextAnalyticsClient(new Uri(endpoint), new AzureKeyCredential(subscriptionKey));
this.locale = locale;
this.log = log;
+ this.appConfig = appConfig?.Value;
}
- public static bool IsTextAnalyticsRequested()
+ public bool IsTextAnalyticsRequested()
{
- return FetchTranscriptionEnvironmentVariables.SentimentAnalysisSetting != SentimentAnalysisSetting.None ||
- FetchTranscriptionEnvironmentVariables.PiiRedactionSetting != PiiRedactionSetting.None;
+ return this.appConfig.SentimentAnalysisSetting != SentimentAnalysisSetting.None ||
+ this.appConfig.PiiRedactionSetting != PiiRedactionSetting.None;
}
///
public async Task GetTranscriptionAnalyticsJobStatusAsync(IEnumerable audioFileInfos)
{
- if (!IsTextAnalyticsRequested())
+ if (!this.IsTextAnalyticsRequested())
{
return TranscriptionAnalyticsJobStatus.Completed;
}
@@ -116,15 +120,15 @@ public async Task> SubmitTranscriptionAnalyticsJobsAsync(Dic
(var utteranceLevelJobIds, var utteranceLevelErrors) = await this.SubmitUtteranceLevelRequests(
speechTranscript,
- FetchTranscriptionEnvironmentVariables.SentimentAnalysisSetting).ConfigureAwait(false);
+ this.appConfig.SentimentAnalysisSetting).ConfigureAwait(false);
var utteranceLevelRequests = utteranceLevelJobIds?.Select(jobId => new TextAnalyticsRequest(jobId, TextAnalyticsRequestStatus.Running));
textAnalyticsErrors.AddRange(utteranceLevelErrors);
(var audioLevelJobIds, var audioLevelErrors) = await this.SubmitAudioLevelRequests(
speechTranscript,
- FetchTranscriptionEnvironmentVariables.SentimentAnalysisSetting,
- FetchTranscriptionEnvironmentVariables.PiiRedactionSetting).ConfigureAwait(false);
+ this.appConfig.SentimentAnalysisSetting,
+ this.appConfig.PiiRedactionSetting).ConfigureAwait(false);
var audioLevelRequests = audioLevelJobIds?.Select(jobId => new TextAnalyticsRequest(jobId, TextAnalyticsRequestStatus.Running));
textAnalyticsErrors.AddRange(audioLevelErrors);
@@ -162,7 +166,7 @@ public async Task> AddTranscriptionAnalyticsResultsToTranscr
var speechTranscript = speechTranscriptMapping.Value;
var audioFileInfo = speechTranscriptMapping.Key;
var fileName = audioFileInfo.FileName;
- if (FetchTranscriptionEnvironmentVariables.PiiRedactionSetting != PiiRedactionSetting.None)
+ if (this.appConfig.PiiRedactionSetting != PiiRedactionSetting.None)
{
speechTranscript.RecognizedPhrases.ToList().ForEach(phrase =>
{
@@ -264,9 +268,9 @@ public async Task> AddTranscriptionAnalyticsResultsToTranscr
{
var action = new RecognizePiiEntitiesAction();
- if (!string.IsNullOrEmpty(FetchTranscriptionEnvironmentVariables.PiiCategories))
+ if (!string.IsNullOrEmpty(this.appConfig.PiiCategories))
{
- var piiEntityCategories = FetchTranscriptionEnvironmentVariables.PiiCategories.Split(",").Select(c => new PiiEntityCategory(c));
+ var piiEntityCategories = this.appConfig.PiiCategories.Split(",").Select(c => new PiiEntityCategory(c));
foreach (var category in piiEntityCategories)
{
@@ -362,7 +366,7 @@ private async Task> AddAudioLevelEntitiesAsync(
};
}
- if (!AnalyzeConversationsProvider.IsConversationalPiiEnabled())
+ if (!(this.appConfig.ConversationPiiSetting != ConversationPiiSetting.None))
{
var piiResult = piiResults.Where(document => document.Id.Equals($"{channel}", StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
if (piiResult != null)
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TranscriptionAnalyticsOrchestrator.cs b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TranscriptionAnalyticsOrchestrator.cs
index 089dbae7c..78842df0d 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TranscriptionAnalyticsOrchestrator.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionAnalytics/TranscriptionAnalyticsOrchestrator.cs
@@ -14,25 +14,26 @@ namespace FetchTranscription
using Connector.Serializable.TranscriptionStartedServiceBusMessage;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
public sealed class TranscriptionAnalyticsOrchestrator
{
private readonly List providers;
+ private readonly AppConfig appConfig;
+
public TranscriptionAnalyticsOrchestrator(
string locale,
- ILogger logger)
+ ILogger logger,
+ IOptions appConfig)
{
- var textAnalyticsKey = FetchTranscriptionEnvironmentVariables.TextAnalyticsKey;
- var textAnalyticsEndpoint = FetchTranscriptionEnvironmentVariables.TextAnalyticsEndpoint;
- var textAnalyticsInfoProvided = !string.IsNullOrEmpty(textAnalyticsKey) && !string.IsNullOrEmpty(textAnalyticsEndpoint);
-
+ this.appConfig = appConfig?.Value;
this.providers = new List();
- if (textAnalyticsInfoProvided)
+ if (!string.IsNullOrEmpty(this.appConfig.TextAnalyticsKey) && !string.IsNullOrEmpty(this.appConfig.TextAnalyticsEndpoint))
{
- this.providers.Add(new TextAnalyticsProvider(locale, textAnalyticsKey, textAnalyticsEndpoint, logger));
- this.providers.Add(new AnalyzeConversationsProvider(locale, textAnalyticsKey, textAnalyticsEndpoint, logger));
+ this.providers.Add(new TextAnalyticsProvider(locale, this.appConfig.TextAnalyticsKey, this.appConfig.TextAnalyticsEndpoint, logger, Options.Create(this.appConfig)));
+ this.providers.Add(new AnalyzeConversationsProvider(locale, this.appConfig.TextAnalyticsKey, this.appConfig.TextAnalyticsEndpoint, logger, Options.Create(this.appConfig)));
}
}
diff --git a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionProcessor.cs b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionProcessor.cs
index f26f206da..faa4c7f10 100644
--- a/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionProcessor.cs
+++ b/samples/ingestion/ingestion-client/FetchTranscription/TranscriptionProcessor.cs
@@ -23,6 +23,8 @@ namespace FetchTranscription
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
+
using Newtonsoft.Json;
public class TranscriptionProcessor
@@ -37,27 +39,31 @@ public class TranscriptionProcessor
private readonly IStorageConnector storageConnector;
+ private readonly AppConfig appConfig;
+
public TranscriptionProcessor(
IStorageConnector storageConnector,
IAzureClientFactory serviceBusClientFactory,
- IngestionClientDbContext databaseContext)
+ IngestionClientDbContext databaseContext,
+ IOptions appConfig)
{
this.storageConnector = storageConnector;
this.databaseContext = databaseContext;
+ this.appConfig = appConfig?.Value;
ArgumentNullException.ThrowIfNull(serviceBusClientFactory, nameof(serviceBusClientFactory));
var startTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
- var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(FetchTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString).EntityPath;
+ var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.StartTranscriptionServiceBusConnectionString).EntityPath;
this.startTranscriptionServiceBusSender = startTranscriptionServiceBusClient.CreateSender(startTranscriptionQueueName);
var fetchTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
- var fetchTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(FetchTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString).EntityPath;
+ var fetchTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.FetchTranscriptionServiceBusConnectionString).EntityPath;
this.fetchTranscriptionServiceBusSender = fetchTranscriptionServiceBusClient.CreateSender(fetchTranscriptionQueueName);
- if (!string.IsNullOrWhiteSpace(FetchTranscriptionEnvironmentVariables.CompletedServiceBusConnectionString))
+ if (!string.IsNullOrWhiteSpace(this.appConfig.CompletedServiceBusConnectionString))
{
var completedTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.CompletedTranscriptionServiceBusClient.ToString());
- var completedTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(FetchTranscriptionEnvironmentVariables.CompletedServiceBusConnectionString).EntityPath;
+ var completedTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.CompletedServiceBusConnectionString).EntityPath;
this.completedTranscriptionServiceBusSender = completedTranscriptionServiceBusClient.CreateSender(completedTranscriptionQueueName);
}
}
@@ -70,12 +76,12 @@ public async Task ProcessTranscriptionJobAsync(TranscriptionStartedMessage servi
throw new ArgumentNullException(nameof(serviceBusMessage));
}
- var subscriptionKey = FetchTranscriptionEnvironmentVariables.AzureSpeechServicesKey;
+ var subscriptionKey = this.appConfig.AzureSpeechServicesKey;
var jobName = serviceBusMessage.JobName;
var transcriptionLocation = serviceBusMessage.TranscriptionLocation;
log.LogInformation($"Received transcription at {transcriptionLocation} with name {jobName} from service bus message.");
- var messageDelayTime = GetMessageDelayTime(serviceBusMessage.PollingCounter);
+ var messageDelayTime = GetMessageDelayTime(serviceBusMessage.PollingCounter, this.appConfig);
serviceBusMessage.PollingCounter += 1;
try
@@ -149,18 +155,18 @@ await this.RetryOrFailJobAsync(
}
}
- private static TimeSpan GetMessageDelayTime(int pollingCounter)
+ private static TimeSpan GetMessageDelayTime(int pollingCounter, AppConfig appConfig)
{
if (pollingCounter == 0)
{
- return TimeSpan.FromMinutes(FetchTranscriptionEnvironmentVariables.InitialPollingDelayInMinutes);
+ return TimeSpan.FromMinutes(appConfig.InitialPollingDelayInMinutes);
}
- var updatedDelay = Math.Pow(2, Math.Min(pollingCounter, 8)) * FetchTranscriptionEnvironmentVariables.InitialPollingDelayInMinutes;
+ var updatedDelay = Math.Pow(2, Math.Min(pollingCounter, 8)) * appConfig.InitialPollingDelayInMinutes;
- if ((int)updatedDelay > FetchTranscriptionEnvironmentVariables.MaxPollingDelayInMinutes)
+ if ((int)updatedDelay > appConfig.MaxPollingDelayInMinutes)
{
- return TimeSpan.FromMinutes(FetchTranscriptionEnvironmentVariables.MaxPollingDelayInMinutes);
+ return TimeSpan.FromMinutes(appConfig.MaxPollingDelayInMinutes);
}
return TimeSpan.FromMinutes(updatedDelay);
@@ -193,7 +199,7 @@ private async Task ProcessFailedTranscriptionAsync(string transcriptionLocation,
errorReportOutput += $"\nReport file: \n {JsonConvert.SerializeObject(reportFileContent)}";
}
- var errorOutputContainer = FetchTranscriptionEnvironmentVariables.ErrorReportOutputContainer;
+ var errorOutputContainer = this.appConfig.ErrorReportOutputContainer;
await this.storageConnector.WriteTextFileToBlobAsync(errorReportOutput, errorOutputContainer, $"jobs/{jobName}.txt").ConfigureAwait(false);
var retryAudioFile = IsRetryableError(safeErrorCode);
@@ -202,7 +208,7 @@ private async Task ProcessFailedTranscriptionAsync(string transcriptionLocation,
{
var fileName = this.storageConnector.GetFileNameFromUri(new Uri(audio.FileUrl));
- if (retryAudioFile && audio.RetryCount < FetchTranscriptionEnvironmentVariables.RetryLimit)
+ if (retryAudioFile && audio.RetryCount < this.appConfig.RetryLimit)
{
log.LogInformation($"Retrying transcription with name {fileName} - retry count: {audio.RetryCount}");
var serviceBusMessage = new Connector.ServiceBusMessage
@@ -223,9 +229,9 @@ private async Task ProcessFailedTranscriptionAsync(string transcriptionLocation,
var message = $"Failed transcription with name {fileName} in job {jobName} after {audio.RetryCount} retries with error: {safeErrorMessage} (Error: {safeErrorCode}).";
await this.storageConnector.WriteTextFileToBlobAsync(message, errorOutputContainer, $"{fileName}.txt").ConfigureAwait(false);
await this.storageConnector.MoveFileAsync(
- FetchTranscriptionEnvironmentVariables.AudioInputContainer,
+ this.appConfig.AudioInputContainer,
fileName,
- FetchTranscriptionEnvironmentVariables.ErrorFilesOutputContainer,
+ this.appConfig.ErrorFilesOutputContainer,
fileName,
false).ConfigureAwait(false);
}
@@ -259,12 +265,12 @@ private async Task ProcessReportFileAsync(TranscriptionReportFile transcriptionR
var errorTxtname = fileName + ".txt";
await this.storageConnector.WriteTextFileToBlobAsync(
message,
- FetchTranscriptionEnvironmentVariables.ErrorReportOutputContainer,
+ this.appConfig.ErrorReportOutputContainer,
errorTxtname).ConfigureAwait(false);
await this.storageConnector.MoveFileAsync(
- FetchTranscriptionEnvironmentVariables.AudioInputContainer,
+ this.appConfig.AudioInputContainer,
fileName,
- FetchTranscriptionEnvironmentVariables.ErrorFilesOutputContainer,
+ this.appConfig.ErrorFilesOutputContainer,
fileName,
false).ConfigureAwait(false);
}
@@ -274,9 +280,9 @@ private async Task RetryOrFailJobAsync(TranscriptionStartedMessage message, stri
{
log.LogError(errorMessage);
message.FailedExecutionCounter += 1;
- var messageDelayTime = GetMessageDelayTime(message.PollingCounter);
+ var messageDelayTime = GetMessageDelayTime(message.PollingCounter, this.appConfig);
- if (message.FailedExecutionCounter <= FetchTranscriptionEnvironmentVariables.RetryLimit || isThrottled)
+ if (message.FailedExecutionCounter <= this.appConfig.RetryLimit || isThrottled)
{
log.LogInformation("Retrying..");
await ServiceBusUtilities.SendServiceBusMessageAsync(this.fetchTranscriptionServiceBusSender, message.CreateMessageString(), log, messageDelayTime).ConfigureAwait(false);
@@ -291,7 +297,7 @@ private async Task RetryOrFailJobAsync(TranscriptionStartedMessage message, stri
private async Task WriteFailedJobLogToStorageAsync(TranscriptionStartedMessage transcriptionStartedMessage, string errorMessage, string jobName, ILogger log)
{
log.LogError(errorMessage);
- var errorOutputContainer = FetchTranscriptionEnvironmentVariables.ErrorReportOutputContainer;
+ var errorOutputContainer = this.appConfig.ErrorReportOutputContainer;
var jobErrorFileName = $"jobs/{jobName}.txt";
await this.storageConnector.WriteTextFileToBlobAsync(errorMessage, errorOutputContainer, jobErrorFileName).ConfigureAwait(false);
@@ -304,9 +310,9 @@ private async Task WriteFailedJobLogToStorageAsync(TranscriptionStartedMessage t
{
await this.storageConnector.WriteTextFileToBlobAsync(errorMessage, errorOutputContainer, errorFileName).ConfigureAwait(false);
await this.storageConnector.MoveFileAsync(
- FetchTranscriptionEnvironmentVariables.AudioInputContainer,
+ this.appConfig.AudioInputContainer,
fileName,
- FetchTranscriptionEnvironmentVariables.ErrorFilesOutputContainer,
+ this.appConfig.ErrorFilesOutputContainer,
fileName,
false).ConfigureAwait(false);
}
@@ -323,7 +329,7 @@ private async Task WriteErrorReportAsync(string errorString, string jobName)
await this.storageConnector.WriteTextFileToBlobAsync(
errorString,
- FetchTranscriptionEnvironmentVariables.ErrorReportOutputContainer,
+ this.appConfig.ErrorReportOutputContainer,
errorTxtname).ConfigureAwait(false);
}
@@ -331,13 +337,13 @@ private async Task ProcessSucceededTranscriptionAsync(string transcriptionLocati
{
log.LogInformation($"Got succeeded transcription for job {jobName}");
- var transcriptionAnalyticsOrchestrator = new TranscriptionAnalyticsOrchestrator(serviceBusMessage.Locale, log);
+ var transcriptionAnalyticsOrchestrator = new TranscriptionAnalyticsOrchestrator(serviceBusMessage.Locale, log, Options.Create(this.appConfig));
var transcriptionAnalyticsJobStatus = await transcriptionAnalyticsOrchestrator.GetTranscriptionAnalyticsJobsStatusAsync(serviceBusMessage).ConfigureAwait(false);
if (transcriptionAnalyticsJobStatus == TranscriptionAnalyticsJobStatus.Running)
{
// If transcription analytics request is still running, re-queue message and get status again after X minutes:
log.LogInformation($"Transcription analytics requests still running for job {jobName} - re-queueing message.");
- await ServiceBusUtilities.SendServiceBusMessageAsync(this.fetchTranscriptionServiceBusSender, serviceBusMessage.CreateMessageString(), log, GetMessageDelayTime(serviceBusMessage.PollingCounter)).ConfigureAwait(false);
+ await ServiceBusUtilities.SendServiceBusMessageAsync(this.fetchTranscriptionServiceBusSender, serviceBusMessage.CreateMessageString(), log, GetMessageDelayTime(serviceBusMessage.PollingCounter, this.appConfig)).ConfigureAwait(false);
return;
}
@@ -436,47 +442,47 @@ private async Task ProcessSucceededTranscriptionAsync(string transcriptionLocati
var jsonFileName = $"{fileName}.json";
var archiveFileLocation = System.IO.Path.GetFileNameWithoutExtension(fileName);
- var jsonFileUrl = await this.storageConnector.WriteTextFileToBlobAsync(editedTranscriptionResultJson, FetchTranscriptionEnvironmentVariables.JsonResultOutputContainer, jsonFileName).ConfigureAwait(false);
+ var jsonFileUrl = await this.storageConnector.WriteTextFileToBlobAsync(editedTranscriptionResultJson, this.appConfig.JsonResultOutputContainer, jsonFileName).ConfigureAwait(false);
- if (!string.IsNullOrEmpty(FetchTranscriptionEnvironmentVariables.CompletedServiceBusConnectionString))
+ if (!string.IsNullOrEmpty(this.appConfig.CompletedServiceBusConnectionString))
{
var completedMessage = new CompletedMessage(audioFileInfo.FileUrl, jsonFileUrl);
completedMessages.Add(completedMessage);
}
- var consolidatedContainer = FetchTranscriptionEnvironmentVariables.ConsolidatedFilesOutputContainer;
- if (FetchTranscriptionEnvironmentVariables.CreateConsolidatedOutputFiles)
+ var consolidatedContainer = this.appConfig.ConsolidatedFilesOutputContainer;
+ if (this.appConfig.CreateConsolidatedOutputFiles)
{
var audioArchiveFileName = $"{archiveFileLocation}/{fileName}";
var jsonArchiveFileName = $"{archiveFileLocation}/{jsonFileName}";
- await this.storageConnector.MoveFileAsync(FetchTranscriptionEnvironmentVariables.AudioInputContainer, fileName, consolidatedContainer, audioArchiveFileName, true).ConfigureAwait(false);
+ await this.storageConnector.MoveFileAsync(this.appConfig.AudioInputContainer, fileName, consolidatedContainer, audioArchiveFileName, true).ConfigureAwait(false);
await this.storageConnector.WriteTextFileToBlobAsync(editedTranscriptionResultJson, consolidatedContainer, jsonArchiveFileName).ConfigureAwait(false);
}
- if (FetchTranscriptionEnvironmentVariables.CreateHtmlResultFile)
+ if (this.appConfig.CreateHtmlResultFile)
{
- var htmlContainer = FetchTranscriptionEnvironmentVariables.HtmlResultOutputContainer;
+ var htmlContainer = this.appConfig.HtmlResultOutputContainer;
var htmlFileName = $"{fileName}.html";
var displayResults = TranscriptionToHtml.ToHtml(speechTranscript, jobName);
await this.storageConnector.WriteTextFileToBlobAsync(displayResults, htmlContainer, htmlFileName).ConfigureAwait(false);
- if (FetchTranscriptionEnvironmentVariables.CreateConsolidatedOutputFiles)
+ if (this.appConfig.CreateConsolidatedOutputFiles)
{
var htmlArchiveFileName = $"{archiveFileLocation}/{htmlFileName}";
await this.storageConnector.WriteTextFileToBlobAsync(displayResults, consolidatedContainer, htmlArchiveFileName).ConfigureAwait(false);
}
}
- if (FetchTranscriptionEnvironmentVariables.UseSqlDatabase)
+ if (this.appConfig.UseSqlDatabase)
{
var duration = string.IsNullOrEmpty(speechTranscript.Duration) ? TimeSpan.Zero : XmlConvert.ToTimeSpan(speechTranscript.Duration);
var approximatedCost = CostEstimation.GetCostEstimation(
duration,
speechTranscript.CombinedRecognizedPhrases.Count(),
serviceBusMessage.UsesCustomModel,
- FetchTranscriptionEnvironmentVariables.SentimentAnalysisSetting,
- FetchTranscriptionEnvironmentVariables.PiiRedactionSetting);
+ this.appConfig.SentimentAnalysisSetting,
+ this.appConfig.PiiRedactionSetting);
var containsMultipleTranscriptions = resultFiles.Skip(1).Any();
var jobId = containsMultipleTranscriptions ? Guid.NewGuid() : new Guid(transcriptionLocation.Split('/').LastOrDefault());
@@ -498,15 +504,15 @@ await this.databaseContext.StoreTranscriptionAsync(
}
}
- if (FetchTranscriptionEnvironmentVariables.CreateAudioProcessedContainer)
+ if (this.appConfig.CreateAudioProcessedContainer)
{
- await this.storageConnector.MoveFileAsync(FetchTranscriptionEnvironmentVariables.AudioInputContainer, fileName, FetchTranscriptionEnvironmentVariables.AudioProcessedContainer, fileName, false).ConfigureAwait(false);
+ await this.storageConnector.MoveFileAsync(this.appConfig.AudioInputContainer, fileName, this.appConfig.AudioProcessedContainer, fileName, false).ConfigureAwait(false);
}
}
if (this.completedTranscriptionServiceBusSender != null)
{
- await ServiceBusUtilities.SendServiceBusMessageAsync(this.completedTranscriptionServiceBusSender, JsonConvert.SerializeObject(completedMessages), log, GetMessageDelayTime(serviceBusMessage.PollingCounter)).ConfigureAwait(false);
+ await ServiceBusUtilities.SendServiceBusMessageAsync(this.completedTranscriptionServiceBusSender, JsonConvert.SerializeObject(completedMessages), log, GetMessageDelayTime(serviceBusMessage.PollingCounter, this.appConfig)).ConfigureAwait(false);
}
var generalErrors = generalErrorsStringBuilder.ToString();
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/Program.cs b/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/Program.cs
index ff471b03c..32c83453c 100644
--- a/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/Program.cs
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/Program.cs
@@ -5,6 +5,8 @@
namespace StartTranscription
{
+ using System.IO;
+
using Azure.Storage;
using Azure.Storage.Blobs;
@@ -12,6 +14,7 @@ namespace StartTranscription
using Connector.Enums;
using Microsoft.Extensions.Azure;
+ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -28,30 +31,40 @@ public static class Program
///
public static void Main(string[] args)
{
- var storageConnectionString = StartTranscriptionEnvironmentVariables.AzureWebJobsStorage;
- var blobServiceClient = new BlobServiceClient(storageConnectionString);
-
- var storageCredential = new StorageSharedKeyCredential(
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", storageConnectionString),
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", storageConnectionString));
-
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
- .ConfigureServices(s =>
+ .ConfigureAppConfiguration((context, config) =>
{
+ config.SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
+ .AddEnvironmentVariables();
+ })
+ .ConfigureServices((context, services) =>
+ {
+ var configuration = context.Configuration;
+ var config = new AppConfig();
+ configuration.GetSection("Values").Bind(config);
+
+ var blobServiceClient = new BlobServiceClient(config.AzureWebJobsStorage);
+ var storageCredential = new StorageSharedKeyCredential(
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", config.AzureWebJobsStorage),
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", config.AzureWebJobsStorage));
+
// This is a unified way to configure logging filter for all functions.
- s.ConfigureIngestionClientLogging();
- s.AddSingleton(blobServiceClient);
- s.AddSingleton(storageCredential);
- s.AddTransient();
+ services.ConfigureIngestionClientLogging();
+ services.AddSingleton(blobServiceClient);
+ services.AddSingleton(storageCredential);
+ services.AddTransient();
+ services.AddTransient();
- s.AddAzureClients(clientBuilder =>
+ services.AddAzureClients(clientBuilder =>
{
- clientBuilder.AddServiceBusClient(StartTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.StartTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
- clientBuilder.AddServiceBusClient(StartTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.FetchTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
});
+ services.Configure(configuration.GetSection("Values"));
})
.Build();
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/StartTranscriptionByServiceBus.cs b/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/StartTranscriptionByServiceBus.cs
index cd4487084..c89e34ccc 100644
--- a/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/StartTranscriptionByServiceBus.cs
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByServiceBus/StartTranscriptionByServiceBus.cs
@@ -9,11 +9,7 @@ namespace StartTranscription
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
- using Connector;
- using Connector.Enums;
-
using Microsoft.Azure.Functions.Worker;
- using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;
using StartTranscriptionByTimer;
@@ -23,39 +19,19 @@ namespace StartTranscription
public class StartTranscriptionByServiceBus
{
private readonly ILogger logger;
-
- private readonly IStorageConnector storageConnector;
-
- private readonly ServiceBusReceiver startTranscriptionServiceBusReceiver;
-
- private readonly ServiceBusSender startTranscriptionServiceBusSender;
-
- private readonly ServiceBusSender fetchTranscriptionServiceBusSender;
+ private readonly IStartTranscriptionHelper transcriptionHelper;
///
/// Initializes a new instance of the class.
///
/// The StartTranscriptionByServiceBus Logger
- /// Storage connector dependency
- /// Azure client factory for service bus clients
+ ///
public StartTranscriptionByServiceBus(
ILogger logger,
- IStorageConnector storageConnector,
- IAzureClientFactory serviceBusClientFactory)
+ IStartTranscriptionHelper transcriptionHelper)
{
this.logger = logger;
- this.storageConnector = storageConnector;
-
- serviceBusClientFactory = serviceBusClientFactory ?? throw new ArgumentNullException(nameof(serviceBusClientFactory));
- var startTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
-
- var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(StartTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString).EntityPath;
- this.startTranscriptionServiceBusReceiver = startTranscriptionServiceBusClient.CreateReceiver(startTranscriptionQueueName);
- this.startTranscriptionServiceBusSender = startTranscriptionServiceBusClient.CreateSender(startTranscriptionQueueName);
-
- var fetchTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
- var fetchTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(StartTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString).EntityPath;
- this.fetchTranscriptionServiceBusSender = fetchTranscriptionServiceBusClient.CreateSender(fetchTranscriptionQueueName);
+ this.transcriptionHelper = transcriptionHelper;
}
///
@@ -72,20 +48,13 @@ public async Task Run([ServiceBusTrigger("start_transcription_queue", Connection
this.logger.LogInformation($"C# Isolated ServiceBus queue trigger function processed message: {message.Subject}");
this.logger.LogInformation($"Received message: SequenceNumber:{message.SequenceNumber} Body:{message.Body}");
- var transcriptionHelper = new StartTranscriptionHelper(
- this.logger,
- this.storageConnector,
- this.startTranscriptionServiceBusSender,
- this.startTranscriptionServiceBusReceiver,
- this.fetchTranscriptionServiceBusSender);
-
- if (message == null || !transcriptionHelper.IsValidServiceBusMessage(message))
+ if (message == null || !this.transcriptionHelper.IsValidServiceBusMessage(message))
{
this.logger.LogInformation($"Service bus message is invalid.");
return;
}
- await transcriptionHelper.StartTranscriptionAsync(message).ConfigureAwait(false);
+ await this.transcriptionHelper.StartTranscriptionAsync(message).ConfigureAwait(false);
}
}
}
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Config/AppConfig.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Config/AppConfig.cs
new file mode 100644
index 000000000..672e0d552
--- /dev/null
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Config/AppConfig.cs
@@ -0,0 +1,83 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace StartTranscriptionByTimer
+{
+ using System;
+
+ using Connector.Constants;
+
+ public class AppConfig
+ {
+ private int messagesPerFunctionExecution = Constants.DefaultMessagesPerFunctionExecution;
+
+ private int filesPerTranscriptionJob = Constants.DefaultFilesPerTranscriptionJob;
+
+ private int initialPollingDelayInMinutes = Constants.DefaultInitialPollingDelayInMinutes;
+ private int retryLimit = Constants.DefaultRetryLimit;
+
+ public bool AddDiarization { get; set; }
+
+ public bool AddWordLevelTimestamps { get; set; }
+
+ public bool IsAzureGovDeployment { get; set; }
+
+ public bool IsByosEnabledSubscription { get; set; }
+
+ public int MessagesPerFunctionExecution
+ {
+ get => this.messagesPerFunctionExecution;
+ set => this.messagesPerFunctionExecution = Math.Clamp(value, 1, Constants.MaxMessagesPerFunctionExecution);
+ }
+
+ public int FilesPerTranscriptionJob
+ {
+ get => this.filesPerTranscriptionJob;
+ set => this.filesPerTranscriptionJob = Math.Clamp(value, 1, Constants.MaxFilesPerTranscriptionJob);
+ }
+
+ public int RetryLimit
+ {
+ get => this.retryLimit;
+ set => this.retryLimit = Math.Clamp(value, 1, Constants.MaxRetryLimit);
+ }
+
+ public int InitialPollingDelayInMinutes
+ {
+ get => this.initialPollingDelayInMinutes;
+ set => this.initialPollingDelayInMinutes = Math.Clamp(value, 2, Constants.MaxInitialPollingDelayInMinutes);
+ }
+
+ public int MaxPollingDelayInMinutes { get; set; } = Constants.DefaultMaxPollingDelayInMinutes;
+
+ public string AudioInputContainer { get; set; }
+
+ public string AzureServiceBus { get; set; }
+
+ public string AzureSpeechServicesKey { get; set; }
+
+ public string AzureSpeechServicesEndpointUri { get; set; }
+
+ public string AzureWebJobsStorage { get; set; }
+
+ public string CustomModelId { get; set; }
+
+ public string ErrorFilesOutputContainer { get; set; }
+
+ public string ErrorReportOutputContainer { get; set; }
+
+ public string FetchTranscriptionServiceBusConnectionString { get; set; }
+
+ public string Locale { get; set; }
+
+ public string ProfanityFilterMode { get; set; }
+
+ public string PunctuationMode { get; set; }
+
+ public string StartTranscriptionServiceBusConnectionString { get; set; }
+
+ public string StartTranscriptionFunctionTimeInterval { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Interfaces/IStartTranscriptionHelper.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Interfaces/IStartTranscriptionHelper.cs
new file mode 100644
index 000000000..13a80fc4d
--- /dev/null
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Interfaces/IStartTranscriptionHelper.cs
@@ -0,0 +1,21 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace StartTranscriptionByTimer
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+ using Azure.Messaging.ServiceBus;
+
+ public interface IStartTranscriptionHelper
+ {
+ Task StartTranscriptionsAsync(IEnumerable messages, DateTime startDateTime);
+
+ Task StartTranscriptionAsync(ServiceBusReceivedMessage message);
+
+ bool IsValidServiceBusMessage(ServiceBusReceivedMessage message);
+ }
+}
\ No newline at end of file
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Program.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Program.cs
index d8d59a99d..7c222c81d 100644
--- a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Program.cs
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/Program.cs
@@ -5,6 +5,8 @@
namespace StartTranscriptionByTimer
{
+ using System.IO;
+
using Azure.Storage;
using Azure.Storage.Blobs;
@@ -12,6 +14,7 @@ namespace StartTranscriptionByTimer
using Connector.Enums;
using Microsoft.Extensions.Azure;
+ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -19,30 +22,41 @@ public static class Program
{
public static void Main(string[] args)
{
- var storageConnectionString = StartTranscriptionEnvironmentVariables.AzureWebJobsStorage;
- var blobServiceClient = new BlobServiceClient(storageConnectionString);
-
- var storageCredential = new StorageSharedKeyCredential(
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", storageConnectionString),
- AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", storageConnectionString));
-
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
- .ConfigureServices(s =>
+
+ .ConfigureAppConfiguration((context, config) =>
{
+ config.SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
+ .AddEnvironmentVariables();
+ })
+ .ConfigureServices((context, services) =>
+ {
+ var configuration = context.Configuration;
+ var config = new AppConfig();
+ configuration.GetSection("Values").Bind(config);
+
+ var blobServiceClient = new BlobServiceClient(config.AzureWebJobsStorage);
+ var storageCredential = new StorageSharedKeyCredential(
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountName", config.AzureWebJobsStorage),
+ AzureStorageConnectionExtensions.GetValueFromConnectionString("AccountKey", config.AzureWebJobsStorage));
+
// This is a unified way to configure logging filter for all functions.
- s.ConfigureIngestionClientLogging();
- s.AddSingleton(blobServiceClient);
- s.AddSingleton(storageCredential);
- s.AddTransient();
+ services.ConfigureIngestionClientLogging();
+ services.AddSingleton(blobServiceClient);
+ services.AddSingleton(storageCredential);
+ services.AddTransient();
+ services.AddTransient();
- s.AddAzureClients(clientBuilder =>
+ services.AddAzureClients(clientBuilder =>
{
- clientBuilder.AddServiceBusClient(StartTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.StartTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
- clientBuilder.AddServiceBusClient(StartTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString)
+ clientBuilder.AddServiceBusClient(config.FetchTranscriptionServiceBusConnectionString)
.WithName(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
});
+ services.Configure(configuration.GetSection("Values"));
})
.Build();
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionByTimer.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionByTimer.cs
index f1b0a1dd4..586014391 100644
--- a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionByTimer.cs
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionByTimer.cs
@@ -17,6 +17,7 @@ namespace StartTranscriptionByTimer
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
///
/// Start Transcription By Timer class.
@@ -27,37 +28,34 @@ public class StartTranscriptionByTimer
private readonly ILogger logger;
- private readonly IStorageConnector storageConnector;
-
private readonly ServiceBusReceiver startTranscriptionServiceBusReceiver;
- private readonly ServiceBusSender startTranscriptionServiceBusSender;
+ private readonly AppConfig appConfig;
- private readonly ServiceBusSender fetchTranscriptionServiceBusSender;
+ private readonly IStartTranscriptionHelper transcriptionHelper;
///
/// Initializes a new instance of the class.
///
/// The StartTranscriptionByTimer logger
- /// Storage connector dependency
- /// Azure client factory for service bus clients
+ /// environment configuration
+ ///
+ ///
public StartTranscriptionByTimer(
ILogger logger,
- IStorageConnector storageConnector,
- IAzureClientFactory serviceBusClientFactory)
+ IOptions appConfig,
+ IAzureClientFactory serviceBusClientFactory,
+ IStartTranscriptionHelper transcriptionHelper)
{
this.logger = logger;
- this.storageConnector = storageConnector;
+ this.appConfig = appConfig?.Value;
+ this.transcriptionHelper = transcriptionHelper;
+
serviceBusClientFactory = serviceBusClientFactory ?? throw new ArgumentNullException(nameof(serviceBusClientFactory));
var startTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
- var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(StartTranscriptionEnvironmentVariables.StartTranscriptionServiceBusConnectionString).EntityPath;
+ var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.StartTranscriptionServiceBusConnectionString).EntityPath;
this.startTranscriptionServiceBusReceiver = startTranscriptionServiceBusClient.CreateReceiver(startTranscriptionQueueName);
- this.startTranscriptionServiceBusSender = startTranscriptionServiceBusClient.CreateSender(startTranscriptionQueueName);
-
- var fetchTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
- var fetchTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(StartTranscriptionEnvironmentVariables.FetchTranscriptionServiceBusConnectionString).EntityPath;
- this.fetchTranscriptionServiceBusSender = fetchTranscriptionServiceBusClient.CreateSender(fetchTranscriptionQueueName);
}
///
@@ -75,15 +73,9 @@ public async Task Run([TimerTrigger("%StartTranscriptionFunctionTimeInterval%")]
this.logger.LogInformation($"C# Isolated Timer trigger function v4 executed at: {startDateTime}. Next occurrence on {timerInfo.ScheduleStatus.Next}.");
var validServiceBusMessages = new List();
- var transcriptionHelper = new StartTranscriptionHelper(
- this.logger,
- this.storageConnector,
- this.startTranscriptionServiceBusSender,
- this.startTranscriptionServiceBusReceiver,
- this.fetchTranscriptionServiceBusSender);
this.logger.LogInformation("Pulling messages from queue...");
- var messages = await this.startTranscriptionServiceBusReceiver.ReceiveMessagesAsync(StartTranscriptionEnvironmentVariables.MessagesPerFunctionExecution, TimeSpan.FromSeconds(MessageReceiveTimeoutInSeconds)).ConfigureAwait(false);
+ var messages = await this.startTranscriptionServiceBusReceiver.ReceiveMessagesAsync(this.appConfig.MessagesPerFunctionExecution, TimeSpan.FromSeconds(MessageReceiveTimeoutInSeconds)).ConfigureAwait(false);
if (messages == null || !messages.Any())
{
@@ -98,7 +90,7 @@ public async Task Run([TimerTrigger("%StartTranscriptionFunctionTimeInterval%")]
{
try
{
- if (transcriptionHelper.IsValidServiceBusMessage(message))
+ if (this.transcriptionHelper.IsValidServiceBusMessage(message))
{
await this.startTranscriptionServiceBusReceiver.RenewMessageLockAsync(message).ConfigureAwait(false);
validServiceBusMessages.Add(message);
@@ -123,7 +115,7 @@ public async Task Run([TimerTrigger("%StartTranscriptionFunctionTimeInterval%")]
this.logger.LogInformation($"Pulled {validServiceBusMessages.Count} valid messages from queue.");
- await transcriptionHelper.StartTranscriptionsAsync(validServiceBusMessages, startDateTime).ConfigureAwait(false);
+ await this.transcriptionHelper.StartTranscriptionsAsync(validServiceBusMessages, startDateTime).ConfigureAwait(false);
}
}
}
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionEnvironmentVariables.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionEnvironmentVariables.cs
deleted file mode 100644
index f3194d5c9..000000000
--- a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionEnvironmentVariables.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
-//
-
-namespace StartTranscriptionByTimer
-{
- using System;
- using Connector;
- using Connector.Constants;
-
- public static class StartTranscriptionEnvironmentVariables
- {
- public static readonly bool AddDiarization = bool.TryParse(Environment.GetEnvironmentVariable(nameof(AddDiarization), EnvironmentVariableTarget.Process), out AddDiarization) && AddDiarization;
-
- public static readonly bool AddWordLevelTimestamps = bool.TryParse(Environment.GetEnvironmentVariable(nameof(AddWordLevelTimestamps), EnvironmentVariableTarget.Process), out AddWordLevelTimestamps) && AddWordLevelTimestamps;
-
- public static readonly bool IsAzureGovDeployment = bool.TryParse(Environment.GetEnvironmentVariable(nameof(IsAzureGovDeployment), EnvironmentVariableTarget.Process), out IsAzureGovDeployment) && IsAzureGovDeployment;
-
- // BYOS = Bring your own storage (https://docs.microsoft.com/azure/cognitive-services/speech-service/speech-encryption-of-data-at-rest#bring-your-own-storage-byos-for-customization-and-logging)
- public static readonly bool IsByosEnabledSubscription = bool.TryParse(Environment.GetEnvironmentVariable(nameof(IsByosEnabledSubscription), EnvironmentVariableTarget.Process), out IsByosEnabledSubscription) && IsByosEnabledSubscription;
-
- public static readonly int MessagesPerFunctionExecution = int.TryParse(Environment.GetEnvironmentVariable(nameof(MessagesPerFunctionExecution), EnvironmentVariableTarget.Process), out MessagesPerFunctionExecution) ? MessagesPerFunctionExecution.ClampInt(1, Constants.MaxMessagesPerFunctionExecution) : Constants.DefaultMessagesPerFunctionExecution;
-
- public static readonly int FilesPerTranscriptionJob = int.TryParse(Environment.GetEnvironmentVariable(nameof(FilesPerTranscriptionJob), EnvironmentVariableTarget.Process), out FilesPerTranscriptionJob) ? FilesPerTranscriptionJob.ClampInt(1, Constants.MaxFilesPerTranscriptionJob) : Constants.DefaultFilesPerTranscriptionJob;
-
- public static readonly int RetryLimit = int.TryParse(Environment.GetEnvironmentVariable(nameof(RetryLimit), EnvironmentVariableTarget.Process), out RetryLimit) ? RetryLimit.ClampInt(1, Constants.MaxRetryLimit) : Constants.DefaultRetryLimit;
-
- public static readonly int InitialPollingDelayInMinutes = int.TryParse(Environment.GetEnvironmentVariable(nameof(InitialPollingDelayInMinutes), EnvironmentVariableTarget.Process), out InitialPollingDelayInMinutes) ? InitialPollingDelayInMinutes.ClampInt(2, Constants.MaxInitialPollingDelayInMinutes) : Constants.DefaultInitialPollingDelayInMinutes;
-
- public static readonly int MaxPollingDelayInMinutes = int.TryParse(Environment.GetEnvironmentVariable(nameof(MaxPollingDelayInMinutes), EnvironmentVariableTarget.Process), out MaxPollingDelayInMinutes) ? MaxPollingDelayInMinutes : Constants.DefaultMaxPollingDelayInMinutes;
-
- public static readonly string AudioInputContainer = Environment.GetEnvironmentVariable(nameof(AudioInputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string AzureServiceBus = Environment.GetEnvironmentVariable(nameof(AzureServiceBus), EnvironmentVariableTarget.Process);
-
- public static readonly string AzureSpeechServicesKey = Environment.GetEnvironmentVariable(nameof(AzureSpeechServicesKey), EnvironmentVariableTarget.Process);
-
- public static readonly string AzureSpeechServicesEndpointUri = Environment.GetEnvironmentVariable(nameof(AzureSpeechServicesEndpointUri), EnvironmentVariableTarget.Process).TrimEnd('/') + '/';
-
- public static readonly string AzureWebJobsStorage = Environment.GetEnvironmentVariable(nameof(AzureWebJobsStorage), EnvironmentVariableTarget.Process);
-
- public static readonly string CustomModelId = Environment.GetEnvironmentVariable(nameof(CustomModelId), EnvironmentVariableTarget.Process);
-
- public static readonly string ErrorFilesOutputContainer = Environment.GetEnvironmentVariable(nameof(ErrorFilesOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string ErrorReportOutputContainer = Environment.GetEnvironmentVariable(nameof(ErrorReportOutputContainer), EnvironmentVariableTarget.Process);
-
- public static readonly string FetchTranscriptionServiceBusConnectionString = Environment.GetEnvironmentVariable(nameof(FetchTranscriptionServiceBusConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string Locale = Environment.GetEnvironmentVariable(nameof(Locale), EnvironmentVariableTarget.Process);
-
- public static readonly string ProfanityFilterMode = Environment.GetEnvironmentVariable(nameof(ProfanityFilterMode), EnvironmentVariableTarget.Process);
-
- public static readonly string PunctuationMode = Environment.GetEnvironmentVariable(nameof(PunctuationMode), EnvironmentVariableTarget.Process);
-
- public static readonly string StartTranscriptionServiceBusConnectionString = Environment.GetEnvironmentVariable(nameof(StartTranscriptionServiceBusConnectionString), EnvironmentVariableTarget.Process);
-
- public static readonly string StartTranscriptionFunctionTimeInterval = Environment.GetEnvironmentVariable(nameof(StartTranscriptionFunctionTimeInterval), EnvironmentVariableTarget.Process);
- }
-}
diff --git a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionHelper.cs b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionHelper.cs
index 2a3871b53..b89da2d3b 100644
--- a/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionHelper.cs
+++ b/samples/ingestion/ingestion-client/StartTranscriptionByTimer/StartTranscriptionHelper.cs
@@ -16,11 +16,18 @@ namespace StartTranscriptionByTimer
using Azure;
using Azure.Messaging.ServiceBus;
using Connector;
+ using Connector.Enums;
+
using Connector.Serializable.TranscriptionStartedServiceBusMessage;
+
+ using Microsoft.Extensions.Azure;
+
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
+
using Newtonsoft.Json;
- public class StartTranscriptionHelper
+ public class StartTranscriptionHelper : IStartTranscriptionHelper
{
private readonly ServiceBusSender startTranscriptionSender;
@@ -28,34 +35,33 @@ public class StartTranscriptionHelper
private readonly ServiceBusSender fetchTranscriptionSender;
- private readonly string subscriptionKey = StartTranscriptionEnvironmentVariables.AzureSpeechServicesKey;
-
- private readonly string errorReportContaineName = StartTranscriptionEnvironmentVariables.ErrorReportOutputContainer;
-
- private readonly string audioInputContainerName = StartTranscriptionEnvironmentVariables.AudioInputContainer;
-
- private readonly int filesPerTranscriptionJob = StartTranscriptionEnvironmentVariables.FilesPerTranscriptionJob;
-
- private readonly ILogger logger;
+ private readonly ILogger logger;
private readonly string locale;
private readonly IStorageConnector storageConnector;
+ private readonly AppConfig appConfig;
+
public StartTranscriptionHelper(
- ILogger logger,
+ ILogger logger,
IStorageConnector storageConnector,
- ServiceBusSender startTranscriptionSender,
- ServiceBusReceiver startTranscriptionReceiver,
- ServiceBusSender fetchTranscriptionSender)
+ IAzureClientFactory serviceBusClientFactory,
+ IOptions appConfig)
{
this.logger = logger;
this.storageConnector = storageConnector;
- this.locale = StartTranscriptionEnvironmentVariables.Locale.Split('|')[0].Trim();
-
- this.startTranscriptionSender = startTranscriptionSender;
- this.startTranscriptionReceiver = startTranscriptionReceiver;
- this.fetchTranscriptionSender = fetchTranscriptionSender;
+ this.appConfig = appConfig?.Value;
+ this.locale = this.appConfig.Locale.Split('|')[0].Trim();
+
+ serviceBusClientFactory = serviceBusClientFactory ?? throw new ArgumentNullException(nameof(serviceBusClientFactory));
+ var startTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString());
+ var startTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.StartTranscriptionServiceBusConnectionString).EntityPath;
+ this.startTranscriptionReceiver = startTranscriptionServiceBusClient.CreateReceiver(startTranscriptionQueueName);
+ this.startTranscriptionSender = startTranscriptionServiceBusClient.CreateSender(startTranscriptionQueueName);
+ var fetchTranscriptionServiceBusClient = serviceBusClientFactory.CreateClient(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString());
+ var fetchTranscriptionQueueName = ServiceBusConnectionStringProperties.Parse(this.appConfig.FetchTranscriptionServiceBusConnectionString).EntityPath;
+ this.fetchTranscriptionSender = fetchTranscriptionServiceBusClient.CreateSender(fetchTranscriptionQueueName);
}
public async Task StartTranscriptionsAsync(IEnumerable messages, DateTime startDateTime)
@@ -63,9 +69,9 @@ public async Task StartTranscriptionsAsync(IEnumerable>();
var messageCount = messages.Count();
- for (var i = 0; i < messageCount; i += this.filesPerTranscriptionJob)
+ for (var i = 0; i < messageCount; i += this.appConfig.FilesPerTranscriptionJob)
{
- var chunk = messages.Skip(i).Take(Math.Min(this.filesPerTranscriptionJob, messageCount - i)).ToList();
+ var chunk = messages.Skip(i).Take(Math.Min(this.appConfig.FilesPerTranscriptionJob, messageCount - i)).ToList();
chunkedMessages.Add(chunk);
}
@@ -135,7 +141,7 @@ public bool IsValidServiceBusMessage(ServiceBusReceivedMessage message)
var serviceBusMessage = JsonConvert.DeserializeObject(messageBody);
if (serviceBusMessage.EventType.Contains("BlobCreate", StringComparison.OrdinalIgnoreCase) &&
- this.storageConnector.GetContainerNameFromUri(serviceBusMessage.Data.Url).Equals(this.audioInputContainerName, StringComparison.Ordinal))
+ this.storageConnector.GetContainerNameFromUri(serviceBusMessage.Data.Url).Equals(this.appConfig.AudioInputContainer, StringComparison.Ordinal))
{
return true;
}
@@ -149,18 +155,18 @@ public bool IsValidServiceBusMessage(ServiceBusReceivedMessage message)
return false;
}
- private static TimeSpan GetMessageDelayTime(int pollingCounter)
+ private static TimeSpan GetMessageDelayTime(int pollingCounter, AppConfig appConfig)
{
if (pollingCounter == 0)
{
- return TimeSpan.FromMinutes(StartTranscriptionEnvironmentVariables.InitialPollingDelayInMinutes);
+ return TimeSpan.FromMinutes(appConfig.InitialPollingDelayInMinutes);
}
- var updatedDelay = Math.Pow(2, Math.Min(pollingCounter, 8)) * StartTranscriptionEnvironmentVariables.InitialPollingDelayInMinutes;
+ var updatedDelay = Math.Pow(2, Math.Min(pollingCounter, 8)) * appConfig.InitialPollingDelayInMinutes;
- if ((int)updatedDelay > StartTranscriptionEnvironmentVariables.MaxPollingDelayInMinutes)
+ if ((int)updatedDelay > appConfig.MaxPollingDelayInMinutes)
{
- return TimeSpan.FromMinutes(StartTranscriptionEnvironmentVariables.MaxPollingDelayInMinutes);
+ return TimeSpan.FromMinutes(appConfig.MaxPollingDelayInMinutes);
}
return TimeSpan.FromMinutes(updatedDelay);
@@ -200,7 +206,7 @@ private async Task StartBatchTranscriptionJobAsync(IEnumerable(Encoding.UTF8.GetString(message.Body));
- if (serviceBusMessage.RetryCount <= StartTranscriptionEnvironmentVariables.RetryLimit || isThrottled)
+ if (serviceBusMessage.RetryCount <= this.appConfig.RetryLimit || isThrottled)
{
serviceBusMessage.RetryCount += 1;
- var messageDelay = GetMessageDelayTime(serviceBusMessage.RetryCount);
+ var messageDelay = GetMessageDelayTime(serviceBusMessage.RetryCount, this.appConfig);
var newMessage = new Azure.Messaging.ServiceBus.ServiceBusMessage(JsonConvert.SerializeObject(serviceBusMessage));
await ServiceBusUtilities.SendServiceBusMessageAsync(this.startTranscriptionSender, newMessage, this.logger, messageDelay).ConfigureAwait(false);
}
@@ -304,7 +310,7 @@ private async Task WriteFailedJobLogToStorageAsync(IEnumerable GetTranscriptionPropertyBag()
{
var properties = new Dictionary();
- var profanityFilterMode = StartTranscriptionEnvironmentVariables.ProfanityFilterMode;
+ var profanityFilterMode = this.appConfig.ProfanityFilterMode;
properties.Add("ProfanityFilterMode", profanityFilterMode);
this.logger.LogInformation($"Setting profanity filter mode to {profanityFilterMode}");
- var punctuationMode = StartTranscriptionEnvironmentVariables.PunctuationMode;
+ var punctuationMode = this.appConfig.PunctuationMode;
punctuationMode = punctuationMode.Replace(" ", string.Empty, StringComparison.Ordinal);
properties.Add("PunctuationMode", punctuationMode);
this.logger.LogInformation($"Setting punctuation mode to {punctuationMode}");
- var addDiarization = StartTranscriptionEnvironmentVariables.AddDiarization;
+ var addDiarization = this.appConfig.AddDiarization;
properties.Add("DiarizationEnabled", addDiarization.ToString(CultureInfo.InvariantCulture));
this.logger.LogInformation($"Setting diarization enabled to {addDiarization}");
- var addWordLevelTimestamps = StartTranscriptionEnvironmentVariables.AddWordLevelTimestamps;
+ var addWordLevelTimestamps = this.appConfig.AddWordLevelTimestamps;
properties.Add("WordLevelTimestampsEnabled", addWordLevelTimestamps.ToString(CultureInfo.InvariantCulture));
this.logger.LogInformation($"Setting word level timestamps enabled to {addWordLevelTimestamps}");
@@ -342,11 +348,11 @@ private async Task ProcessFailedFileAsync(string fileName, string errorMessage,
{
try
{
- await this.storageConnector.WriteTextFileToBlobAsync(errorMessage, this.errorReportContaineName, logFileName).ConfigureAwait(false);
+ await this.storageConnector.WriteTextFileToBlobAsync(errorMessage, this.appConfig.ErrorReportOutputContainer, logFileName).ConfigureAwait(false);
await this.storageConnector.MoveFileAsync(
- this.audioInputContainerName,
+ this.appConfig.AudioInputContainer,
fileName,
- StartTranscriptionEnvironmentVariables.ErrorFilesOutputContainer,
+ this.appConfig.ErrorFilesOutputContainer,
fileName,
false).ConfigureAwait(false);
}
diff --git a/samples/ingestion/ingestion-client/Tests/EndToEndTests.cs b/samples/ingestion/ingestion-client/Tests/EndToEndTests.cs
index c83635d90..e893bdf9a 100644
--- a/samples/ingestion/ingestion-client/Tests/EndToEndTests.cs
+++ b/samples/ingestion/ingestion-client/Tests/EndToEndTests.cs
@@ -10,7 +10,6 @@ namespace Tests
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-
using Connector;
using Connector.Serializable.Language.Conversations;
using Connector.Serializable.TranscriptionStartedServiceBusMessage;
@@ -18,24 +17,31 @@ namespace Tests
using FetchTranscription;
using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-
using Moq;
-
using Newtonsoft.Json;
+ // using StartTranscriptionByTimer;
[TestClass]
public class EndToEndTests
{
- private static TestContext testContext;
+ private readonly Mock logger;
- private static Mock Logger { get; set; }
+ private readonly IOptions appConfigOptions;
- [ClassInitialize]
- public static void ClassInitialize(TestContext context)
+ public EndToEndTests()
{
- testContext = context ?? throw new ArgumentNullException(nameof(context));
- Logger = new Mock();
+ this.logger = new Mock();
+ var appConfig = new AppConfig
+ {
+ AzureWebJobsStorage = "UseDevelopmentStorage=true",
+ StartTranscriptionServiceBusConnectionString = "Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=testkey=",
+ FetchTranscriptionServiceBusConnectionString = "Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=testkey=",
+ TextAnalyticsKey = "sometestkey",
+ TextAnalyticsEndpoint = "https://sometestendpoint",
+ };
+ this.appConfigOptions = Options.Create(appConfig);
}
[TestMethod]
@@ -52,9 +58,8 @@ public async Task AnalyzeConversationTestAsync()
FallbackRole = Role.None,
}
}));
- var region = testContext.Properties["LanguageServiceRegion"].ToString();
- var subscriptionKey = testContext.Properties["LanguageServiceSubscriptionKey"].ToString();
- var provider = new AnalyzeConversationsProvider("en-US", subscriptionKey, region, Logger.Object);
+
+ var provider = new AnalyzeConversationsProvider("en-US", this.appConfigOptions.Value.TextAnalyticsKey, this.appConfigOptions.Value.TextAnalyticsEndpoint, this.logger.Object, this.appConfigOptions);
var body = File.ReadAllText(@"TestFiles/summarizationInputSample.json");
var transcription = JsonConvert.DeserializeObject(body);
diff --git a/samples/ingestion/ingestion-client/Tests/StartTranscriptionByServiceBus/StartTranscriptionByServiceBusTests.cs b/samples/ingestion/ingestion-client/Tests/StartTranscriptionByServiceBus/StartTranscriptionByServiceBusTests.cs
new file mode 100644
index 000000000..f84feeadd
--- /dev/null
+++ b/samples/ingestion/ingestion-client/Tests/StartTranscriptionByServiceBus/StartTranscriptionByServiceBusTests.cs
@@ -0,0 +1,142 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+
+ using Azure.Messaging.ServiceBus;
+
+ using Microsoft.Extensions.Logging;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ using Moq;
+ using StartTranscription;
+
+ using StartTranscriptionByTimer;
+
+ [TestClass]
+ public class StartTranscriptionByServiceBusTests
+ {
+ private readonly Mock> mockLogger;
+ private readonly Mock mockTranscriptionHelper;
+ private readonly StartTranscriptionByServiceBus startTranscriptionByServiceBus;
+
+ public StartTranscriptionByServiceBusTests()
+ {
+ this.mockLogger = new Mock>();
+ this.mockTranscriptionHelper = new Mock();
+ this.startTranscriptionByServiceBus = new StartTranscriptionByServiceBus(
+ this.mockLogger.Object,
+ this.mockTranscriptionHelper.Object);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunValidMessageCallsStartTranscriptionAsync()
+ {
+ // Arrange
+ var messages = new List
+ {
+ ServiceBusModelFactory.ServiceBusReceivedMessage(
+ messageId: "1",
+ subject: "TestSubject",
+ sequenceNumber: 123,
+ lockedUntil: DateTimeOffset.UtcNow.AddMinutes(1),
+ body: new BinaryData("EventType: TranscriptionStarted")),
+ };
+
+ this.mockTranscriptionHelper.Setup(h => h.IsValidServiceBusMessage(It.IsAny()))
+ .Returns(true);
+
+ // Act
+ await this.startTranscriptionByServiceBus.Run(messages.First());
+
+ // Assert
+ this.mockLogger.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Information),
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("C# Isolated ServiceBus queue trigger function processed message: TestSubject")),
+ It.IsAny(),
+ It.Is>((v, t) => true)),
+ Times.Once);
+
+ this.mockLogger.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Information),
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Received message: SequenceNumber:123 Body:EventType: TranscriptionStarted")),
+ It.IsAny(),
+ It.Is>((v, t) => true)),
+ Times.Once);
+
+ this.mockTranscriptionHelper.Verify(helper => helper.StartTranscriptionAsync(It.IsAny()), Times.Once);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunInvalidMessageLogsInvalidMessageAndDoesNotCallTranscription()
+ {
+ // Arrange
+ var messages = new List
+ {
+ ServiceBusModelFactory.ServiceBusReceivedMessage(
+ messageId: "1",
+ subject: "TestSubject",
+ sequenceNumber: 123,
+ lockedUntil: DateTimeOffset.UtcNow.AddMinutes(1),
+ body: new BinaryData("EventType: TranscriptionStarted")),
+ };
+
+ this.mockTranscriptionHelper.Setup(h => h.IsValidServiceBusMessage(It.IsAny()))
+ .Returns(false);
+
+ // Act
+ await this.startTranscriptionByServiceBus.Run(messages.First());
+
+ // Assert
+ this.mockLogger.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Information),
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("C# Isolated ServiceBus queue trigger function processed message: TestSubject")),
+ It.IsAny(),
+ It.Is>((v, t) => true)),
+ Times.Once);
+
+ this.mockLogger.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Information),
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Received message: SequenceNumber:123 Body:EventType: TranscriptionStarted")),
+ It.IsAny(),
+ It.Is>((v, t) => true)),
+ Times.Once);
+
+ this.mockLogger.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Information),
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Service bus message is invalid.")),
+ It.IsAny(),
+ It.Is>((v, t) => true)),
+ Times.Once);
+
+ this.mockTranscriptionHelper.Verify(helper => helper.StartTranscriptionAsync(It.IsAny()), Times.Never);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunNullMessageThrowsArgumentNullException()
+ {
+ // Arrange
+ ServiceBusReceivedMessage message = null;
+
+ // Act & Assert
+ await Assert.ThrowsExceptionAsync(() => this.startTranscriptionByServiceBus.Run(message));
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/ingestion/ingestion-client/Tests/StartTranscriptionByTimer/StartTranscriptionByTimerTests.cs b/samples/ingestion/ingestion-client/Tests/StartTranscriptionByTimer/StartTranscriptionByTimerTests.cs
new file mode 100644
index 000000000..d36e977a4
--- /dev/null
+++ b/samples/ingestion/ingestion-client/Tests/StartTranscriptionByTimer/StartTranscriptionByTimerTests.cs
@@ -0,0 +1,215 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ using Azure.Messaging.ServiceBus;
+ using Connector.Enums;
+
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.Extensions.Azure;
+ using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
+ using StartTranscriptionByTimer;
+
+ [TestClass]
+ public class StartTranscriptionByTimerTests
+ {
+ private readonly Mock> mockLogger;
+
+ // private readonly Mock mockStorageConnector;
+ private readonly Mock> mockServiceBusClientFactory;
+ private readonly Mock mockServiceBusClient;
+ private readonly Mock mockServiceBusReceiver;
+ private readonly Mock mockServiceBusSender;
+ private readonly IOptions appConfigOptions;
+
+ private readonly Mock mockTranscriptionHelper;
+
+ public StartTranscriptionByTimerTests()
+ {
+ this.mockLogger = new Mock>();
+
+ // this.mockStorageConnector = new Mock();
+ this.mockServiceBusClientFactory = new Mock>();
+ this.mockServiceBusClient = new Mock();
+ this.mockServiceBusReceiver = new Mock();
+ this.mockServiceBusSender = new Mock();
+ this.mockTranscriptionHelper = new Mock();
+
+ var appConfig = new AppConfig
+ {
+ AzureWebJobsStorage = "UseDevelopmentStorage=true",
+ StartTranscriptionServiceBusConnectionString = "Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=testkey=",
+ FetchTranscriptionServiceBusConnectionString = "Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=testkey=",
+ MessagesPerFunctionExecution = 5,
+ Locale = "en-US | English (United States)",
+ };
+ this.appConfigOptions = Options.Create(appConfig);
+
+ this.mockServiceBusClientFactory
+ .Setup(f => f.CreateClient(ServiceBusClientName.StartTranscriptionServiceBusClient.ToString()))
+ .Returns(this.mockServiceBusClient.Object);
+
+ this.mockServiceBusClientFactory
+ .Setup(f => f.CreateClient(ServiceBusClientName.FetchTranscriptionServiceBusClient.ToString()))
+ .Returns(this.mockServiceBusClient.Object);
+
+ this.mockServiceBusClient
+ .Setup(c => c.CreateReceiver(It.IsAny()))
+ .Returns(this.mockServiceBusReceiver.Object);
+
+ this.mockServiceBusClient
+ .Setup(c => c.CreateSender(It.IsAny()))
+ .Returns(this.mockServiceBusSender.Object);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunNoMessagesLogsNoMessages()
+ {
+ // Arrange
+ var function = new StartTranscriptionByTimer(
+ this.mockLogger.Object,
+ this.appConfigOptions,
+ this.mockServiceBusClientFactory.Object,
+ this.mockTranscriptionHelper.Object);
+
+ var timerInfo = new TimerInfo
+ {
+ ScheduleStatus = new ScheduleStatus
+ {
+ Last = DateTime.UtcNow,
+ Next = DateTime.UtcNow.AddMinutes(5)
+ }
+ };
+
+ this.mockServiceBusReceiver
+ .Setup(r => r.ReceiveMessagesAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new List());
+
+ // Act
+ await function.Run(timerInfo);
+
+ // Assert
+ this.mockLogger.Verify(
+ x => x.Log(
+ LogLevel.Information,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Got no messages in this iteration.")),
+ null,
+ It.IsAny>()),
+ Times.Once);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunValidMessagesLogsPulledValidMessages()
+ {
+ // Arrange
+ var function = new StartTranscriptionByTimer(
+ this.mockLogger.Object,
+ this.appConfigOptions,
+ this.mockServiceBusClientFactory.Object,
+ this.mockTranscriptionHelper.Object);
+
+ var timerInfo = new TimerInfo
+ {
+ ScheduleStatus = new ScheduleStatus
+ {
+ Last = DateTime.UtcNow,
+ Next = DateTime.UtcNow.AddMinutes(5)
+ }
+ };
+
+ var messages = new List
+ {
+ ServiceBusModelFactory.ServiceBusReceivedMessage(
+ messageId: "1",
+ lockedUntil: DateTimeOffset.UtcNow.AddMinutes(1),
+ body: new BinaryData("EventType: TranscriptionStarted")),
+ };
+ this.mockServiceBusReceiver
+ .Setup(r => r.ReceiveMessagesAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(messages);
+
+ this.mockTranscriptionHelper
+ .Setup(t => t.IsValidServiceBusMessage(It.IsAny()))
+ .Returns(true);
+ this.mockTranscriptionHelper
+ .Setup(t => t.StartTranscriptionsAsync(It.IsAny>(), It.IsAny()))
+ .Returns(Task.CompletedTask);
+
+ // Act
+ await function.Run(timerInfo);
+
+ // Assert
+ this.mockLogger.Verify(
+ x => x.Log(
+ LogLevel.Information,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Pulled 1 valid messages from queue.")),
+ null,
+ It.IsAny>()),
+ Times.Once);
+ }
+
+ [TestMethod]
+ public async Task FunctionRunInvalidMessagesLogsPulledNoValidMessages()
+ {
+ // Arrange
+ var function = new StartTranscriptionByTimer(
+ this.mockLogger.Object,
+ this.appConfigOptions,
+ this.mockServiceBusClientFactory.Object,
+ this.mockTranscriptionHelper.Object);
+
+ var timerInfo = new TimerInfo
+ {
+ ScheduleStatus = new ScheduleStatus
+ {
+ Last = DateTime.UtcNow,
+ Next = DateTime.UtcNow.AddMinutes(5)
+ }
+ };
+
+ var messages = new List
+ {
+ ServiceBusModelFactory.ServiceBusReceivedMessage(
+ messageId: "1",
+ lockedUntil: DateTimeOffset.UtcNow.AddMinutes(1),
+ body: new BinaryData("EventType: TranscriptionStarted")),
+ };
+ this.mockServiceBusReceiver
+ .Setup(r => r.ReceiveMessagesAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(messages);
+
+ this.mockTranscriptionHelper
+ .Setup(t => t.IsValidServiceBusMessage(It.IsAny()))
+ .Returns(false);
+ this.mockTranscriptionHelper
+ .Setup(t => t.StartTranscriptionsAsync(It.IsAny>(), It.IsAny()))
+ .Returns(Task.CompletedTask);
+
+ // Act
+ await function.Run(timerInfo);
+
+ // Assert
+ this.mockLogger.Verify(
+ x => x.Log(
+ LogLevel.Information,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("No valid messages were found in this function execution.")),
+ null,
+ It.IsAny>()),
+ Times.Once);
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/ingestion/ingestion-client/Tests/Tests.csproj b/samples/ingestion/ingestion-client/Tests/Tests.csproj
index d0b584328..c0c436124 100644
--- a/samples/ingestion/ingestion-client/Tests/Tests.csproj
+++ b/samples/ingestion/ingestion-client/Tests/Tests.csproj
@@ -10,6 +10,8 @@
+
+