-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' of https://github.com/Azure/azure-functions-durabl…
…e-extension into dajusto/remove-potentially-sensitive-logs
- Loading branch information
Showing
16 changed files
with
523 additions
and
12 deletions.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
samples/durable-client-managed-identity/aspnetcore-app/Controllers/TodoController.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 |
---|---|---|
@@ -0,0 +1,130 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask.Options; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.Extensions.Configuration; | ||
using Newtonsoft.Json; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Threading.Tasks; | ||
using TodoApi.Models; | ||
|
||
namespace TodoApi.Controllers | ||
{ | ||
[Route("api/[controller]")] | ||
[ApiController] | ||
public class TodoController : Controller | ||
{ | ||
private readonly TodoContext _context; | ||
private readonly IDurableClient _client; | ||
|
||
public TodoController(TodoContext context, IDurableClientFactory clientFactory, IConfiguration configuration) | ||
{ | ||
_context = context; | ||
|
||
if (_context.TodoItems.Count() == 0) | ||
{ | ||
_context.TodoItems.Add(new TodoItem { Name = "Item1" }); | ||
_context.SaveChanges(); | ||
} | ||
|
||
_client = clientFactory.CreateClient(new DurableClientOptions | ||
{ | ||
ConnectionName = configuration["MyStorage"], | ||
TaskHub = configuration["TaskHub"] | ||
}); | ||
} | ||
|
||
// GET: api/Todo | ||
[HttpGet] | ||
public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItem() | ||
{ | ||
return await _context.TodoItems.ToListAsync(); | ||
} | ||
|
||
// GET: api/Todo/5 | ||
[HttpGet("{id}")] | ||
public async Task<ActionResult<TodoItem>> GetTodoItem(long id) | ||
{ | ||
var todoItem = await _context.TodoItems.FindAsync(id); | ||
|
||
if (todoItem == null) | ||
{ | ||
return NotFound(); | ||
} | ||
|
||
return todoItem; | ||
} | ||
|
||
// PUT: api/Todo/5 | ||
// To protect from overposting attacks, please enable the specific properties you want to bind to, for | ||
// more details see https://aka.ms/RazorPagesCRUD. | ||
[HttpPut("{id}")] | ||
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem) | ||
{ | ||
if (id != todoItem.Id) | ||
{ | ||
return BadRequest(); | ||
} | ||
|
||
_context.Entry(todoItem).State = EntityState.Modified; | ||
|
||
try | ||
{ | ||
await _context.SaveChangesAsync(); | ||
} | ||
catch (DbUpdateConcurrencyException) | ||
{ | ||
if (!TodoItemExists(id)) | ||
{ | ||
return NotFound(); | ||
} | ||
else | ||
{ | ||
throw; | ||
} | ||
} | ||
|
||
return NoContent(); | ||
} | ||
|
||
// POST: api/Todo | ||
// To protect from overposting attacks, please enable the specific properties you want to bind to, for | ||
// more details see https://aka.ms/RazorPagesCRUD. | ||
[HttpPost] | ||
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem) | ||
{ | ||
_context.TodoItems.Add(todoItem); | ||
await _context.SaveChangesAsync(); | ||
|
||
string instanceId = await _client.StartNewAsync<string>("SetReminder", todoItem.Name); | ||
|
||
return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem); | ||
} | ||
|
||
// DELETE: api/Todo/5 | ||
[HttpDelete("{id}")] | ||
public async Task<ActionResult<TodoItem>> DeleteTodoItem(long id) | ||
{ | ||
var todoItem = await _context.TodoItems.FindAsync(id); | ||
if (todoItem == null) | ||
{ | ||
return NotFound(); | ||
} | ||
|
||
_context.TodoItems.Remove(todoItem); | ||
await _context.SaveChangesAsync(); | ||
|
||
return todoItem; | ||
} | ||
|
||
private bool TodoItemExists(long id) | ||
{ | ||
return _context.TodoItems.Any(e => e.Id == id); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
samples/durable-client-managed-identity/aspnetcore-app/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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
namespace TodoApi | ||
{ | ||
public class Program | ||
{ | ||
|
||
static void Main(string[] args) | ||
{ | ||
CreateHostBuilder(args).Build().Run(); | ||
} | ||
|
||
public static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
samples/durable-client-managed-identity/aspnetcore-app/README.md
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,37 @@ | ||
# ASP.NET Core API To Do List Sample with Identity-Based Connection | ||
|
||
This example is adapted from the [To Do List sample](https://github.com/Azure-Samples/dotnet-core-api) in the Azure-Samples repository. It demonstrates an ASP.NET Core application with an injected Durable Client and identity-based connections. In this sample, the Durable Client is configured to use a storage connection with a custom name, `MyStorage`, and is set up to utilize a client secret for authentication. | ||
|
||
|
||
## To make the sample run, you need to: | ||
|
||
1. Create an identity for your Function App in the Azure portal. | ||
|
||
2. Grant the following Role-Based Access Control (RBAC) permissions to the identity: | ||
- Storage Queue Data Contributor | ||
- Storage Blob Data Contributor | ||
- Storage Table Data Contributor | ||
|
||
3. Link your storage account to your Function App by adding either of these two details to your configuration, which is appsettings.json file in this sample . | ||
- accountName | ||
- blobServiceUri, queueServiceUri and tableServiceUri | ||
|
||
4. Add the required identity information to your Functions App configuration, which is appsettings.json file in this sample. | ||
- system-assigned identity: nothing needs to be provided. | ||
- user-assigned identity: | ||
- credential: managedidentity | ||
- clientId | ||
- client secret application: | ||
- clientId | ||
- ClientSecret | ||
- tenantId | ||
|
||
|
||
## Notes | ||
- The storage connection information must be provided in the format specified in the appsettings.json file. | ||
- If your storage information is saved in a custom-named JSON file, be sure to add it to your configuration as shown below. | ||
```csharp | ||
this.Configuration = new ConfigurationBuilder() | ||
.AddJsonFile("myjson.json") | ||
.Build(); | ||
``` |
74 changes: 74 additions & 0 deletions
74
samples/durable-client-managed-identity/aspnetcore-app/Startup.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 |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.OpenApi.Models; | ||
using TodoApi.Models; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask; | ||
|
||
namespace TodoApi | ||
{ | ||
public class Startup | ||
{ | ||
public Startup(IConfiguration configuration) | ||
{ | ||
Configuration = configuration; | ||
} | ||
|
||
public IConfiguration Configuration { get; } | ||
|
||
// This method gets called by the runtime. Use this method to add services to the container. | ||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
// AddDurableClientFactory() registers IDurableClientFactory as a service so the application | ||
// can consume it and and call the Durable Client APIs | ||
services.AddDurableClientFactory(); | ||
|
||
services.AddControllers(); | ||
|
||
// Register the Swagger generator, defining 1 or more Swagger documents | ||
services.AddSwaggerGen(c => | ||
{ | ||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); | ||
}); | ||
|
||
services.AddDbContext<TodoContext>(options => options.UseInMemoryDatabase("TodoList")); | ||
} | ||
|
||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||
{ | ||
// Enable middleware to serve generated Swagger as a JSON endpoint. | ||
app.UseSwagger(); | ||
|
||
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), | ||
// specifying the Swagger JSON endpoint. | ||
app.UseSwaggerUI(c => | ||
{ | ||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); | ||
}); | ||
|
||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
} | ||
|
||
//app.UseHttpsRedirection(); | ||
|
||
app.UseDefaultFiles(); | ||
|
||
app.UseStaticFiles(); | ||
|
||
app.UseRouting(); | ||
|
||
app.UseAuthorization(); | ||
|
||
app.UseEndpoints(endpoints => | ||
{ | ||
endpoints.MapControllers(); | ||
}); | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
samples/durable-client-managed-identity/aspnetcore-app/ToDoList.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,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="EntityFramework" Version="6.4.0" /> | ||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.13.5" /> | ||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.2" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.3" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.0" /> | ||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" /> | ||
</ItemGroup> | ||
</Project> |
25 changes: 25 additions & 0 deletions
25
samples/durable-client-managed-identity/aspnetcore-app/ToDoList.sln
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,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.30503.244 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToDoList", "ToDoList.csproj", "{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {E7920E27-E4F7-47B7-B1B9-01F8645883CA} | ||
EndGlobalSection | ||
EndGlobal |
17 changes: 17 additions & 0 deletions
17
samples/durable-client-managed-identity/aspnetcore-app/appsettings.json
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,17 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft": "Warning", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
}, | ||
"AllowedHosts": "*", | ||
"TaskHub": "MyTestHub", | ||
"MyStorage": { | ||
"accountName": "YourStorageAccountName", | ||
"clientId": "<your client id here>", | ||
"clientsecret": "<your client secret here>", | ||
"tenantId": "<your tenant id here>" | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
samples/durable-client-managed-identity/functions-app/ClientFunction.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 |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Azure.WebJobs; | ||
using Microsoft.Azure.WebJobs.Extensions.Http; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations; | ||
using Microsoft.Azure.WebJobs.Extensions.DurableTask.Options; | ||
using Microsoft.Extensions.Configuration; | ||
|
||
namespace DurableClientSampleFunctionApp | ||
{ | ||
public class ClientFunction | ||
{ | ||
private readonly IDurableClient _client; | ||
|
||
public ClientFunction(IDurableClientFactory clientFactory, IConfiguration configuration) | ||
{ | ||
_client = clientFactory.CreateClient(new DurableClientOptions | ||
{ | ||
ConnectionName = "ClientStorage", | ||
TaskHub = configuration["TaskHub"] | ||
}); | ||
} | ||
|
||
[FunctionName("CallHelloSequence")] | ||
public async Task<IActionResult> Run( | ||
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, | ||
ILogger log) | ||
{ | ||
log.LogInformation("C# HTTP trigger function processed a request."); | ||
|
||
string instanceId = await _client.StartNewAsync("E1_HelloSequence"); | ||
|
||
DurableOrchestrationStatus status = await _client.GetStatusAsync(instanceId); | ||
|
||
while (status.RuntimeStatus == OrchestrationRuntimeStatus.Pending || | ||
status.RuntimeStatus == OrchestrationRuntimeStatus.Running || | ||
status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew) | ||
{ | ||
await Task.Delay(10000); | ||
status = await _client.GetStatusAsync(instanceId); | ||
} | ||
|
||
return new ObjectResult(status); | ||
} | ||
} | ||
} |
Oops, something went wrong.