diff --git a/examples/Actor/ActorClient/Program.cs b/examples/Actor/ActorClient/Program.cs index bae5d2ec2..f6ca26f53 100644 --- a/examples/Actor/ActorClient/Program.cs +++ b/examples/Actor/ActorClient/Program.cs @@ -11,6 +11,9 @@ // limitations under the License. // ------------------------------------------------------------------------ +using Dapr.Actors.Communication; +using IDemoActor; + namespace ActorClient { using System; @@ -18,7 +21,6 @@ namespace ActorClient using System.Threading.Tasks; using Dapr.Actors; using Dapr.Actors.Client; - using IDemoActorInterface; /// /// Actor Client class. @@ -43,7 +45,7 @@ public static async Task Main(string[] args) // Make strongly typed Actor calls with Remoting. // DemoActor is the type registered with Dapr runtime in the service. - var proxy = ActorProxy.Create(actorId, "DemoActor"); + var proxy = ActorProxy.Create(actorId, "DemoActor"); Console.WriteLine("Making call using actor proxy to save data."); await proxy.SaveData(data, TimeSpan.FromMinutes(10)); diff --git a/examples/Actor/DemoActor/BankService.cs b/examples/Actor/DemoActor/BankService.cs index 0a164183f..a24eadedb 100644 --- a/examples/Actor/DemoActor/BankService.cs +++ b/examples/Actor/DemoActor/BankService.cs @@ -11,9 +11,9 @@ // limitations under the License. // ------------------------------------------------------------------------ -using IDemoActorInterface; +using IDemoActor; -namespace DaprDemoActor +namespace DemoActor { public class BankService { diff --git a/examples/Actor/DemoActor/DemoActor.cs b/examples/Actor/DemoActor/DemoActor.cs index da780d517..b5ef53e93 100644 --- a/examples/Actor/DemoActor/DemoActor.cs +++ b/examples/Actor/DemoActor/DemoActor.cs @@ -11,14 +11,14 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace DaprDemoActor -{ - using System; - using System.Text.Json; - using System.Threading.Tasks; - using Dapr.Actors.Runtime; - using IDemoActorInterface; +using System; +using System.Text.Json; +using System.Threading.Tasks; +using Dapr.Actors.Runtime; +using IDemoActor; +namespace DemoActor +{ // The following example showcases a few features of Actors // // Every actor should inherit from the Actor type, and must implement one or more actor interfaces. @@ -27,7 +27,7 @@ namespace DaprDemoActor // For Actors to use Reminders, it must derive from IRemindable. // If you don't intend to use Reminder feature, you can skip implementing IRemindable and reminder // specific methods which are shown in the code below. - public class DemoActor : Actor, IDemoActor, IBankActor, IRemindable + public class DemoActor : Actor, IDemoActor.IDemoActor, IBankActor, IRemindable { private const string StateName = "my_data"; diff --git a/examples/Actor/DemoActor/Program.cs b/examples/Actor/DemoActor/Program.cs index a56681fdb..1d538b471 100644 --- a/examples/Actor/DemoActor/Program.cs +++ b/examples/Actor/DemoActor/Program.cs @@ -11,11 +11,11 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace DaprDemoActor -{ - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +namespace DemoActor +{ public class Program { public static void Main(string[] args) diff --git a/examples/Actor/DemoActor/Startup.cs b/examples/Actor/DemoActor/Startup.cs index da2b9e764..f1165e3c7 100644 --- a/examples/Actor/DemoActor/Startup.cs +++ b/examples/Actor/DemoActor/Startup.cs @@ -11,14 +11,14 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace DaprDemoActor -{ - using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +namespace DemoActor +{ public class Startup { public Startup(IConfiguration configuration) diff --git a/examples/Actor/IDemoActor/IBankActor.cs b/examples/Actor/IDemoActor/IBankActor.cs index 95ac23844..c495f027b 100644 --- a/examples/Actor/IDemoActor/IBankActor.cs +++ b/examples/Actor/IDemoActor/IBankActor.cs @@ -11,12 +11,12 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace IDemoActorInterface -{ - using System; - using System.Threading.Tasks; - using Dapr.Actors; +using System; +using System.Threading.Tasks; +using Dapr.Actors; +namespace IDemoActor +{ public interface IBankActor : IActor { Task GetAccountBalance(); diff --git a/examples/Actor/IDemoActor/IDemoActor.cs b/examples/Actor/IDemoActor/IDemoActor.cs index 25ce09370..6f2d32801 100644 --- a/examples/Actor/IDemoActor/IDemoActor.cs +++ b/examples/Actor/IDemoActor/IDemoActor.cs @@ -11,13 +11,12 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace IDemoActorInterface -{ - using System; - using System.Threading.Tasks; - using Dapr.Actors; - using Dapr.Actors.Runtime; +using System; +using System.Threading.Tasks; +using Dapr.Actors; +namespace IDemoActor +{ /// /// Interface for Actor method. /// diff --git a/examples/AspNetCore/ControllerSample/CustomTopicAttribute.cs b/examples/AspNetCore/ControllerSample/CustomTopicAttribute.cs index 96eb918fb..5c9996aea 100644 --- a/examples/AspNetCore/ControllerSample/CustomTopicAttribute.cs +++ b/examples/AspNetCore/ControllerSample/CustomTopicAttribute.cs @@ -11,6 +11,8 @@ // limitations under the License. // ------------------------------------------------------------------------ +using Dapr.AspNetCore; + namespace ControllerSample { using System; diff --git a/examples/AspNetCore/ControllerSample/Startup.cs b/examples/AspNetCore/ControllerSample/Startup.cs index 11b81d8b3..64cfba512 100644 --- a/examples/AspNetCore/ControllerSample/Startup.cs +++ b/examples/AspNetCore/ControllerSample/Startup.cs @@ -11,6 +11,8 @@ // limitations under the License. // ------------------------------------------------------------------------ +using Dapr.AspNetCore; + namespace ControllerSample { using Microsoft.AspNetCore.Builder; diff --git a/examples/AspNetCore/GrpcServiceSample/Services/BankingService.cs b/examples/AspNetCore/GrpcServiceSample/Services/BankingService.cs index 56b80cad6..9518fd610 100644 --- a/examples/AspNetCore/GrpcServiceSample/Services/BankingService.cs +++ b/examples/AspNetCore/GrpcServiceSample/Services/BankingService.cs @@ -22,7 +22,7 @@ using GrpcServiceSample.Generated; using Microsoft.Extensions.Logging; -namespace GrpcServiceSample +namespace GrpcServiceSample.Services { /// /// BankAccount gRPC service diff --git a/examples/AspNetCore/GrpcServiceSample/Startup.cs b/examples/AspNetCore/GrpcServiceSample/Startup.cs index 752d62448..4aa5ac7d3 100644 --- a/examples/AspNetCore/GrpcServiceSample/Startup.cs +++ b/examples/AspNetCore/GrpcServiceSample/Startup.cs @@ -11,6 +11,8 @@ // limitations under the License. // ------------------------------------------------------------------------ +using Dapr.AspNetCore; +using GrpcServiceSample.Services; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; diff --git a/examples/Client/ConfigurationApi/Startup.cs b/examples/Client/ConfigurationApi/Startup.cs index 62a77ac49..db5b921c9 100644 --- a/examples/Client/ConfigurationApi/Startup.cs +++ b/examples/Client/ConfigurationApi/Startup.cs @@ -1,4 +1,5 @@ using System; +using Dapr.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; diff --git a/examples/Client/Cryptography/Program.cs b/examples/Client/Cryptography/Program.cs index 74e3c7f48..da81bef8f 100644 --- a/examples/Client/Cryptography/Program.cs +++ b/examples/Client/Cryptography/Program.cs @@ -11,10 +11,9 @@ // limitations under the License. // ------------------------------------------------------------------------ -using Cryptography; using Cryptography.Examples; -namespace Samples.Client +namespace Cryptography { class Program { diff --git a/examples/Client/DistributedLock/Startup.cs b/examples/Client/DistributedLock/Startup.cs index 0309af0f5..9f40e4752 100644 --- a/examples/Client/DistributedLock/Startup.cs +++ b/examples/Client/DistributedLock/Startup.cs @@ -1,4 +1,5 @@ -using DistributedLock.Services; +using Dapr.AspNetCore; +using DistributedLock.Services; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; diff --git a/examples/Workflow/WorkflowConsoleApp/Activities/ProcessPaymentActivity.cs b/examples/Workflow/WorkflowConsoleApp/Activities/ProcessPaymentActivity.cs index dc4cc531b..1ddb51bbf 100644 --- a/examples/Workflow/WorkflowConsoleApp/Activities/ProcessPaymentActivity.cs +++ b/examples/Workflow/WorkflowConsoleApp/Activities/ProcessPaymentActivity.cs @@ -1,7 +1,6 @@ using Dapr.Client; using Dapr.Workflow; using Microsoft.Extensions.Logging; -using WorkflowConsoleApp.Models; namespace WorkflowConsoleApp.Activities { diff --git a/examples/Workflow/WorkflowConsoleApp/Activities/RequestApprovalActivity.cs b/examples/Workflow/WorkflowConsoleApp/Activities/RequestApprovalActivity.cs index af0b1fa13..d40078fc8 100644 --- a/examples/Workflow/WorkflowConsoleApp/Activities/RequestApprovalActivity.cs +++ b/examples/Workflow/WorkflowConsoleApp/Activities/RequestApprovalActivity.cs @@ -1,6 +1,5 @@ using Dapr.Workflow; using Microsoft.Extensions.Logging; -using WorkflowConsoleApp.Models; namespace WorkflowConsoleApp.Activities { diff --git a/examples/Workflow/WorkflowConsoleApp/Activities/ReserveInventoryActivity.cs b/examples/Workflow/WorkflowConsoleApp/Activities/ReserveInventoryActivity.cs index fc6c48921..cdae1c6ed 100644 --- a/examples/Workflow/WorkflowConsoleApp/Activities/ReserveInventoryActivity.cs +++ b/examples/Workflow/WorkflowConsoleApp/Activities/ReserveInventoryActivity.cs @@ -1,7 +1,6 @@ using Dapr.Client; using Dapr.Workflow; using Microsoft.Extensions.Logging; -using WorkflowConsoleApp.Models; namespace WorkflowConsoleApp.Activities { diff --git a/examples/Workflow/WorkflowConsoleApp/Activities/UpdateInventoryActivity.cs b/examples/Workflow/WorkflowConsoleApp/Activities/UpdateInventoryActivity.cs index 947dab6cb..c035aadde 100644 --- a/examples/Workflow/WorkflowConsoleApp/Activities/UpdateInventoryActivity.cs +++ b/examples/Workflow/WorkflowConsoleApp/Activities/UpdateInventoryActivity.cs @@ -1,6 +1,5 @@ using Dapr.Client; using Dapr.Workflow; -using WorkflowConsoleApp.Models; using Microsoft.Extensions.Logging; namespace WorkflowConsoleApp.Activities diff --git a/examples/Workflow/WorkflowConsoleApp/Models.cs b/examples/Workflow/WorkflowConsoleApp/Models.cs index 6c9583d84..7892c7525 100644 --- a/examples/Workflow/WorkflowConsoleApp/Models.cs +++ b/examples/Workflow/WorkflowConsoleApp/Models.cs @@ -1,4 +1,4 @@ -namespace WorkflowConsoleApp.Models +namespace WorkflowConsoleApp { public record OrderPayload(string Name, double TotalCost, int Quantity = 1); public record InventoryRequest(string RequestId, string ItemName, int Quantity); diff --git a/examples/Workflow/WorkflowConsoleApp/Program.cs b/examples/Workflow/WorkflowConsoleApp/Program.cs index 2b8213887..26d34615d 100644 --- a/examples/Workflow/WorkflowConsoleApp/Program.cs +++ b/examples/Workflow/WorkflowConsoleApp/Program.cs @@ -1,10 +1,10 @@ using Dapr.Client; using Dapr.Workflow; using WorkflowConsoleApp.Activities; -using WorkflowConsoleApp.Models; using WorkflowConsoleApp.Workflows; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.DependencyInjection; +using WorkflowConsoleApp; const string StoreName = "statestore"; diff --git a/examples/Workflow/WorkflowConsoleApp/Workflows/OrderProcessingWorkflow.cs b/examples/Workflow/WorkflowConsoleApp/Workflows/OrderProcessingWorkflow.cs index bd2a710b6..3b8af5951 100644 --- a/examples/Workflow/WorkflowConsoleApp/Workflows/OrderProcessingWorkflow.cs +++ b/examples/Workflow/WorkflowConsoleApp/Workflows/OrderProcessingWorkflow.cs @@ -1,6 +1,5 @@ using Dapr.Workflow; using WorkflowConsoleApp.Activities; -using WorkflowConsoleApp.Models; namespace WorkflowConsoleApp.Workflows { diff --git a/examples/Workflow/WorkflowUnitTest/OrderProcessingTests.cs b/examples/Workflow/WorkflowUnitTest/OrderProcessingTests.cs index ac53c4081..e38a0c940 100644 --- a/examples/Workflow/WorkflowUnitTest/OrderProcessingTests.cs +++ b/examples/Workflow/WorkflowUnitTest/OrderProcessingTests.cs @@ -1,8 +1,8 @@ using System.Threading.Tasks; using Dapr.Workflow; using Moq; +using WorkflowConsoleApp; using WorkflowConsoleApp.Activities; -using WorkflowConsoleApp.Models; using WorkflowConsoleApp.Workflows; using Xunit; diff --git a/src/Dapr.Client/DaprClient.cs b/src/Dapr.Client/DaprClient.cs index 4f89d8668..94a43b759 100644 --- a/src/Dapr.Client/DaprClient.cs +++ b/src/Dapr.Client/DaprClient.cs @@ -1296,192 +1296,7 @@ public abstract Task Unlock( string resourceId, string lockOwner, CancellationToken cancellationToken = default); - - /// - /// Attempt to start the given workflow with response indicating success. - /// - /// The component to interface with. - /// Name of the workflow to run. - /// Identifier of the specific run. - /// The JSON-serializeable input for the given workflow. - /// The list of options that are potentially needed to start a workflow. - /// A that can be used to cancel the operation. - /// A containing a - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task StartWorkflowAsync( - string workflowComponent, - string workflowName, - string instanceId = null, - object input = null, - IReadOnlyDictionary workflowOptions = default, - CancellationToken cancellationToken = default); - - /// - /// Waits for a workflow to start running and returns a object that contains metadata - /// about the started workflow. - /// - /// - /// - /// A "started" workflow instance is any instance not in the state. - /// - /// This method will return a completed task if the workflow has already started running or has already completed. - /// - /// - /// The unique ID of the workflow instance to wait for. - /// The component to interface with. - /// A that can be used to cancel the wait operation. - /// - /// Returns a record that describes the workflow instance and its execution status. - /// - /// - /// Thrown if is canceled before the workflow starts running. - /// - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public virtual async Task WaitForWorkflowStartAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - while (true) - { - var response = await this.GetWorkflowAsync(instanceId, workflowComponent, cancellationToken); - if (response.RuntimeStatus != WorkflowRuntimeStatus.Pending) - { - return response; - } - - await Task.Delay(TimeSpan.FromMilliseconds(500), cancellationToken); - } - } - - /// - /// Waits for a workflow to complete and returns a - /// object that contains metadata about the started instance. - /// - /// - /// - /// A "completed" workflow instance is any instance in one of the terminal states. For example, the - /// , , or - /// states. - /// - /// Workflows are long-running and could take hours, days, or months before completing. - /// Workflows can also be eternal, in which case they'll never complete unless terminated. - /// In such cases, this call may block indefinitely, so care must be taken to ensure appropriate timeouts are - /// enforced using the parameter. - /// - /// If a workflow instance is already complete when this method is called, the method will return immediately. - /// - /// - /// - /// Returns a record that describes the workflow instance and its execution status. - /// - /// - /// Thrown if is canceled before the workflow completes. - /// - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public virtual async Task WaitForWorkflowCompletionAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - while (true) - { - var response = await this.GetWorkflowAsync(instanceId, workflowComponent, cancellationToken); - if (response.RuntimeStatus == WorkflowRuntimeStatus.Completed || - response.RuntimeStatus == WorkflowRuntimeStatus.Failed || - response.RuntimeStatus == WorkflowRuntimeStatus.Terminated) - { - return response; - } - - await Task.Delay(TimeSpan.FromMilliseconds(500), cancellationToken); - } - } - - /// - /// Attempt to get information about the given workflow. - /// - /// The unique ID of the target workflow instance. - /// The component to interface with. - /// A that can be used to cancel the operation. - /// A containing a - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task GetWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default); - - /// - /// Attempt to get terminate the given workflow. - /// - /// The unique ID of the target workflow instance. - /// The component to interface with. - /// A that can be used to cancel the operation. - /// A that will complete when the terminate operation has been scheduled. If the wrapped value is true the operation suceeded. - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task TerminateWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default); - - /// - /// Attempt to raise an event the given workflow with response indicating success. - /// - /// Identifier of the specific run. - /// The component to interface with. - /// Name of the event to raise. - /// The JSON-serializable event payload to include in the raised event. - /// A that can be used to cancel the operation. - /// A that will complete when the raise event operation has been scheduled. If the wrapped value is true the operation suceeded. - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task RaiseWorkflowEventAsync( - string instanceId, - string workflowComponent, - string eventName, - object eventData = null, - CancellationToken cancellationToken = default); - - - /// - /// Pauses the specified workflow instance. - /// - /// The unique ID of the target workflow instance. - /// The component to interface with. - /// A that can be used to cancel the operation. - /// A that will complete when the pause operation has been scheduled. If the wrapped value is true the operation suceeded. - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task PauseWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default); - - - /// - /// Resumes a paused workflow instance. - /// - /// The unique ID of the target workflow instance. - /// The component to interface with. - /// A that can be used to cancel the operation. - /// A that will complete when the resume operation has been scheduled. If the wrapped value is true the operation suceeded. - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task ResumeWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default); - - /// - /// Delete all state associated with the specified workflow instance. The workflow must be in a non-running state to be purged. - /// - /// The unique ID of the target workflow instance. - /// The component to interface with. - /// A that can be used to cancel the operation. - /// A that will complete when the purge operation has been scheduled. If the wrapped value is true the operation suceeded. - [Obsolete("This API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")] - public abstract Task PurgeWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default); - + /// public void Dispose() { diff --git a/src/Dapr.Client/DaprClientGrpc.cs b/src/Dapr.Client/DaprClientGrpc.cs index af245afc3..73ab1ec67 100644 --- a/src/Dapr.Client/DaprClientGrpc.cs +++ b/src/Dapr.Client/DaprClientGrpc.cs @@ -2036,287 +2036,6 @@ public async override Task Unlock( #endregion - - #region Workflow API - /// - [Obsolete] - public async override Task StartWorkflowAsync( - string workflowComponent, - string workflowName, - string instanceId = null, - object input = null, - IReadOnlyDictionary workflowOptions = default, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowName, nameof(workflowName)); - ArgumentVerifier.ThrowIfNull(input, nameof(input)); - - // Serialize json data. Converts input object to bytes and then bytestring inside the request. - byte[] jsonUtf8Bytes = null; - if (input is not null) - { - jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(input); - } - - var request = new Autogenerated.StartWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent, - WorkflowName = workflowName, - Input = jsonUtf8Bytes is not null ? ByteString.CopyFrom(jsonUtf8Bytes) : null, - }; - - if (workflowOptions?.Count > 0) - { - foreach (var item in workflowOptions) - { - request.Options[item.Key] = item.Value; - } - } - - try - { - var options = CreateCallOptions(headers: null, cancellationToken); - var response = await client.StartWorkflowAlpha1Async(request, options); - return new StartWorkflowResponse(response.InstanceId); - - } - catch (RpcException ex) - { - throw new DaprException("Start Workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - } - - /// - [Obsolete] - public async override Task GetWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - - var request = new Autogenerated.GetWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent - }; - - try - { - var options = CreateCallOptions(headers: null, cancellationToken); - var response = await client.GetWorkflowAlpha1Async(request, options); - if (response == null) - { - throw new DaprException("Get workflow operation failed: the Dapr endpoint returned an empty result."); - } - - response.CreatedAt ??= new Timestamp(); - response.LastUpdatedAt ??= response.CreatedAt; - - return new GetWorkflowResponse - { - InstanceId = response.InstanceId, - WorkflowName = response.WorkflowName, - WorkflowComponentName = workflowComponent, - CreatedAt = response.CreatedAt.ToDateTime(), - LastUpdatedAt = response.LastUpdatedAt.ToDateTime(), - RuntimeStatus = GetWorkflowRuntimeStatus(response.RuntimeStatus), - Properties = response.Properties, - FailureDetails = GetWorkflowFailureDetails(response, workflowComponent), - }; - } - catch (RpcException ex) - { - throw new DaprException("Get workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - } - - private static WorkflowRuntimeStatus GetWorkflowRuntimeStatus(string runtimeStatus) - { - if (!System.Enum.TryParse(runtimeStatus, true /* ignoreCase */, out WorkflowRuntimeStatus status)) - { - status = WorkflowRuntimeStatus.Unknown; - } - - return status; - } - - private static WorkflowFailureDetails GetWorkflowFailureDetails(Autogenerated.GetWorkflowResponse response, string componentName) - { - // FUTURE: Make this part of the protobuf contract instead of getting it from properties - // NOTE: The use of | instead of || is intentional. We want to get all the values. - if (response.Properties.TryGetValue($"{componentName}.workflow.failure.error_type", out string errorType) | - response.Properties.TryGetValue($"{componentName}.workflow.failure.error_message", out string errorMessage) | - response.Properties.TryGetValue($"{componentName}.workflow.failure.stack_trace", out string stackTrace)) - { - return new WorkflowFailureDetails(errorMessage, errorType, stackTrace); - } - - return null; - } - - /// - [Obsolete] - public async override Task TerminateWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - - var request = new Autogenerated.TerminateWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent - }; - - var options = CreateCallOptions(headers: null, cancellationToken); - - try - { - await client.TerminateWorkflowAlpha1Async(request, options); - } - catch (RpcException ex) - { - throw new DaprException("Terminate workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - - } - - /// - [Obsolete] - public async override Task RaiseWorkflowEventAsync( - string instanceId, - string workflowComponent, - string eventName, - Object eventData, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - ArgumentVerifier.ThrowIfNullOrEmpty(eventName, nameof(eventName)); - - byte[] jsonUtf8Bytes = new byte[0]; - // Serialize json data. Converts eventData object to bytes and then bytestring inside the request. - if (eventData != null) - { - jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(eventData); - } - - var request = new Autogenerated.RaiseEventWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent, - EventName = eventName, - EventData = ByteString.CopyFrom(jsonUtf8Bytes), - }; - - var options = CreateCallOptions(headers: null, cancellationToken); - - try - { - await client.RaiseEventWorkflowAlpha1Async(request, options); - } - catch (RpcException ex) - { - throw new DaprException("Start Workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - } - - - /// - [Obsolete] - public async override Task PauseWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - - var request = new Autogenerated.PauseWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent - }; - - var options = CreateCallOptions(headers: null, cancellationToken); - - try - { - await client.PauseWorkflowAlpha1Async(request, options); - } - catch (RpcException ex) - { - throw new DaprException("Pause workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - } - - /// - [Obsolete] - public async override Task ResumeWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - - var request = new Autogenerated.ResumeWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent - }; - - var options = CreateCallOptions(headers: null, cancellationToken); - - try - { - await client.ResumeWorkflowAlpha1Async(request, options); - } - catch (RpcException ex) - { - throw new DaprException("Resume workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - - } - - /// - [Obsolete] - public async override Task PurgeWorkflowAsync( - string instanceId, - string workflowComponent, - CancellationToken cancellationToken = default) - { - ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); - ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); - - var request = new Autogenerated.PurgeWorkflowRequest() - { - InstanceId = instanceId, - WorkflowComponent = workflowComponent - }; - - var options = CreateCallOptions(headers: null, cancellationToken); - - try - { - await client.PurgeWorkflowAlpha1Async(request, options); - } - catch (RpcException ex) - { - throw new DaprException("Purge workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); - } - - } - #endregion - - #region Dapr Sidecar Methods /// diff --git a/src/Dapr.Client/GetWorkflowResponse.cs b/src/Dapr.Client/GetWorkflowResponse.cs deleted file mode 100644 index 11fc253ac..000000000 --- a/src/Dapr.Client/GetWorkflowResponse.cs +++ /dev/null @@ -1,100 +0,0 @@ -// ------------------------------------------------------------------------ -// Copyright 2021 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.Collections.Generic; -using System.Text.Json; - -namespace Dapr.Client -{ - /// - /// The response type for the API. - /// - public class GetWorkflowResponse - { - /// - /// Gets the instance ID of the workflow. - /// - public string InstanceId { get; init; } - - /// - /// Gets the name of the workflow. - /// - public string WorkflowName { get; init; } - - /// - /// Gets the name of the workflow component. - /// - public string WorkflowComponentName { get; init; } - - /// - /// Gets the time at which the workflow was created. - /// - public DateTime CreatedAt { get; init; } - - /// - /// Gets the time at which the workflow was last updated. - /// - public DateTime LastUpdatedAt { get; init; } - - /// - /// Gets the runtime status of the workflow. - /// - public WorkflowRuntimeStatus RuntimeStatus { get; init; } - - /// - /// Gets the component-specific workflow properties. - /// - public IReadOnlyDictionary Properties { get; init; } - - /// - /// Gets the details associated with the workflow failure, if any. - /// - public WorkflowFailureDetails FailureDetails { get; init; } - - /// - /// Deserializes the workflow input into using . - /// - /// The type to deserialize the workflow input into. - /// Options to control the behavior during parsing. - /// Returns the input as , or returns a default value if the workflow doesn't have an input. - public T ReadInputAs(JsonSerializerOptions options = null) - { - // FUTURE: Make this part of the protobuf contract instead of properties - string defaultInputKey = $"{this.WorkflowComponentName}.workflow.input"; - if (!this.Properties.TryGetValue(defaultInputKey, out string serializedInput)) - { - return default; - } - - return JsonSerializer.Deserialize(serializedInput, options); - } - - /// - /// Deserializes the workflow output into using . - /// - /// The type to deserialize the workflow output into. - /// Options to control the behavior during parsing. - /// Returns the output as , or returns a default value if the workflow doesn't have an output. - public T ReadOutputAs(JsonSerializerOptions options = null) - { - // FUTURE: Make this part of the protobuf contract instead of properties - string defaultOutputKey = $"{this.WorkflowComponentName}.workflow.output"; - if (!this.Properties.TryGetValue(defaultOutputKey, out string serializedOutput)) - { - return default; - } - - return JsonSerializer.Deserialize(serializedOutput, options); - } - } -} diff --git a/src/Dapr.Client/WorkflowFailureDetails.cs b/src/Dapr.Client/WorkflowFailureDetails.cs deleted file mode 100644 index a61754ff1..000000000 --- a/src/Dapr.Client/WorkflowFailureDetails.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ------------------------------------------------------------------------ -// Copyright 2021 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.Client -{ - /// - /// Represents workflow failure details. - /// - /// A summary description of the failure, which is typically an exception message. - /// The error type, which is defined by the workflow component implementation. - /// The stack trace of the failure. - public record WorkflowFailureDetails( - string ErrorMessage, - string ErrorType, - string StackTrace = null) - { - /// - /// Creates a user-friendly string representation of the failure information. - /// - public override string ToString() - { - return $"{this.ErrorType}: {this.ErrorMessage}"; - } - } -} diff --git a/src/Dapr.Client/WorkflowRuntimeStatus.cs b/src/Dapr.Workflow/WorkflowRuntimeStatus.cs similarity index 98% rename from src/Dapr.Client/WorkflowRuntimeStatus.cs rename to src/Dapr.Workflow/WorkflowRuntimeStatus.cs index dc652630e..24024cd63 100644 --- a/src/Dapr.Client/WorkflowRuntimeStatus.cs +++ b/src/Dapr.Workflow/WorkflowRuntimeStatus.cs @@ -11,7 +11,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace Dapr.Client +namespace Dapr.Workflow { /// /// Enum describing the runtime status of a workflow. diff --git a/test/Dapr.E2E.Test/Workflows/WorkflowTest.cs b/test/Dapr.E2E.Test/Workflows/WorkflowTest.cs index d95929ca3..cfcbc4bd8 100644 --- a/test/Dapr.E2E.Test/Workflows/WorkflowTest.cs +++ b/test/Dapr.E2E.Test/Workflows/WorkflowTest.cs @@ -19,7 +19,7 @@ using FluentAssertions; using Xunit; using System.Linq; -using System.Diagnostics; +using Dapr.Workflow; namespace Dapr.E2E.Test { @@ -79,94 +79,5 @@ public async Task TestWorkflowLogging() Assert.True(false, "The logs were not able to found within the timeout"); } } - [Fact] - public async Task TestWorkflows() - { - var instanceId = "testInstanceId"; - var instanceId2 = "EventRaiseId"; - var workflowComponent = "dapr"; - var workflowName = "PlaceOrder"; - object input = "paperclips"; - Dictionary workflowOptions = new Dictionary(); - workflowOptions.Add("task_queue", "testQueue"); - - using var daprClient = new DaprClientBuilder().UseGrpcEndpoint(this.GrpcEndpoint).UseHttpEndpoint(this.HttpEndpoint).Build(); - var health = await daprClient.CheckHealthAsync(); - health.Should().Be(true, "DaprClient is not healthy"); - - // START WORKFLOW TEST - var startResponse = await daprClient.StartWorkflowAsync( - instanceId: instanceId, - workflowComponent: workflowComponent, - workflowName: workflowName, - input: input, - workflowOptions: workflowOptions); - - startResponse.InstanceId.Should().Be("testInstanceId", $"Instance ID {startResponse.InstanceId} was not correct"); - - // GET INFO TEST - var getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - getResponse.InstanceId.Should().Be("testInstanceId"); - getResponse.RuntimeStatus.Should().Be(WorkflowRuntimeStatus.Running, $"Instance ID {getResponse.RuntimeStatus} was not correct"); - - // PAUSE TEST: - await daprClient.PauseWorkflowAsync(instanceId, workflowComponent); - getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - getResponse.RuntimeStatus.Should().Be(WorkflowRuntimeStatus.Suspended, $"Instance ID {getResponse.RuntimeStatus} was not correct"); - - // RESUME TEST: - await daprClient.ResumeWorkflowAsync(instanceId, workflowComponent); - getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - getResponse.RuntimeStatus.Should().Be(WorkflowRuntimeStatus.Running, $"Instance ID {getResponse.RuntimeStatus} was not correct"); - - // RAISE EVENT TEST - await daprClient.RaiseWorkflowEventAsync(instanceId, workflowComponent, "ChangePurchaseItem", "computers"); - getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - - // TERMINATE TEST: - await daprClient.TerminateWorkflowAsync(instanceId, workflowComponent); - getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - getResponse.RuntimeStatus.Should().Be(WorkflowRuntimeStatus.Terminated, $"Instance ID {getResponse.RuntimeStatus} was not correct"); - - // PURGE TEST - await daprClient.PurgeWorkflowAsync(instanceId, workflowComponent); - - try - { - getResponse = await daprClient.GetWorkflowAsync(instanceId, workflowComponent); - Assert.True(false, "The GetWorkflowAsync call should have failed since the instance was purged"); - } - catch (DaprException ex) - { - ex.InnerException.Message.Should().Contain("no such instance exists", $"Instance {instanceId} was not correctly purged"); - } - - // Start another workflow for event raising purposes - startResponse = await daprClient.StartWorkflowAsync( - instanceId: instanceId2, - workflowComponent: workflowComponent, - workflowName: workflowName, - input: input, - workflowOptions: workflowOptions); - - // PARALLEL RAISE EVENT TEST - var event1 = daprClient.RaiseWorkflowEventAsync(instanceId2, workflowComponent, "ChangePurchaseItem", "computers"); - var event2 = daprClient.RaiseWorkflowEventAsync(instanceId2, workflowComponent, "ChangePurchaseItem", "computers"); - var event3 = daprClient.RaiseWorkflowEventAsync(instanceId2, workflowComponent, "ChangePurchaseItem", "computers"); - var event4 = daprClient.RaiseWorkflowEventAsync(instanceId2, workflowComponent, "ChangePurchaseItem", "computers"); - var event5 = daprClient.RaiseWorkflowEventAsync(instanceId2, workflowComponent, "ChangePurchaseItem", "computers"); - - var externalEvents = Task.WhenAll(event1, event2, event3, event4, event5); - var winner = await Task.WhenAny(externalEvents, Task.Delay(TimeSpan.FromSeconds(30))); - externalEvents.IsCompletedSuccessfully.Should().BeTrue($"Unsuccessful at raising events. Status of events: {externalEvents.IsCompletedSuccessfully}"); - - // Wait up to 30 seconds for the workflow to complete and check the output - using var cts = new CancellationTokenSource(delay: TimeSpan.FromSeconds(30)); - getResponse = await daprClient.WaitForWorkflowCompletionAsync(instanceId2, workflowComponent, cts.Token); - var outputString = getResponse.Properties["dapr.workflow.output"]; - outputString.Should().Be("\"computers\"", $"Purchased item {outputString} was not correct"); - var deserializedOutput = getResponse.ReadOutputAs(); - deserializedOutput.Should().Be("computers", $"Deserialized output '{deserializedOutput}' was not expected"); - } } }