Skip to content

Commit

Permalink
feat: set isolated project option as default az func worker (#750)
Browse files Browse the repository at this point in the history
* feat: set isolated project option as default az func worker

* Update docker-integration-tests.yml

* Update docker-integration-tests.yml

* pr-fix: add 'using' for 'SensorReading' example model
  • Loading branch information
stijnmoreels authored Dec 23, 2022
1 parent b6d34d5 commit d2bf712
Show file tree
Hide file tree
Showing 19 changed files with 129 additions and 156 deletions.
10 changes: 5 additions & 5 deletions build/templates/docker-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ stages:
parameters:
projectName: 'Arcus.Demo.AzureFunctions.EventHubs.InProcess'
projectAlias: 'arcus-az-func-eventhubs'
options: '--functions-worker inProcess'
projectOptions: '--functions-worker inProcess'
ports: '$(Arcus.AzureFunctions.EventHubs.InProcess.Port):$(Arcus.AzureFunctions.EventHubs.InProcess.Port)'
script: |
Get-Content './Arcus.Demo.AzureFunctions.EventHubs.InProcess/Startup.cs' -Raw |
Expand All @@ -196,12 +196,12 @@ stages:
parameters:
projectName: 'Arcus.Demo.AzureFunctions.EventHubs.Isolated'
projectAlias: 'arcus-az-func-eventhubs'
options: '--functions-worker isolated'
projectOptions: '--functions-worker isolated'
ports: '$(Arcus.AzureFunctions.EventHubs.Isolated.Port):$(Arcus.AzureFunctions.EventHubs.Isolated.Port)'
script: |
Get-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/Startup.cs' -Raw |
Get-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/Program.cs' -Raw |
% { $_ -replace '#error', '#warning' -replace '#if DEBUG', '#if RELEASE' } |
Set-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/Startup.cs'
Set-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/Program.cs'
Get-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/SensorReadingFunction.cs' -Raw |
% { $_ -replace 'sensors', '$(Arcus.EventHubs.Docker.EventHubsName)' } |
Set-Content './Arcus.Demo.AzureFunctions.EventHubs.Isolated/SensorReadingFunction.cs'
Expand Down Expand Up @@ -273,4 +273,4 @@ stages:
inputs:
targetType: 'inline'
script: 'docker logs Arcus.Demo.AzureFunctions.Isolated.Http'
condition: failed()
condition: failed()
4 changes: 2 additions & 2 deletions docs/preview/features/azurefunctions-eventhubs-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Creates a starter worker project with by default configured:

And additional features available with options:
* `--functions-worker`: Configures the type of Azure Functions worker type the project should target.
* `inProcess` (default): Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
* `isolated`: Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `isolated` (default): Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `inProcess`: Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
For more information on the difference between the two, see [Microsoft's documentation](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide).
* `-es|--exclude-serilog`: Exclude the [Serilog](https://serilog.net/) logging infrastructure in the worker project which includes default enrichers ([version](https://observability.arcus-azure.net/features/telemetry-enrichment#version-enricher) and [application](https://observability.arcus-azure.net/features/telemetry-enrichment#application-enricher)), and sinking to Application Insights.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Creates a starter worker project with by default configured:

And additional features available with options:
* `--functions-worker`: Configures the type of Azure Functions worker type the project should target.
* `inProcess` (default): Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
* `isolated`: Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `isolated` (default): Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `inProcess`: Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
For more information on the difference between the two, see [Microsoft's documentation](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide).
* `--exclude-serilog`: Exclude the [Serilog](https://serilog.net/) logging infrastructure in the Azure Functions project which includes default enrichers ([version](https://observability.arcus-azure.net/features/telemetry-enrichment#version-enricher) and [application](https://observability.arcus-azure.net/features/telemetry-enrichment#application-enricher)), and sinking to Application Insights.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Creates a starter worker project with by default configured:

And additional features available with options:
* `--functions-worker`: Configures the type of Azure Functions worker type the project should target.
* `inProcess` (default): Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
* `isolated`: Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `isolated` (default): Uses the isolated Azure Functions worker type which runs on a different process as the Azure Function
* `inProcess`: Uses the in-process Azure Functions worker type which runs on the same process as run Azure Function
For more information on the difference between the two, see [Microsoft's documentation](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide).
* `--exclude-serilog`: Exclude the [Serilog](https://serilog.net/) logging infrastructure in the Azure Functions project which includes default enrichers ([version](https://observability.arcus-azure.net/features/telemetry-enrichment#version-enricher) and [application](https://observability.arcus-azure.net/features/telemetry-enrichment#application-enricher)), and sinking to Application Insights.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"description": "Uses Azure Functions isolated worker template"
}
],
"defaultValue": "inProcess",
"defaultValue": "isolated",
"description": "Chooses the kind of Azure Functions worker template"
},
"InProcess": {
Expand Down
1 change: 1 addition & 0 deletions src/Arcus.Templates.AzureFunctions.EventHubs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Arcus.Security.Core;
using Arcus.Security.Core.Caching.Configuration;
using Arcus.Templates.AzureFunctions.EventHubs.Model;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
#if Serilog_AppInsights
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"description": "Uses Azure Functions isolated worker template"
}
],
"defaultValue": "inProcess",
"defaultValue": "isolated",
"description": "Chooses the kind of Azure Functions worker template"
},
"InProcess": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"description": "Uses Azure Functions isolated worker template"
}
],
"defaultValue": "inProcess",
"defaultValue": "isolated",
"description": "Chooses the kind of Azure Functions worker template"
},
"InProcess": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ public abstract class AzureFunctionsProject : TemplateProject
/// </summary>
/// <param name="templateDirectory">The file directory where the .NET project template is located.</param>
/// <param name="configuration">The configuration instance to retrieve Azure Functions-specific test values.</param>
/// <param name="options">The options used to manipulate the resulting Azure Functions project.</param>
/// <param name="outputWriter">The logger instance to write diagnostic trace messages during the lifetime of the test project.</param>
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="templateDirectory"/>, <paramref name="configuration"/>, or <paramref name="outputWriter"/> is <c>null</c>.</exception>
protected AzureFunctionsProject(
DirectoryInfo templateDirectory,
TestConfig configuration,
AzureFunctionsProjectOptions options,
ITestOutputHelper outputWriter)
: base(templateDirectory,
configuration.GetFixtureProjectDirectory(),
Expand All @@ -44,11 +46,23 @@ protected AzureFunctionsProject(
Guard.NotNull(outputWriter, nameof(outputWriter), "Requires an logger instance to write diagnostic trace messages during the lifetime of the project.");

Configuration = configuration;
FunctionsWorker = options.FunctionsWorker;
RuntimeFileName = DetermineStartupCodeFileName();
RootEndpoint = configuration.GenerateRandomLocalhostUrl().ResetToRoot().ToUri();
AzureFunctionsConfig = configuration.GetAzureFunctionsConfig();
ApplicationInsightsConfig = configuration.GetApplicationInsightsConfig();
}

/// <summary>
/// Gets the Azure Functions worker type the project should target.
/// </summary>
public FunctionsWorker FunctionsWorker { get; }

/// <summary>
/// Gets the file name of the Azure Functions that contains the startup code ('Startup.cs' for in-process functions, 'Program.cs' for isolated functions).
/// </summary>
public string RuntimeFileName { get; }

/// <summary>
/// Gets the root endpoint on which the Azure Function is running.
/// </summary>
Expand All @@ -72,23 +86,34 @@ protected AzureFunctionsProject(
/// <summary>
/// Adds an test Azure storage account connection string to the Azure Function project so the project can start up correctly.
/// </summary>
protected void AddLocalSettings(FunctionsWorker workerType)
protected void AddLocalSettings()
{
string storageAccountConnectionString = AzureFunctionsConfig.StorageAccountConnectionString;
string workerRuntime = DetermineWorkerRuntime(workerType);
string workerRuntime = DetermineWorkerRuntime();

AddFileInProject("local.settings.json",
$"{{ \"IsEncrypted\": false, \"Values\": {{ \"AzureWebJobsStorage\": \"{storageAccountConnectionString}\", \"FUNCTIONS_WORKER_RUNTIME\": \"{workerRuntime}\", \"APPLICATIONINSIGHTS_CONNECTION_STRING\": \"\" }}, \"Host\": {{ \"LocalHttpPort\": {RootEndpoint.Port} }} }}");
}

private static string DetermineWorkerRuntime(FunctionsWorker workerType)
private string DetermineWorkerRuntime()
{
switch (workerType)
switch (FunctionsWorker)
{
case FunctionsWorker.InProcess: return "dotnet";
case FunctionsWorker.Isolated: return "dotnet-isolated";
default:
throw new ArgumentOutOfRangeException(nameof(workerType), workerType, "Unknown Azure Functions worker type");
throw new ArgumentOutOfRangeException(nameof(FunctionsWorker), FunctionsWorker, "Unknown Azure Functions worker type");
}
}

private string DetermineStartupCodeFileName()
{
switch (FunctionsWorker)
{
case FunctionsWorker.InProcess: return "Startup.cs";
case FunctionsWorker.Isolated: return "Program.cs";
default:
throw new ArgumentOutOfRangeException(nameof(FunctionsWorker), FunctionsWorker, "Unknown Azure Functions worker type");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using Arcus.Templates.Tests.Integration.Fixture;

namespace Arcus.Templates.Tests.Integration.AzureFunctions
{
/// <summary>
/// Represents an simple set of options used in the Azure Functions project templates.
/// </summary>
public class AzureFunctionsProjectOptions : ProjectOptions
{
/// <summary>
/// Gets the Azure Functions worker type the project should target.
/// </summary>
public FunctionsWorker FunctionsWorker { get; protected set; } = FunctionsWorker.Isolated;

/// <summary>
/// Sets the Azure Functions worker type of the project template.
/// </summary>
/// <param name="workerType">The functions worker type.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="workerType"/> is outside the bounds of the enumeration.</exception>
protected void SetFunctionsWorker(FunctionsWorker workerType)
{
string workerTyperArgument = DetermineFunctionsWorkerArgument(workerType);
AddOption($"--functions-worker {workerTyperArgument}");

FunctionsWorker = workerType;
}

private static string DetermineFunctionsWorkerArgument(FunctionsWorker workerType)
{
switch (workerType)
{
case FunctionsWorker.InProcess: return "inProcess";
case FunctionsWorker.Isolated: return "isolated";
default:
throw new ArgumentOutOfRangeException(nameof(workerType), workerType, "Unknown functions worker type");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ public class AzureFunctionsDatabricksProject : AzureFunctionsProject

private AzureFunctionsDatabricksProject(
TestConfig configuration,
AzureFunctionsDatabricksProjectOptions options,
ITestOutputHelper outputWriter)
: base(configuration.GetAzureFunctionsDatabricksJobMetricsProjectDirectory(),
configuration,
options,
outputWriter)
{
AzureFunctionDatabricksConfig = configuration.GetDatabricksConfig();
Expand Down Expand Up @@ -89,10 +91,10 @@ public static async Task<AzureFunctionsDatabricksProject> StartNewAsync(TestConf

private static AzureFunctionsDatabricksProject CreateNew(TestConfig configuration, AzureFunctionsDatabricksProjectOptions options, ITestOutputHelper outputWriter)
{
var project = new AzureFunctionsDatabricksProject(configuration, outputWriter);
var project = new AzureFunctionsDatabricksProject(configuration, options, outputWriter);
project.CreateNewProject(options);
project.AddDatabricksSecurityToken(project.AzureFunctionDatabricksConfig.SecurityToken);
project.AddLocalSettings(FunctionsWorker.InProcess);
project.AddLocalSettings();

return project;
}
Expand All @@ -107,7 +109,7 @@ private void AddDatabricksSecurityToken(string securityToken)
{
AddTypeAsFile<SingleValueSecretProvider>();

UpdateFileInProject("Startup.cs", contents =>
UpdateFileInProject(RuntimeFileName, contents =>
RemovesUserErrorsFromContents(contents)
.Replace("AddAzureKeyVaultWithManagedIdentity(\"https://your-keyvault.vault.azure.net/\", CacheConfiguration.Default)",
$"AddProvider(new {nameof(SingleValueSecretProvider)}(\"{securityToken}\"))"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
using Arcus.Templates.Tests.Integration.Fixture;

namespace Arcus.Templates.Tests.Integration.AzureFunctions.Databricks.JobMetrics
namespace Arcus.Templates.Tests.Integration.AzureFunctions.Databricks.JobMetrics
{
/// <summary>
/// Represents the additional user project options to change the <see cref="AzureFunctionsDatabricksProject"/> project contents and functionality.
/// </summary>
public class AzureFunctionsDatabricksProjectOptions : ProjectOptions
public class AzureFunctionsDatabricksProjectOptions : AzureFunctionsProjectOptions
{
/// <summary>
/// Initializes a new instance of the <see cref="AzureFunctionsDatabricksProjectOptions" /> class.
/// </summary>
public AzureFunctionsDatabricksProjectOptions()
{
FunctionsWorker = FunctionsWorker.InProcess;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
namespace Arcus.Templates.Tests.Integration.AzureFunctions.EventHubs
{
/// <summary>
/// Project template to create Azure Functions EventHubs triger projects.
/// Project template to create Azure Functions EventHubs trigger projects.
/// </summary>
public class AzureFunctionsEventHubsProject : AzureFunctionsProject, IAsyncDisposable
{
private AzureFunctionsEventHubsProject(
TestEventHubsMessageProducer messageProducer,
TestConfig config,
AzureFunctionsEventHubsProjectOptions options,
ITestOutputHelper outputWriter)
: base(config.GetAzureFunctionsEventHubsProjectDirectory(), config, outputWriter)
: base(config.GetAzureFunctionsEventHubsProjectDirectory(), config, options, outputWriter)
{
MessagePump = new MessagePumpService(messageProducer, config, outputWriter);
}
Expand Down Expand Up @@ -83,16 +84,16 @@ private static AzureFunctionsEventHubsProject CreateNew(
{
EventHubsConfig eventHubsConfig = configuration.GetEventHubsConfig();
var producer = new TestEventHubsMessageProducer(eventHubsConfig.EventHubsName, eventHubsConfig.EventHubsConnectionString);
var project = new AzureFunctionsEventHubsProject(producer, configuration, outputWriter);
var project = new AzureFunctionsEventHubsProject(producer, configuration, options, outputWriter);

project.CreateNewProject(options);
project.AddTestMessageHandler(eventHubsConfig, options);
project.AddLocalSettings(options.FunctionsWorker);
project.AddTestMessageHandler(eventHubsConfig);
project.AddLocalSettings();

return project;
}

private void AddTestMessageHandler(EventHubsConfig eventHubsConfig, AzureFunctionsEventHubsProjectOptions options)
private void AddTestMessageHandler(EventHubsConfig eventHubsConfig)
{
AddPackage("Arcus.EventGrid.Core", "3.3.0");
AddTypeAsFile<Order>();
Expand All @@ -105,18 +106,7 @@ private void AddTestMessageHandler(EventHubsConfig eventHubsConfig, AzureFunctio
contents => contents.Replace("EventHubTrigger(\"sensors\"", $"EventHubTrigger(\"{eventHubsConfig.EventHubsName}\"")
.Replace("var data = new EventData(message);", $"var data = new EventData(message);{Environment.NewLine}data.CorrelationId = properties[\"Operation-Id\"].GetString();"));

string fileName = "";
if (options.FunctionsWorker is FunctionsWorker.InProcess)
{
fileName = "Startup.cs";
}

if (options.FunctionsWorker is FunctionsWorker.Isolated)
{
fileName = "Program.cs";
}

UpdateFileInProject(fileName, contents =>
UpdateFileInProject(RuntimeFileName, contents =>
RemovesUserErrorsFromContents(contents)
.Replace(".MinimumLevel.Debug()", ".MinimumLevel.Verbose()")
.Replace("SensorReadingAzureEventHubsMessageHandler", nameof(TestOrdersAzureEventHubsMessageHandler))
Expand Down
Loading

0 comments on commit d2bf712

Please sign in to comment.