-
Notifications
You must be signed in to change notification settings - Fork 296
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update Managed Identity Samples with Logging (#1124)
- Loading branch information
Showing
7 changed files
with
203 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 0 additions & 15 deletions
15
samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/ConsoleApp.csproj
This file was deleted.
Oops, something went wrong.
19 changes: 19 additions & 0 deletions
19
samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/ManagedIdentity.AzStorageV1.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<LangVersion>Latest</LangVersion> | ||
<Nullable>enable</Nullable> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Azure.Identity" Version="1.12.0" /> | ||
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="1.17.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.4" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
140 changes: 82 additions & 58 deletions
140
samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,96 @@ | ||
using Azure.Core; | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Azure.Core; | ||
using Azure.Identity; | ||
using DurableTask.AzureStorage; | ||
using DurableTask.Core; | ||
using Microsoft.Extensions.Azure; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.WindowsAzure.Storage.Auth; | ||
|
||
internal class Program | ||
// Create a DefaultAzureCredential used to access the Azure Storage Account. | ||
// The identity will require the following roles on the resource: | ||
// - Azure Blob Data Contributor | ||
// - Azure Queue Data Contributor | ||
// - Azure Table Data Contributor | ||
DefaultAzureCredential credential = new(); | ||
|
||
// Create a diagnostic logger factory for reading telemetry | ||
ILoggerFactory loggerFactory = LoggerFactory.Create(b => b | ||
.AddConsole() | ||
.AddFilter("Azure.Core", LogLevel.Warning) | ||
.AddFilter("Azure.Identity", LogLevel.Warning)); | ||
|
||
// The Azure SDKs used by the Azure.Identity library write their telemetry via Event Sources | ||
using AzureEventSourceLogForwarder logForwarder = new(loggerFactory); | ||
logForwarder.Start(); | ||
|
||
NewTokenAndFrequency initialTokenInfo = await GetTokenInfoAsync(credential); | ||
AzureStorageOrchestrationService service = new(new AzureStorageOrchestrationServiceSettings | ||
{ | ||
private static async Task Main(string[] args) | ||
StorageAccountDetails = new StorageAccountDetails | ||
{ | ||
// 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(); | ||
} | ||
AccountName = "YourStorageAccount", | ||
EndpointSuffix = "core.windows.net", | ||
StorageCredentials = new StorageCredentials(new Microsoft.WindowsAzure.Storage.Auth.TokenCredential( | ||
initialTokenInfo.Token, | ||
GetTokenInfoAsync, | ||
credential, | ||
initialTokenInfo.Frequency.GetValueOrDefault())) | ||
}, | ||
LoggerFactory = loggerFactory, | ||
}); | ||
|
||
TaskHubClient client = new(service, loggerFactory: loggerFactory); | ||
TaskHubWorker worker = new(service, loggerFactory); | ||
|
||
worker.AddTaskOrchestrations(typeof(SampleOrchestration)); | ||
worker.AddTaskActivities(typeof(SampleActivity)); | ||
|
||
await worker.StartAsync(); | ||
|
||
OrchestrationInstance instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World"); | ||
OrchestrationState state = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1)); | ||
|
||
ILogger logger = loggerFactory.CreateLogger(nameof(Program)); | ||
logger.LogInformation("Orchestration output: {Output}", state.Output); | ||
|
||
await worker.StopAsync(); | ||
|
||
static async Task<NewTokenAndFrequency> GetTokenInfoAsync(object state, CancellationToken cancellationToken = default) | ||
{ | ||
const string AzureStorageScope = "https://storage.azure.com/.default"; | ||
|
||
if (state is not DefaultAzureCredential credential) | ||
throw new InvalidOperationException(); | ||
|
||
AccessToken accessToken = await credential.GetTokenAsync(new TokenRequestContext([AzureStorageScope]), cancellationToken); | ||
TimeSpan refreshFrequency = accessToken.ExpiresOn - DateTimeOffset.UtcNow - TimeSpan.FromMinutes(10); // 10 minutes before expiration | ||
return new NewTokenAndFrequency(accessToken.Token, refreshFrequency); | ||
} | ||
|
||
public class SampleOrchestration : TaskOrchestration<string, string> | ||
internal sealed class SampleOrchestration : TaskOrchestration<string, string> | ||
{ | ||
public override async Task<string> RunTask(OrchestrationContext context, string input) | ||
{ | ||
return await context.ScheduleTask<string>(typeof(SampleActivity), input); | ||
} | ||
public override Task<string> RunTask(OrchestrationContext context, string input) => | ||
context.ScheduleTask<string>(typeof(SampleActivity), input); | ||
} | ||
|
||
public class SampleActivity : TaskActivity<string, string> | ||
internal sealed class SampleActivity : TaskActivity<string, string> | ||
{ | ||
protected override string Execute(TaskContext context, string input) | ||
{ | ||
return "Hello, " + input + "!"; | ||
} | ||
protected override string Execute(TaskContext context, string input) => | ||
"Hello, " + input + "!"; | ||
} |
15 changes: 0 additions & 15 deletions
15
samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/ConsoleApp.csproj
This file was deleted.
Oops, something went wrong.
19 changes: 19 additions & 0 deletions
19
samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/ManagedIdentity.AzStorageV2.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<LangVersion>Latest</LangVersion> | ||
<Nullable>enable</Nullable> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Azure.Identity" Version="1.12.0" /> | ||
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="2.0.0-rc.3" /> | ||
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.4" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
94 changes: 56 additions & 38 deletions
94
samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,71 @@ | ||
using DurableTask.AzureStorage; | ||
using DurableTask.Core; | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Threading.Tasks; | ||
using Azure.Identity; | ||
using DurableTask.AzureStorage; | ||
using DurableTask.Core; | ||
using Microsoft.Extensions.Azure; | ||
using Microsoft.Extensions.Logging; | ||
|
||
// Create a DefaultAzureCredential used to access the Azure Storage Account. | ||
// The identity will require the following roles on the resource: | ||
// - Azure Blob Data Contributor | ||
// - Azure Queue Data Contributor | ||
// - Azure Table Data Contributor | ||
DefaultAzureCredential credential = new(); | ||
|
||
// Create a diagnostic logger factory for reading telemetry | ||
ILoggerFactory loggerFactory = LoggerFactory.Create(b => b | ||
.AddConsole() | ||
.AddFilter("Azure.Core", LogLevel.Warning) | ||
.AddFilter("Azure.Identity", LogLevel.Warning)); | ||
|
||
internal class Program | ||
// The Azure SDKs used by the Azure.Identity and Azure Storage client libraries write their telemetry via Event Sources | ||
using AzureEventSourceLogForwarder logForwarder = new(loggerFactory); | ||
logForwarder.Start(); | ||
|
||
AzureStorageOrchestrationService service = new(new AzureStorageOrchestrationServiceSettings | ||
{ | ||
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), | ||
}); | ||
LoggerFactory = loggerFactory, | ||
StorageAccountClientProvider = new StorageAccountClientProvider("YourStorageAccount", credential), | ||
}); | ||
|
||
var client = new TaskHubClient(service); | ||
var worker = new TaskHubWorker(service); | ||
TaskHubClient client = new(service, loggerFactory: loggerFactory); | ||
TaskHubWorker worker = new(service, loggerFactory); | ||
|
||
worker.AddTaskOrchestrations(typeof(SampleOrchestration)); | ||
worker.AddTaskActivities(typeof(SampleActivity)); | ||
worker.AddTaskOrchestrations(typeof(SampleOrchestration)); | ||
worker.AddTaskActivities(typeof(SampleActivity)); | ||
|
||
await worker.StartAsync(); | ||
await worker.StartAsync(); | ||
|
||
var instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World"); | ||
OrchestrationInstance instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World"); | ||
OrchestrationState state = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1)); | ||
|
||
var result = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1)); | ||
ILogger logger = loggerFactory.CreateLogger(nameof(Program)); | ||
logger.LogInformation("Orchestration output: {Output}", state.Output); | ||
|
||
Console.WriteLine($"Orchestration result : {result.Output}"); | ||
|
||
await worker.StopAsync(); | ||
} | ||
} | ||
await worker.StopAsync(); | ||
|
||
public class SampleOrchestration : TaskOrchestration<string, string> | ||
internal sealed 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 override Task<string> RunTask(OrchestrationContext context, string input) => | ||
context.ScheduleTask<string>(typeof(SampleActivity), input); | ||
} | ||
|
||
public class SampleActivity : TaskActivity<string, string> | ||
internal sealed class SampleActivity : TaskActivity<string, string> | ||
{ | ||
protected override string Execute(TaskContext context, string input) | ||
{ | ||
Console.WriteLine("saying hello to " + input); | ||
return "Hello " + input + "!"; | ||
} | ||
protected override string Execute(TaskContext context, string input) => | ||
"Hello, " + input + "!"; | ||
} | ||
|