Skip to content

Commit

Permalink
Add Token Credential Samples with DTFx.AzureStorage v1 and v2 (#1118)
Browse files Browse the repository at this point in the history
* initial commit

* Update ReadMe.md

* update by comments

* remove "en-us" in the link

* remove en-us in the links

* update by comments

* udpate token credential sample

* update by comment

* Update ConsoleApp.csproj

* Update ConsoleApp.csproj

* remove duplicate method
  • Loading branch information
nytian authored Jun 26, 2024
1 parent 2ba65e8 commit 8ddb4a6
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="1.17.3" />
</ItemGroup>

</Project>
72 changes: 72 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Azure.Core;
using Azure.Identity;
using DurableTask.AzureStorage;
using DurableTask.Core;
using Microsoft.WindowsAzure.Storage.Auth;

internal class Program
{
private static async Task Main(string[] args)
{
// Create credential based on the configuration
var credential = new DefaultAzureCredential();
string[] scopes = new string[] { "https://storage.azure.com/.default" }; // Scope for Azure Storage

static Task<NewTokenAndFrequency> RenewTokenFuncAsync(object state, CancellationToken cancellationToken)
{
var credential = new DefaultAzureCredential();
var initialToken = credential.GetToken(new TokenRequestContext(new[] { "https://storage.azure.com/.default" }));
var expiresAfter = initialToken.ExpiresOn - DateTimeOffset.UtcNow - TimeSpan.FromMinutes(10);
return Task.FromResult(new NewTokenAndFrequency(initialToken.Token, expiresAfter));
}

// Get the token
var accessToken = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(scopes));

var service = new AzureStorageOrchestrationService(new AzureStorageOrchestrationServiceSettings
{
StorageAccountDetails = new StorageAccountDetails
{
AccountName = "YourStorageAccount",
EndpointSuffix = "core.windows.net",
StorageCredentials = new StorageCredentials(new Microsoft.WindowsAzure.Storage.Auth.TokenCredential(
accessToken.Token,
RenewTokenFuncAsync,
null,
TimeSpan.FromMinutes(5)))
}
});

var client = new TaskHubClient(service);
var worker = new TaskHubWorker(service);

worker.AddTaskOrchestrations(typeof(SampleOrchestration));
worker.AddTaskActivities(typeof(SampleActivity));

await worker.StartAsync();

var instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World");

var result = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1));

Console.WriteLine($"Orchestration result : {result.Output}");

await worker.StopAsync();
}
}

public class SampleOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
return await context.ScheduleTask<string>(typeof(SampleActivity), input);
}
}

public class SampleActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string input)
{
return "Hello, " + input + "!";
}
}
19 changes: 19 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Token Credential Sample

This sample demonstrates how to configure a Identity based connection when using DurableTask.AzureStorage v1.x as the orchestration provider for a Durable Task project.

> Note:
> Identity based connection **is not supported** with .NET framework 4.x with DurableTask.AzureStorage v1.x
## Configuration Prerequisites

Before running this sample, you must

1. Create a new Azure Storage account or reuse an existing one
2. Create your identity in the Azure Portal. Detailed instructions can be found [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=certificate)
3. Assign Role-based Access Controls (RBAC) of the storage account created in step 1 to the identity created in step 2 with [these instructions](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal-managed-identity#Overview).
* Storage Queue Data Contributor
* Storage Blob Data Contributor
* Storage Table Data Contributor
4. Add the identity required information to your app's configuration.
5. Set `AccountName` to the name of the storage account. AccountName can be replaced with Storage Account BlobServiceUri, TableServiceUri and QueueServiceUri.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="2.0.0-rc.3" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
</ItemGroup>

</Project>
53 changes: 53 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using DurableTask.AzureStorage;
using DurableTask.Core;
using Azure.Identity;

internal class Program
{
private static async Task Main(string[] args)
{
var credential = new DefaultAzureCredential();

// Pass the credential created to the StorageAccountClientProvider to start an AzureStorageOrchestrationService
var service = new AzureStorageOrchestrationService(new AzureStorageOrchestrationServiceSettings
{
StorageAccountClientProvider = new StorageAccountClientProvider("AccountName", credential),
});

var client = new TaskHubClient(service);
var worker = new TaskHubWorker(service);

worker.AddTaskOrchestrations(typeof(SampleOrchestration));
worker.AddTaskActivities(typeof(SampleActivity));

await worker.StartAsync();

var instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World");

var result = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1));

Console.WriteLine($"Orchestration result : {result.Output}");

await worker.StopAsync();
}
}

public class SampleOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
await context.ScheduleTask<string>(typeof(SampleActivity), input);

return "Orchestrator Finished!";
}
}

public class SampleActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string input)
{
Console.WriteLine("saying hello to " + input);
return "Hello " + input + "!";
}
}

16 changes: 16 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Token Credential Sample

This sample demonstrates how to configure a Identity based connection when using DurableTask.AzureStorage v2.x as the orchestration provider for a Durable Task project.

## Configuration Prerequisites

Before running this sample, you must

1. Create a new Azure Storage account or reuse an existing one
2. Create your identity in the Azure Portal. Detailed instructions can be found [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=certificate)
3. Assign Role-based Access Controls (RBAC) of the storage account created in step 1 to the identity created in step 2 with [these instructions](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal-managed-identity#Overview).
* Storage Queue Data Contributor
* Storage Blob Data Contributor
* Storage Table Data Contributor
4. Add the identity information to your app or configuration. In the sample here, client secret credential requires clientId, clientSecret and tenantId.
5. Set `AccountName` to the name of the storage account. AccountName can be replaced with Storage Account BlobServiceUri, TableServiceUri and QueueServiceUri.

0 comments on commit 8ddb4a6

Please sign in to comment.