From ee2e3eef5cb6ab49925176e9b660459fcfa77c31 Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 29 Aug 2023 22:22:36 -0600 Subject: [PATCH 1/8] Updating workflow collection to allow for use of API Token validation Signed-off-by: Ryan Lettieri --- .../Workflow/WorkflowConsoleApp/Program.cs | 11 +++- .../WorkflowServiceCollectionExtensions.cs | 64 ++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/examples/Workflow/WorkflowConsoleApp/Program.cs b/examples/Workflow/WorkflowConsoleApp/Program.cs index a1189e70b..5ce16c423 100644 --- a/examples/Workflow/WorkflowConsoleApp/Program.cs +++ b/examples/Workflow/WorkflowConsoleApp/Program.cs @@ -47,7 +47,16 @@ using var host = builder.Build(); host.Start(); -using var daprClient = new DaprClientBuilder().Build(); +DaprClient daprClient; +string apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); +if (!string.IsNullOrEmpty(apiToken)) +{ + daprClient = new DaprClientBuilder().UseDaprApiToken(apiToken).Build(); +} +else +{ + daprClient = new DaprClientBuilder().Build(); +} // Wait for the sidecar to become available while (!await daprClient.CheckHealthAsync()) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index c24265475..abac75004 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -14,10 +14,12 @@ namespace Dapr.Workflow { using System; + using Grpc.Net.Client; using Microsoft.DurableTask.Client; using Microsoft.DurableTask.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; + using System.Net.Http; /// /// Contains extension methods for using Dapr Workflow with dependency injection. @@ -57,7 +59,19 @@ public static IServiceCollection AddDaprWorkflow( if (TryGetGrpcAddress(out string address)) { - builder.UseGrpc(address); + string? apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); + if (!string.IsNullOrEmpty(apiToken)) + { + serviceCollection.ConfigureDurableGrpcClient(apiToken); + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + builder.UseGrpc(CreateChannel(client)); + } + else + { + builder.UseGrpc(address); + } + } else { @@ -85,7 +99,19 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s { if (TryGetGrpcAddress(out string address)) { - builder.UseGrpc(address); + string? apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); + if (!string.IsNullOrEmpty(apiToken)) + { + services.ConfigureDurableGrpcClient(apiToken); + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + builder.UseGrpc(CreateChannel(client)); + } + else + { + builder.UseGrpc(address); + } + } else { @@ -126,6 +152,40 @@ static bool TryGetGrpcAddress(out string address) address = string.Empty; return false; } + + static GrpcChannel CreateChannel(HttpClient client) + { + string address = "localhost"; + string? daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); + if (int.TryParse(daprPortStr, out int daprGrpcPort)) + { + // There is a bug in the Durable Task SDK that requires us to change the format of the address + // depending on the version of .NET that we're targeting. For now, we work around this manually. +#if NET6_0_OR_GREATER + address = $"http://localhost:{daprGrpcPort}"; +#else + address = $"localhost:{daprGrpcPort}"; +#endif + } + GrpcChannelOptions options = new() { HttpClient = client}; + return GrpcChannel.ForAddress(address, options); + } + } + + static class DaprDurableGrpcExtensions + { + const string ClientName = "durabletask-grpc"; + + public static IServiceCollection ConfigureDurableGrpcClient(this IServiceCollection services, string apiToken) + { + services.AddHttpClient(ClientName) + .ConfigureHttpClient(client => + { + client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + }); + return services; + } + } } From bad483a0f4ec28f361fd04f3720672019e60c87f Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 5 Sep 2023 13:55:28 -0600 Subject: [PATCH 2/8] Addressing review comments Signed-off-by: Ryan Lettieri --- examples/Workflow/README.md | 4 + .../Workflow/WorkflowConsoleApp/Program.cs | 218 +++++++++--------- .../WorkflowServiceCollectionExtensions.cs | 4 +- 3 files changed, 116 insertions(+), 110 deletions(-) diff --git a/examples/Workflow/README.md b/examples/Workflow/README.md index b93af1bb5..e119465c3 100644 --- a/examples/Workflow/README.md +++ b/examples/Workflow/README.md @@ -9,6 +9,10 @@ This Dapr workflow example shows how to create a Dapr workflow (`Workflow`) and - [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/) - [Dapr .NET SDK](https://github.com/dapr/dotnet-sdk/) + +## Optional Setup +Dapr workflow, as well as this example program, now support authentication through the use of API tokens. For more information on this, view the following document: [API Token](https://github.com/dapr/dotnet-sdk/docs/api-token.md) + ## Projects in sample This sample contains a single [WorkflowConsoleApp](./WorkflowConsoleApp) .NET project. diff --git a/examples/Workflow/WorkflowConsoleApp/Program.cs b/examples/Workflow/WorkflowConsoleApp/Program.cs index 5ce16c423..9aae2427e 100644 --- a/examples/Workflow/WorkflowConsoleApp/Program.cs +++ b/examples/Workflow/WorkflowConsoleApp/Program.cs @@ -79,136 +79,138 @@ await RestockInventory(daprClient, baseInventory); // Start the input loop -while (true) +using (daprClient) { - // Get the name of the item to order and make sure we have inventory - string items = string.Join(", ", baseInventory.Select(i => i.Name)); - Console.WriteLine($"Enter the name of one of the following items to order [{items}]."); - Console.WriteLine("To restock items, type 'restock'."); - string itemName = Console.ReadLine()?.Trim(); - if (string.IsNullOrEmpty(itemName)) - { - continue; - } - else if (string.Equals("restock", itemName, StringComparison.OrdinalIgnoreCase)) + while (true) { - await RestockInventory(daprClient, baseInventory); - continue; - } + // Get the name of the item to order and make sure we have inventory + string items = string.Join(", ", baseInventory.Select(i => i.Name)); + Console.WriteLine($"Enter the name of one of the following items to order [{items}]."); + Console.WriteLine("To restock items, type 'restock'."); + string itemName = Console.ReadLine()?.Trim(); + if (string.IsNullOrEmpty(itemName)) + { + continue; + } + else if (string.Equals("restock", itemName, StringComparison.OrdinalIgnoreCase)) + { + await RestockInventory(daprClient, baseInventory); + continue; + } - InventoryItem item = baseInventory.FirstOrDefault(item => string.Equals(item.Name, itemName, StringComparison.OrdinalIgnoreCase)); - if (item == null) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine($"We don't have {itemName}!"); - Console.ResetColor(); - continue; - } + InventoryItem item = baseInventory.FirstOrDefault(item => string.Equals(item.Name, itemName, StringComparison.OrdinalIgnoreCase)); + if (item == null) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($"We don't have {itemName}!"); + Console.ResetColor(); + continue; + } - Console.WriteLine($"How many {itemName} would you like to purchase?"); - string amountStr = Console.ReadLine().Trim(); - if (!int.TryParse(amountStr, out int amount) || amount <= 0) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine($"Invalid input. Assuming you meant to type '1'."); - Console.ResetColor(); - amount = 1; - } + Console.WriteLine($"How many {itemName} would you like to purchase?"); + string amountStr = Console.ReadLine().Trim(); + if (!int.TryParse(amountStr, out int amount) || amount <= 0) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($"Invalid input. Assuming you meant to type '1'."); + Console.ResetColor(); + amount = 1; + } - // Construct the order with a unique order ID - string orderId = $"{itemName.ToLowerInvariant()}-{Guid.NewGuid().ToString()[..8]}"; - double totalCost = amount * item.PerItemCost; - var orderInfo = new OrderPayload(itemName.ToLowerInvariant(), totalCost, amount); + // Construct the order with a unique order ID + string orderId = $"{itemName.ToLowerInvariant()}-{Guid.NewGuid().ToString()[..8]}"; + double totalCost = amount * item.PerItemCost; + var orderInfo = new OrderPayload(itemName.ToLowerInvariant(), totalCost, amount); - // Start the workflow using the order ID as the workflow ID - Console.WriteLine($"Starting order workflow '{orderId}' purchasing {amount} {itemName}"); - await daprClient.StartWorkflowAsync( - workflowComponent: DaprWorkflowComponent, - workflowName: nameof(OrderProcessingWorkflow), - input: orderInfo, - instanceId: orderId); + // Start the workflow using the order ID as the workflow ID + Console.WriteLine($"Starting order workflow '{orderId}' purchasing {amount} {itemName}"); + await daprClient.StartWorkflowAsync( + workflowComponent: DaprWorkflowComponent, + workflowName: nameof(OrderProcessingWorkflow), + input: orderInfo, + instanceId: orderId); - // Wait for the workflow to start and confirm the input - GetWorkflowResponse state = await daprClient.WaitForWorkflowStartAsync( - instanceId: orderId, - workflowComponent: DaprWorkflowComponent); + // Wait for the workflow to start and confirm the input + GetWorkflowResponse state = await daprClient.WaitForWorkflowStartAsync( + instanceId: orderId, + workflowComponent: DaprWorkflowComponent); - Console.WriteLine($"{state.WorkflowName} (ID = {orderId}) started successfully with {state.ReadInputAs()}"); + Console.WriteLine($"{state.WorkflowName} (ID = {orderId}) started successfully with {state.ReadInputAs()}"); - // Wait for the workflow to complete - while (true) - { - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); - try - { - state = await daprClient.WaitForWorkflowCompletionAsync( - instanceId: orderId, - workflowComponent: DaprWorkflowComponent, - cancellationToken: cts.Token); - break; - } - catch (OperationCanceledException) + // Wait for the workflow to complete + while (true) { - // Check to see if the workflow is blocked waiting for an approval - state = await daprClient.GetWorkflowAsync( - instanceId: orderId, - workflowComponent: DaprWorkflowComponent); - if (state.Properties.TryGetValue("dapr.workflow.custom_status", out string customStatus) && - customStatus.Contains("Waiting for approval")) + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + try { - Console.WriteLine($"{state.WorkflowName} (ID = {orderId}) requires approval. Approve? [Y/N]"); - string approval = Console.ReadLine(); - ApprovalResult approvalResult = ApprovalResult.Unspecified; - if (string.Equals(approval, "Y", StringComparison.OrdinalIgnoreCase)) - { - Console.WriteLine("Approving order..."); - approvalResult = ApprovalResult.Approved; - } - else if (string.Equals(approval, "N", StringComparison.OrdinalIgnoreCase)) - { - Console.WriteLine("Rejecting order..."); - approvalResult = ApprovalResult.Rejected; - } - - if (approvalResult != ApprovalResult.Unspecified) + state = await daprClient.WaitForWorkflowCompletionAsync( + instanceId: orderId, + workflowComponent: DaprWorkflowComponent, + cancellationToken: cts.Token); + break; + } + catch (OperationCanceledException) + { + // Check to see if the workflow is blocked waiting for an approval + state = await daprClient.GetWorkflowAsync( + instanceId: orderId, + workflowComponent: DaprWorkflowComponent); + if (state.Properties.TryGetValue("dapr.workflow.custom_status", out string customStatus) && + customStatus.Contains("Waiting for approval")) { - // Raise the workflow event to the workflow - await daprClient.RaiseWorkflowEventAsync( - instanceId: orderId, - workflowComponent: DaprWorkflowComponent, - eventName: "ManagerApproval", - eventData: approvalResult); + Console.WriteLine($"{state.WorkflowName} (ID = {orderId}) requires approval. Approve? [Y/N]"); + string approval = Console.ReadLine(); + ApprovalResult approvalResult = ApprovalResult.Unspecified; + if (string.Equals(approval, "Y", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine("Approving order..."); + approvalResult = ApprovalResult.Approved; + } + else if (string.Equals(approval, "N", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine("Rejecting order..."); + approvalResult = ApprovalResult.Rejected; + } + + if (approvalResult != ApprovalResult.Unspecified) + { + // Raise the workflow event to the workflow + await daprClient.RaiseWorkflowEventAsync( + instanceId: orderId, + workflowComponent: DaprWorkflowComponent, + eventName: "ManagerApproval", + eventData: approvalResult); + } + + // otherwise, keep waiting } - - // otherwise, keep waiting } } - } - if (state.RuntimeStatus == WorkflowRuntimeStatus.Completed) - { - OrderResult result = state.ReadOutputAs(); - if (result.Processed) + if (state.RuntimeStatus == WorkflowRuntimeStatus.Completed) { - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine($"Order workflow is {state.RuntimeStatus} and the order was processed successfully ({result})."); - Console.ResetColor(); + OrderResult result = state.ReadOutputAs(); + if (result.Processed) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine($"Order workflow is {state.RuntimeStatus} and the order was processed successfully ({result})."); + Console.ResetColor(); + } + else + { + Console.WriteLine($"Order workflow is {state.RuntimeStatus} but the order was not processed."); + } } - else + else if (state.RuntimeStatus == WorkflowRuntimeStatus.Failed) { - Console.WriteLine($"Order workflow is {state.RuntimeStatus} but the order was not processed."); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"The workflow failed - {state.FailureDetails}"); + Console.ResetColor(); } - } - else if (state.RuntimeStatus == WorkflowRuntimeStatus.Failed) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"The workflow failed - {state.FailureDetails}"); - Console.ResetColor(); - } - Console.WriteLine(); + Console.WriteLine(); + } } - static async Task RestockInventory(DaprClient daprClient, List inventory) { Console.WriteLine("*** Restocking inventory..."); diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index abac75004..4280009bf 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -59,7 +59,7 @@ public static IServiceCollection AddDaprWorkflow( if (TryGetGrpcAddress(out string address)) { - string? apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); + var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!string.IsNullOrEmpty(apiToken)) { serviceCollection.ConfigureDurableGrpcClient(apiToken); @@ -104,7 +104,7 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s { services.ConfigureDurableGrpcClient(apiToken); HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + // client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); builder.UseGrpc(CreateChannel(client)); } else From db364f116acf46436da94884997eb87e732dc46b Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 5 Sep 2023 17:06:04 -0600 Subject: [PATCH 3/8] Cleaning up variables and removing unneeded fn Signed-off-by: Ryan Lettieri --- .../WorkflowServiceCollectionExtensions.cs | 33 +++++-------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index 4280009bf..0c63e0a49 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -62,7 +62,7 @@ public static IServiceCollection AddDaprWorkflow( var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!string.IsNullOrEmpty(apiToken)) { - serviceCollection.ConfigureDurableGrpcClient(apiToken); + // serviceCollection.ConfigureDurableGrpcClient(apiToken); HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); builder.UseGrpc(CreateChannel(client)); @@ -99,12 +99,12 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s { if (TryGetGrpcAddress(out string address)) { - string? apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); + var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!string.IsNullOrEmpty(apiToken)) { - services.ConfigureDurableGrpcClient(apiToken); + // services.ConfigureDurableGrpcClient(apiToken); HttpClient client = new HttpClient(); - // client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); builder.UseGrpc(CreateChannel(client)); } else @@ -130,13 +130,13 @@ static bool TryGetGrpcAddress(out string address) // 1. DaprDefaults.cs uses 127.0.0.1 instead of localhost, which prevents testing with Dapr on WSL2 and the app on Windows // 2. DaprDefaults.cs doesn't compile when the project has C# nullable reference types enabled. // If the above issues are fixed (ensuring we don't regress anything) we should switch to using the logic in DaprDefaults.cs. - string? daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); + var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); if (!String.IsNullOrEmpty(daprEndpoint)) { address = daprEndpoint; return true; } - string? daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); + var daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); if (int.TryParse(daprPortStr, out int daprGrpcPort)) { // There is a bug in the Durable Task SDK that requires us to change the format of the address @@ -155,8 +155,8 @@ static bool TryGetGrpcAddress(out string address) static GrpcChannel CreateChannel(HttpClient client) { - string address = "localhost"; - string? daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); + var address = "localhost"; + var daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); if (int.TryParse(daprPortStr, out int daprGrpcPort)) { // There is a bug in the Durable Task SDK that requires us to change the format of the address @@ -171,21 +171,4 @@ static GrpcChannel CreateChannel(HttpClient client) return GrpcChannel.ForAddress(address, options); } } - - static class DaprDurableGrpcExtensions - { - const string ClientName = "durabletask-grpc"; - - public static IServiceCollection ConfigureDurableGrpcClient(this IServiceCollection services, string apiToken) - { - services.AddHttpClient(ClientName) - .ConfigureHttpClient(client => - { - client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); - }); - return services; - } - - } } - From daaeaec3ff5dbf3f20e4bbed44947bb5213303ee Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 5 Sep 2023 18:36:28 -0600 Subject: [PATCH 4/8] Potential fix for grpc workflow issue Signed-off-by: Ryan Lettieri --- .../WorkflowServiceCollectionExtensions.cs | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index 0c63e0a49..d036a9d7e 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -62,10 +62,9 @@ public static IServiceCollection AddDaprWorkflow( var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!string.IsNullOrEmpty(apiToken)) { - // serviceCollection.ConfigureDurableGrpcClient(apiToken); HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); - builder.UseGrpc(CreateChannel(client)); + builder.UseGrpc(CreateChannel(address, client)); } else { @@ -102,10 +101,9 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!string.IsNullOrEmpty(apiToken)) { - // services.ConfigureDurableGrpcClient(apiToken); HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); - builder.UseGrpc(CreateChannel(client)); + builder.UseGrpc(CreateChannel(address, client)); } else { @@ -153,19 +151,30 @@ static bool TryGetGrpcAddress(out string address) return false; } - static GrpcChannel CreateChannel(HttpClient client) + static GrpcChannel CreateChannel(string address, HttpClient client) { - var address = "localhost"; + + var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); + if (!String.IsNullOrEmpty(daprEndpoint)) { + GrpcChannelOptions options1 = new() { HttpClient = client}; + return GrpcChannel.ForAddress(address, options1); + } + var daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); if (int.TryParse(daprPortStr, out int daprGrpcPort)) { - // There is a bug in the Durable Task SDK that requires us to change the format of the address - // depending on the version of .NET that we're targeting. For now, we work around this manually. -#if NET6_0_OR_GREATER - address = $"http://localhost:{daprGrpcPort}"; -#else - address = $"localhost:{daprGrpcPort}"; -#endif + // If there is no address passed in, we default to localhost + if (String.IsNullOrEmpty(address)) + { + // There is a bug in the Durable Task SDK that requires us to change the format of the address + // depending on the version of .NET that we're targeting. For now, we work around this manually. + #if NET6_0_OR_GREATER + address = $"http://localhost:{daprGrpcPort}"; + #else + address = $"localhost:{daprGrpcPort}"; + #endif + } + } GrpcChannelOptions options = new() { HttpClient = client}; return GrpcChannel.ForAddress(address, options); From 980017f79ff481c1aa1c5cdf74223a04e6e3b37c Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 5 Sep 2023 18:39:25 -0600 Subject: [PATCH 5/8] Potential fix for grpc workflow issue pt2 Signed-off-by: Ryan Lettieri --- src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index d036a9d7e..df3173444 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -156,8 +156,8 @@ static GrpcChannel CreateChannel(string address, HttpClient client) var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); if (!String.IsNullOrEmpty(daprEndpoint)) { - GrpcChannelOptions options1 = new() { HttpClient = client}; - return GrpcChannel.ForAddress(address, options1); + GrpcChannelOptions options = new() { HttpClient = client}; + return GrpcChannel.ForAddress(daprEndpoint, options); } var daprPortStr = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT"); @@ -176,8 +176,8 @@ static GrpcChannel CreateChannel(string address, HttpClient client) } } - GrpcChannelOptions options = new() { HttpClient = client}; - return GrpcChannel.ForAddress(address, options); + GrpcChannelOptions options1 = new() { HttpClient = client}; + return GrpcChannel.ForAddress(address, options1); } } } From fa5ab832c0595ddc8d29f33ccb47a4d49e604cdd Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Tue, 5 Sep 2023 20:23:12 -0600 Subject: [PATCH 6/8] Cleaning up workflow service collection code Signed-off-by: Ryan Lettieri --- src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index df3173444..d29f51699 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -154,9 +154,9 @@ static bool TryGetGrpcAddress(out string address) static GrpcChannel CreateChannel(string address, HttpClient client) { + GrpcChannelOptions options = new() { HttpClient = client}; var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); if (!String.IsNullOrEmpty(daprEndpoint)) { - GrpcChannelOptions options = new() { HttpClient = client}; return GrpcChannel.ForAddress(daprEndpoint, options); } @@ -176,8 +176,7 @@ static GrpcChannel CreateChannel(string address, HttpClient client) } } - GrpcChannelOptions options1 = new() { HttpClient = client}; - return GrpcChannel.ForAddress(address, options1); + return GrpcChannel.ForAddress(address, options); } } } From bfa2b86a73acff99b30535f434929d7a3878b626 Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Thu, 7 Sep 2023 00:26:26 -0600 Subject: [PATCH 7/8] Using and fixing daprdefaults for workflow api token default Signed-off-by: Ryan Lettieri --- src/Dapr.Workflow/Dapr.Workflow.csproj | 4 ++++ .../WorkflowServiceCollectionExtensions.cs | 19 ++++++++++-------- src/Shared/DaprDefaults.cs | 20 +++++++++---------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Dapr.Workflow/Dapr.Workflow.csproj b/src/Dapr.Workflow/Dapr.Workflow.csproj index 781e891d0..9d8ba1a4e 100644 --- a/src/Dapr.Workflow/Dapr.Workflow.csproj +++ b/src/Dapr.Workflow/Dapr.Workflow.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index d29f51699..3c6ce63e0 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -20,12 +20,15 @@ namespace Dapr.Workflow using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System.Net.Http; + using Dapr; /// /// Contains extension methods for using Dapr Workflow with dependency injection. /// public static class WorkflowServiceCollectionExtensions { + private static string daprApiToken = ""; + /// /// Adds Dapr Workflow support to the service collection. /// @@ -59,11 +62,11 @@ public static IServiceCollection AddDaprWorkflow( if (TryGetGrpcAddress(out string address)) { - var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); - if (!string.IsNullOrEmpty(apiToken)) + daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); + if (!string.IsNullOrEmpty(daprApiToken)) { HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + client.DefaultRequestHeaders.Add("Dapr-Api-Token", daprApiToken); builder.UseGrpc(CreateChannel(address, client)); } else @@ -98,11 +101,11 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s { if (TryGetGrpcAddress(out string address)) { - var apiToken = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); - if (!string.IsNullOrEmpty(apiToken)) + daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); + if (!string.IsNullOrEmpty(daprApiToken)) { HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Add("Dapr-Api-Token", apiToken); + client.DefaultRequestHeaders.Add("Dapr-Api-Token", daprApiToken); builder.UseGrpc(CreateChannel(address, client)); } else @@ -128,7 +131,7 @@ static bool TryGetGrpcAddress(out string address) // 1. DaprDefaults.cs uses 127.0.0.1 instead of localhost, which prevents testing with Dapr on WSL2 and the app on Windows // 2. DaprDefaults.cs doesn't compile when the project has C# nullable reference types enabled. // If the above issues are fixed (ensuring we don't regress anything) we should switch to using the logic in DaprDefaults.cs. - var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); + var daprEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(); if (!String.IsNullOrEmpty(daprEndpoint)) { address = daprEndpoint; return true; @@ -155,7 +158,7 @@ static GrpcChannel CreateChannel(string address, HttpClient client) { GrpcChannelOptions options = new() { HttpClient = client}; - var daprEndpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); + var daprEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(); if (!String.IsNullOrEmpty(daprEndpoint)) { return GrpcChannel.ForAddress(daprEndpoint, options); } diff --git a/src/Shared/DaprDefaults.cs b/src/Shared/DaprDefaults.cs index 1ddab49b0..b738de921 100644 --- a/src/Shared/DaprDefaults.cs +++ b/src/Shared/DaprDefaults.cs @@ -17,10 +17,10 @@ namespace Dapr { internal static class DaprDefaults { - private static string httpEndpoint; - private static string grpcEndpoint; - private static string daprApiToken; - private static string appApiToken; + private static string httpEndpoint = string.Empty; + private static string grpcEndpoint = string.Empty; + private static string daprApiToken = string.Empty; + private static string appApiToken = string.Empty; /// /// Get the value of environment variable DAPR_API_TOKEN @@ -31,11 +31,11 @@ public static string GetDefaultDaprApiToken() // Lazy-init is safe because this is just populating the default // We don't plan to support the case where the user changes environment variables // for a running process. - if (daprApiToken == null) + if (string.IsNullOrEmpty(daprApiToken)) { // Treat empty the same as null since it's an environment variable var value = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); - daprApiToken = (value == string.Empty) ? null : value; + daprApiToken = string.IsNullOrEmpty(value) ? string.Empty : value; } return daprApiToken; @@ -47,10 +47,10 @@ public static string GetDefaultDaprApiToken() /// The value of environment variable APP_API_TOKEN public static string GetDefaultAppApiToken() { - if (appApiToken == null) + if (string.IsNullOrEmpty(appApiToken)) { var value = Environment.GetEnvironmentVariable("APP_API_TOKEN"); - appApiToken = (value == string.Empty) ? null : value; + appApiToken = string.IsNullOrEmpty(value) ? string.Empty : value; } return appApiToken; @@ -62,7 +62,7 @@ public static string GetDefaultAppApiToken() /// The value of HTTP endpoint based off environment variables public static string GetDefaultHttpEndpoint() { - if (httpEndpoint == null) + if (string.IsNullOrEmpty(httpEndpoint)) { var endpoint = Environment.GetEnvironmentVariable("DAPR_HTTP_ENDPOINT"); if (!string.IsNullOrEmpty(endpoint)) { @@ -84,7 +84,7 @@ public static string GetDefaultHttpEndpoint() /// The value of gRPC endpoint based off environment variables public static string GetDefaultGrpcEndpoint() { - if (grpcEndpoint == null) + if (string.IsNullOrEmpty(grpcEndpoint)) { var endpoint = Environment.GetEnvironmentVariable("DAPR_GRPC_ENDPOINT"); if (!string.IsNullOrEmpty(endpoint)) { From 5704c079fa39938598dffa7b1911f182195cb2ce Mon Sep 17 00:00:00 2001 From: Ryan Lettieri Date: Thu, 7 Sep 2023 01:57:59 -0600 Subject: [PATCH 8/8] more feedback Signed-off-by: Ryan Lettieri --- src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index 3c6ce63e0..50880ab24 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -27,7 +27,6 @@ namespace Dapr.Workflow /// public static class WorkflowServiceCollectionExtensions { - private static string daprApiToken = ""; /// /// Adds Dapr Workflow support to the service collection. @@ -62,10 +61,10 @@ public static IServiceCollection AddDaprWorkflow( if (TryGetGrpcAddress(out string address)) { - daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); + var daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); if (!string.IsNullOrEmpty(daprApiToken)) { - HttpClient client = new HttpClient(); + var client = new HttpClient(); client.DefaultRequestHeaders.Add("Dapr-Api-Token", daprApiToken); builder.UseGrpc(CreateChannel(address, client)); } @@ -101,10 +100,10 @@ public static IServiceCollection AddDaprWorkflowClient(this IServiceCollection s { if (TryGetGrpcAddress(out string address)) { - daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); + var daprApiToken = DaprDefaults.GetDefaultDaprApiToken(); if (!string.IsNullOrEmpty(daprApiToken)) { - HttpClient client = new HttpClient(); + var client = new HttpClient(); client.DefaultRequestHeaders.Add("Dapr-Api-Token", daprApiToken); builder.UseGrpc(CreateChannel(address, client)); }