mirror of https://github.com/dapr/dotnet-sdk.git
Workflow Authoring: initial methods (#981)
* Initial workflow sdk implementation
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Dapr Workflow initial methods for dotnet-sdk
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Handled mistake in the workflow name
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Added common license header to .cs files
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Changed namespace to Dapr.Workflow
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Addressed docs related review comments
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Reverted few changes to avoid compile time error
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Examples changes
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Added readonly dictionary
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Added .csproj to sln file with few minor comments
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
* Change nuget dependency and update folder structure
This commit re-adds commit d5b9189da5
but with DCO.
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Update Durable Task SDK version & simplify example
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
* Addresses some PR comments.
* Rename ActivityContext to WorkflowActivityContext
* Change example webapp port away from 8080x
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Addressing review comments.
* Rename workflow and activity in example to be more meangniful
* Add parameter documentation to some methods
* Use local project references when appropriate
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Adding more documentation
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Replaces custom AddSingletonIfNotPresent with std. TryAddSingleton
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Renames AddWorkflowsToRegistry to AddActivitiesToRegistry to better match what it does
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Add cancelation token overload for WorkflowContext.WaitForExternalEventAsync
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Renaming AddWorkflowsAndActivitiesToRegistry
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
* Defer launch URL and port to launchSettings.json
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Co-authored-by: Amulya Varote <amulyavarote@microsoft.com>
Co-authored-by: Chris Gillum <cgillum@microsoft.com>
This commit is contained in:
parent
ab5403ed01
commit
2aa4806c44
65
all.sln
65
all.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29318.209
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32929.385
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors", "src\Dapr.Actors\Dapr.Actors.csproj", "{C2DB4B64-B7C3-4FED-8753-C040F677C69A}"
|
||||
EndProject
|
||||
|
@ -35,57 +35,63 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.Test", "test\Dapr.Actors.AspNetCore.Test\Dapr.Actors.AspNetCore.Test.csproj", "{9C1D6ABA-5EDE-4FA0-A8A9-0AB98CB74737}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.Test", "test\Dapr.Actors.AspNetCore.Test\Dapr.Actors.AspNetCore.Test.csproj", "{9C1D6ABA-5EDE-4FA0-A8A9-0AB98CB74737}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.IntegrationTest", "test\Dapr.Actors.AspNetCore.IntegrationTest\Dapr.Actors.AspNetCore.IntegrationTest.csproj", "{95BAF30B-8089-42CE-8530-6DFBCE1F6A07}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.IntegrationTest", "test\Dapr.Actors.AspNetCore.IntegrationTest\Dapr.Actors.AspNetCore.IntegrationTest.csproj", "{95BAF30B-8089-42CE-8530-6DFBCE1F6A07}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.IntegrationTest.App", "test\Dapr.Actors.AspNetCore.IntegrationTest.App\Dapr.Actors.AspNetCore.IntegrationTest.App.csproj", "{1BA7E772-8AA7-4D5A-800D-66B17F62421C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.IntegrationTest.App", "test\Dapr.Actors.AspNetCore.IntegrationTest.App\Dapr.Actors.AspNetCore.IntegrationTest.App.csproj", "{1BA7E772-8AA7-4D5A-800D-66B17F62421C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Extensions.Configuration.Test", "test\Dapr.Extensions.Configuration.Test\Dapr.Extensions.Configuration.Test.csproj", "{78FC19B2-396C-4ED2-BFD9-6C5667C61666}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Extensions.Configuration.Test", "test\Dapr.Extensions.Configuration.Test\Dapr.Extensions.Configuration.Test.csproj", "{78FC19B2-396C-4ED2-BFD9-6C5667C61666}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Extensions.Configuration", "src\Dapr.Extensions.Configuration\Dapr.Extensions.Configuration.csproj", "{B615B353-476C-43B9-A776-B193B0DBD256}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Extensions.Configuration", "src\Dapr.Extensions.Configuration\Dapr.Extensions.Configuration.csproj", "{B615B353-476C-43B9-A776-B193B0DBD256}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCore", "AspNetCore", "{A11DC259-D1DB-4686-AD28-A427D0BABA83}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcServiceSample", "examples\AspNetCore\GrpcServiceSample\GrpcServiceSample.csproj", "{2EC50C79-782D-4985-ABB1-AD07F35D1621}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcServiceSample", "examples\AspNetCore\GrpcServiceSample\GrpcServiceSample.csproj", "{2EC50C79-782D-4985-ABB1-AD07F35D1621}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoutingSample", "examples\AspNetCore\RoutingSample\RoutingSample.csproj", "{15A16323-2CCA-472E-BE79-07259DAD5F6F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingSample", "examples\AspNetCore\RoutingSample\RoutingSample.csproj", "{15A16323-2CCA-472E-BE79-07259DAD5F6F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecretStoreConfigurationProviderSample", "examples\AspNetCore\SecretStoreConfigurationProviderSample\SecretStoreConfigurationProviderSample.csproj", "{5BACBA51-03FE-4CE1-B0F5-9E9C2A132FAB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecretStoreConfigurationProviderSample", "examples\AspNetCore\SecretStoreConfigurationProviderSample\SecretStoreConfigurationProviderSample.csproj", "{5BACBA51-03FE-4CE1-B0F5-9E9C2A132FAB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControllerSample", "examples\AspNetCore\ControllerSample\ControllerSample.csproj", "{3160CC92-1D6E-42CB-AE89-9401C8CEC5CB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerSample", "examples\AspNetCore\ControllerSample\ControllerSample.csproj", "{3160CC92-1D6E-42CB-AE89-9401C8CEC5CB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actor", "Actor", "{02374BD0-BF0B-40F8-A04A-C4C4D61D4992}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IDemoActor", "examples\Actor\IDemoActor\IDemoActor.csproj", "{7957E852-1291-4FAA-9034-FB66CE817FF1}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IDemoActor", "examples\Actor\IDemoActor\IDemoActor.csproj", "{7957E852-1291-4FAA-9034-FB66CE817FF1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoActor", "examples\Actor\DemoActor\DemoActor.csproj", "{626D74DD-4F37-4F74-87A3-5A6888684F5E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoActor", "examples\Actor\DemoActor\DemoActor.csproj", "{626D74DD-4F37-4F74-87A3-5A6888684F5E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ActorClient", "examples\Actor\ActorClient\ActorClient.csproj", "{CC0A5C98-ACDE-4139-BA2F-2995A9B8E18C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActorClient", "examples\Actor\ActorClient\ActorClient.csproj", "{CC0A5C98-ACDE-4139-BA2F-2995A9B8E18C}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{A7F41094-8648-446B-AECD-DCC2CC871F73}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StateManagement", "examples\Client\StateManagement\StateManagement.csproj", "{F70AC78E-8925-4770-832A-2FC67A620EB2}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StateManagement", "examples\Client\StateManagement\StateManagement.csproj", "{F70AC78E-8925-4770-832A-2FC67A620EB2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceInvocation", "examples\Client\ServiceInvocation\ServiceInvocation.csproj", "{8B570E70-0E73-4042-A4B6-1CC3CC782A65}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceInvocation", "examples\Client\ServiceInvocation\ServiceInvocation.csproj", "{8B570E70-0E73-4042-A4B6-1CC3CC782A65}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublishSubscribe", "examples\Client\PublishSubscribe\PublishSubscribe.csproj", "{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublishSubscribe", "examples\Client\PublishSubscribe\PublishSubscribe.csproj", "{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test", "test\Dapr.E2E.Test\Dapr.E2E.Test.csproj", "{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test", "test\Dapr.E2E.Test\Dapr.E2E.Test.csproj", "{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.App", "test\Dapr.E2E.Test.App\Dapr.E2E.Test.App.csproj", "{345FC3FB-D1E9-4AE8-9052-17D20AB01FA2}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App", "test\Dapr.E2E.Test.App\Dapr.E2E.Test.App.csproj", "{345FC3FB-D1E9-4AE8-9052-17D20AB01FA2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.Actors", "test\Dapr.E2E.Test.Actors\Dapr.E2E.Test.Actors.csproj", "{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors", "test\Dapr.E2E.Test.Actors\Dapr.E2E.Test.Actors.csproj", "{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.App.Grpc", "test\Dapr.E2E.Test.App.Grpc\Dapr.E2E.Test.App.Grpc.csproj", "{E8212911-344B-4638-ADC3-B215BCDCAFD1}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App.Grpc", "test\Dapr.E2E.Test.App.Grpc\Dapr.E2E.Test.App.Grpc.csproj", "{E8212911-344B-4638-ADC3-B215BCDCAFD1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigurationApi", "examples\Client\ConfigurationApi\ConfigurationApi.csproj", "{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigurationApi", "examples\Client\ConfigurationApi\ConfigurationApi.csproj", "{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.App.ReentrantActors", "test\Dapr.E2E.Test.App.ReentrantActor\Dapr.E2E.Test.App.ReentrantActors.csproj", "{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App.ReentrantActors", "test\Dapr.E2E.Test.App.ReentrantActor\Dapr.E2E.Test.App.ReentrantActors.csproj", "{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistributedLock", "examples\Client\DistributedLock\DistributedLock.csproj", "{35031EDB-C0DE-453A-8335-D2EBEA2FC640}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock", "examples\Client\DistributedLock\DistributedLock.csproj", "{35031EDB-C0DE-453A-8335-D2EBEA2FC640}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Workflow", "src\Dapr.Workflow\Dapr.Workflow.csproj", "{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflow", "Workflow", "{BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowWebApp", "examples\Workflow\WorkflowWebApp\WorkflowWebApp.csproj", "{5C61ABED-7623-4C28-A5C9-C5972A0F669C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -217,6 +223,14 @@ Global
|
|||
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -256,6 +270,9 @@ Global
|
|||
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
|
||||
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7} = {DD020B34-460F-455F-8D17-CF4A949F100B}
|
||||
{35031EDB-C0DE-453A-8335-D2EBEA2FC640} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
|
||||
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
|
||||
{BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
|
||||
{5C61ABED-7623-4C28-A5C9-C5972A0F669C} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {65220BF2-EAE1-4CB2-AA58-EBE80768CB40}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
using Dapr.Workflow;
|
||||
|
||||
// The workflow host is a background service that connects to the sidecar over gRPC
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Dapr workflows are registered as part of the service configuration
|
||||
builder.Services.AddDaprWorkflow(options =>
|
||||
{
|
||||
// Example of registering a "PlaceOrder" workflow function
|
||||
options.RegisterWorkflow<string, string>("PlaceOrder", implementation: async (context, input) =>
|
||||
{
|
||||
// In real life there are other steps related to placing an order, like reserving
|
||||
// inventory and charging the customer credit card etc. But let's keep it simple ;)
|
||||
return await context.CallActivityAsync<string>("ShipProduct", "Coffee Beans");
|
||||
});
|
||||
|
||||
// Example of registering a "ShipProduct" workflow activity function
|
||||
options.RegisterActivity<string, string>("ShipProduct", implementation: (context, input) =>
|
||||
{
|
||||
return Task.FromResult($"We are shipping {input} to the customer using our hoard of drones!");
|
||||
});
|
||||
});
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
|
||||
// POST starts new workflow instances
|
||||
app.MapPost("/order", async (HttpContext context, WorkflowClient client) =>
|
||||
{
|
||||
string id = Guid.NewGuid().ToString()[..8];
|
||||
await client.ScheduleNewWorkflowAsync("PlaceOrder", id);
|
||||
|
||||
// return an HTTP 202 and a Location header to be used for status query
|
||||
return Results.AcceptedAtRoute("GetOrderEndpoint", new { id });
|
||||
});
|
||||
|
||||
// GET fetches metadata for specific order workflow instances
|
||||
app.MapGet("/order/{id}", async (string id, WorkflowClient client) =>
|
||||
{
|
||||
WorkflowMetadata metadata = await client.GetWorkflowMetadataAsync(id, getInputsAndOutputs: true);
|
||||
if (metadata.Exists)
|
||||
{
|
||||
return Results.Ok(metadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Results.NotFound($"No workflow created for order with ID = '{id}' was found.");
|
||||
}
|
||||
}).WithName("GetOrderEndpoint");
|
||||
|
||||
app.Run();
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"profiles": {
|
||||
"OrderingWebApi": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:10080"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Dapr.Workflow\Dapr.Workflow.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net6</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
### Create new order
|
||||
POST http://localhost:8080/workflow
|
||||
Content-Type: application/json
|
||||
|
||||
### Query placeholder
|
||||
GET http://localhost:8080/workflow/XXX
|
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- NuGet configuration -->
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net5;net6</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>Dapr.Workflow</PackageId>
|
||||
<Title>Dapr Workflow Authoring SDK</Title>
|
||||
<Description>Dapr Workflow SDK for building workflows as code with Dapr</Description>
|
||||
<VersionPrefix>0.1.0</VersionPrefix>
|
||||
<VersionSuffix>alpha</VersionSuffix>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.DurableTask.Client.Grpc" Version="1.0.0-rc.1" />
|
||||
<PackageReference Include="Microsoft.DurableTask.Worker.Grpc" Version="1.0.0-rc.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Dapr.Client\Dapr.Client.csproj" />
|
||||
<ProjectReference Include="..\Dapr.AspNetCore\Dapr.AspNetCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,43 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DurableTask;
|
||||
|
||||
/// <summary>
|
||||
/// Defines properties and methods for task activity context objects.
|
||||
/// </summary>
|
||||
public class WorkflowActivityContext
|
||||
{
|
||||
readonly TaskActivityContext innerContext;
|
||||
|
||||
internal WorkflowActivityContext(TaskActivityContext innerContext)
|
||||
{
|
||||
this.innerContext = innerContext ?? throw new ArgumentNullException(nameof(innerContext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the activity.
|
||||
/// </summary>
|
||||
public TaskName Name => this.innerContext.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique ID of the current workflow instance.
|
||||
/// </summary>
|
||||
public string InstanceId => this.innerContext.InstanceId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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 Microsoft.DurableTask;
|
||||
using Microsoft.DurableTask.Client;
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
// TODO: This will be replaced by the official Dapr Workflow management client.
|
||||
/// <summary>
|
||||
/// Defines client operations for managing Dapr Workflow instances.
|
||||
/// </summary>
|
||||
public sealed class WorkflowClient : IAsyncDisposable
|
||||
{
|
||||
readonly DurableTaskClient innerClient;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WorkflowClient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="innerClient">The Durable Task client used to communicate with the Dapr sidecar.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="innerClient"/> is <c>null</c>.</exception>
|
||||
public WorkflowClient(DurableTaskClient innerClient)
|
||||
{
|
||||
this.innerClient = innerClient ?? throw new ArgumentNullException(nameof(innerClient));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedules a new workflow instance for execution.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the orchestrator to schedule.</param>
|
||||
/// <param name="instanceId">
|
||||
/// The unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used.
|
||||
/// </param>
|
||||
/// <param name="startTime">
|
||||
/// The time when the orchestration instance should start executing. If not specified or if a date-time in the past
|
||||
/// is specified, the orchestration instance will be scheduled immediately.
|
||||
/// </param>
|
||||
/// <param name="input">
|
||||
/// The optional input to pass to the scheduled orchestration instance. This must be a serializable value.
|
||||
/// </param>
|
||||
public Task<string> ScheduleNewWorkflowAsync(
|
||||
string name,
|
||||
string? instanceId = null,
|
||||
object? input = null,
|
||||
DateTime? startTime = null)
|
||||
{
|
||||
StartOrchestrationOptions options = new(instanceId, startTime);
|
||||
return this.innerClient.ScheduleNewOrchestrationInstanceAsync(name, input, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches runtime metadata for the specified workflow instance.
|
||||
/// </summary>
|
||||
/// <param name="instanceId">The unique ID of the orchestration instance to fetch.</param>
|
||||
/// <param name="getInputsAndOutputs">
|
||||
/// Specify <c>true</c> to fetch the orchestration instance's inputs, outputs, and custom status, or <c>false</c> to
|
||||
/// omit them. Defaults to false.
|
||||
/// </param>
|
||||
public async Task<WorkflowMetadata> GetWorkflowMetadataAsync(string instanceId, bool getInputsAndOutputs = false)
|
||||
{
|
||||
OrchestrationMetadata? metadata = await this.innerClient.GetInstanceMetadataAsync(
|
||||
instanceId,
|
||||
getInputsAndOutputs);
|
||||
return new WorkflowMetadata(metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes any unmanaged resources associated with this client.
|
||||
/// </summary>
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
return ((IAsyncDisposable)this.innerClient).DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DurableTask;
|
||||
|
||||
/// <summary>
|
||||
/// Context object used by workflow implementations to perform actions such as scheduling activities, durable timers, waiting for
|
||||
/// external events, and for getting basic information about the current workflow instance.
|
||||
/// </summary>
|
||||
public class WorkflowContext
|
||||
{
|
||||
readonly TaskOrchestrationContext innerContext;
|
||||
|
||||
internal WorkflowContext(TaskOrchestrationContext innerContext)
|
||||
{
|
||||
this.innerContext = innerContext ?? throw new ArgumentNullException(nameof(innerContext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the current workflow.
|
||||
/// </summary>
|
||||
public TaskName Name => this.innerContext.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance ID of the current workflow.
|
||||
/// </summary>
|
||||
public string InstanceId => this.innerContext.InstanceId;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current workflow time in UTC.
|
||||
/// </summary>
|
||||
public DateTime CurrentUtcDateTime => this.innerContext.CurrentUtcDateTime;
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a custom status value to the current workflow.
|
||||
/// </summary>
|
||||
public void SetCustomStatus(object? customStatus) => this.innerContext.SetCustomStatus(customStatus);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a durable timer that expires after the specified delay.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="TaskOrchestrationContext.CreateTimer(TimeSpan, CancellationToken)"/>
|
||||
public Task CreateTimer(TimeSpan delay, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return this.innerContext.CreateTimer(delay, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for an event to be raised with name <paramref name="eventName"/> and returns the event data.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="TaskOrchestrationContext.WaitForExternalEvent{T}(string, TimeSpan)"/>
|
||||
public Task<T> WaitForExternalEventAsync<T>(string eventName, TimeSpan timeout)
|
||||
{
|
||||
return this.innerContext.WaitForExternalEvent<T>(eventName, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for an event to be raised with name <paramref name="eventName"/> and returns the event data.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="TaskOrchestrationContext.WaitForExternalEvent{T}(string, CancellationToken)"/>
|
||||
public Task<T> WaitForExternalEventAsync<T>(string eventName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return this.innerContext.WaitForExternalEvent<T>(eventName, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously invokes an activity by name and with the specified input value.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="TaskOrchestrationContext.CallActivityAsync{T}(TaskName, object?, TaskOptions?)"/>
|
||||
public Task<T> CallActivityAsync<T>(TaskName name, object? input = null, TaskOptions? options = null)
|
||||
{
|
||||
return this.innerContext.CallActivityAsync<T>(name, input, options);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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 Microsoft.DurableTask.Client;
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a snapshot of a workflow instance's current state, including metadata.
|
||||
/// </summary>
|
||||
public class WorkflowMetadata
|
||||
{
|
||||
internal WorkflowMetadata(OrchestrationMetadata? metadata)
|
||||
{
|
||||
this.Details = metadata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the requested workflow instance exists.
|
||||
/// </summary>
|
||||
public bool Exists => this.Details != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the requested workflow is in a running state.
|
||||
/// </summary>
|
||||
public bool IsWorkflowRunning => this.Details?.RuntimeStatus == OrchestrationRuntimeStatus.Running;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the detailed metadata for the requested workflow instance.
|
||||
/// This value will be <c>null</c> when <see cref="Exists" /> is <c>false</c>.
|
||||
/// </summary>
|
||||
public OrchestrationMetadata? Details { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DurableTask;
|
||||
|
||||
/// <summary>
|
||||
/// Defines runtime options for workflows.
|
||||
/// </summary>
|
||||
public sealed class WorkflowRuntimeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary to name and register a workflow.
|
||||
/// </summary>
|
||||
readonly Dictionary<string, Action<DurableTaskRegistry>> factories = new();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a workflow as a function that takes a specified input type and returns a specified output type.
|
||||
/// </summary>
|
||||
/// <param name="name">Workflow name</param>
|
||||
/// <param name="implementation">Function implementing the workflow definition</param>
|
||||
public void RegisterWorkflow<TInput, TOutput>(string name, Func<WorkflowContext, TInput, Task<TOutput>> implementation)
|
||||
{
|
||||
// Dapr workflows are implemented as specialized Durable Task orchestrations
|
||||
this.factories.Add(name, (DurableTaskRegistry registry) =>
|
||||
{
|
||||
registry.AddOrchestratorFunc<TInput, TOutput>(name, (innerContext, input) =>
|
||||
{
|
||||
WorkflowContext workflowContext = new(innerContext);
|
||||
return implementation(workflowContext, input);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a workflow activity as a function that takes a specified input type and returns a specified output type.
|
||||
/// </summary>
|
||||
/// <param name="name">Activity name</param>
|
||||
/// <param name="implementation">Activity implemetation</param>
|
||||
public void RegisterActivity<TInput, TOutput>(string name, Func<WorkflowActivityContext, TInput, Task<TOutput>> implementation)
|
||||
{
|
||||
// Dapr activities are implemented as specialized Durable Task activities
|
||||
this.factories.Add(name, (DurableTaskRegistry registry) =>
|
||||
{
|
||||
registry.AddActivityFunc<TInput, TOutput>(name, (innerContext, input) =>
|
||||
{
|
||||
WorkflowActivityContext activityContext = new(innerContext);
|
||||
return implementation(activityContext, input);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to add workflows and activities to the registry.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry we will add workflows and activities to</param>
|
||||
internal void AddWorkflowsAndActivitiesToRegistry(DurableTaskRegistry registry)
|
||||
{
|
||||
foreach (Action<DurableTaskRegistry> factory in this.factories.Values)
|
||||
{
|
||||
factory.Invoke(registry); // This adds workflows to the registry indirectly.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// Copyright 2022 The Dapr Authors
|
||||
// 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.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Workflow
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.DurableTask.Client;
|
||||
using Microsoft.DurableTask.Worker;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extension methods for using Dapr Workflow with dependency injection.
|
||||
/// </summary>
|
||||
public static class WorkflowServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds Dapr Workflow support to the service collection.
|
||||
/// </summary>
|
||||
/// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
|
||||
/// <param name="configure">A delegate used to configure actor options and register workflow functions.</param>
|
||||
public static IServiceCollection AddDaprWorkflow(
|
||||
this IServiceCollection serviceCollection,
|
||||
Action<WorkflowRuntimeOptions> configure)
|
||||
{
|
||||
if (serviceCollection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(serviceCollection));
|
||||
}
|
||||
|
||||
serviceCollection.TryAddSingleton<WorkflowRuntimeOptions>();
|
||||
serviceCollection.TryAddSingleton<WorkflowClient>();
|
||||
serviceCollection.AddDaprClient();
|
||||
|
||||
serviceCollection.AddDurableTaskClient(builder =>
|
||||
{
|
||||
builder.UseGrpc();
|
||||
builder.RegisterDirectly();
|
||||
});
|
||||
|
||||
serviceCollection.AddDurableTaskWorker(builder =>
|
||||
{
|
||||
WorkflowRuntimeOptions options = new();
|
||||
configure?.Invoke(options);
|
||||
|
||||
builder.UseGrpc();
|
||||
builder.AddTasks(registry => options.AddWorkflowsAndActivitiesToRegistry(registry));
|
||||
});
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue