mirror of https://github.com/dapr/dotnet-sdk.git
				
				
				
			Merge branch 'remove-workflow-methods' into remote-workflow-methods-4
# Conflicts: # test/Dapr.E2E.Test/Workflows/WorkflowTest.cs
This commit is contained in:
		
						commit
						8948152a87
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Actor Client class.
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +45,7 @@ namespace ActorClient
 | 
			
		|||
 | 
			
		||||
            // Make strongly typed Actor calls with Remoting.
 | 
			
		||||
            // DemoActor is the type registered with Dapr runtime in the service.
 | 
			
		||||
            var proxy = ActorProxy.Create<IDemoActor>(actorId, "DemoActor");
 | 
			
		||||
            var proxy = ActorProxy.Create<IDemoActor.IDemoActor>(actorId, "DemoActor");
 | 
			
		||||
 | 
			
		||||
            Console.WriteLine("Making call using actor proxy to save data.");
 | 
			
		||||
            await proxy.SaveData(data, TimeSpan.FromMinutes(10));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,9 +11,9 @@
 | 
			
		|||
// limitations under the License.
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
using IDemoActorInterface;
 | 
			
		||||
using IDemoActor;
 | 
			
		||||
 | 
			
		||||
namespace DaprDemoActor
 | 
			
		||||
namespace DemoActor
 | 
			
		||||
{
 | 
			
		||||
    public class BankService
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<AccountBalance> GetAccountBalance();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Interface for Actor method.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,8 @@
 | 
			
		|||
// limitations under the License.
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
using Dapr.AspNetCore;
 | 
			
		||||
 | 
			
		||||
namespace ControllerSample
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,8 @@
 | 
			
		|||
// limitations under the License.
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
using Dapr.AspNetCore;
 | 
			
		||||
 | 
			
		||||
namespace ControllerSample
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ using Grpc.Core;
 | 
			
		|||
using GrpcServiceSample.Generated;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace GrpcServiceSample
 | 
			
		||||
namespace GrpcServiceSample.Services
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// BankAccount gRPC service
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Dapr.AspNetCore;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,10 +11,9 @@
 | 
			
		|||
// limitations under the License.
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
using Cryptography;
 | 
			
		||||
using Cryptography.Examples;
 | 
			
		||||
 | 
			
		||||
namespace Samples.Client
 | 
			
		||||
namespace Cryptography
 | 
			
		||||
{
 | 
			
		||||
    class Program
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
using Dapr.Client;
 | 
			
		||||
using Dapr.Workflow;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using WorkflowConsoleApp.Models;
 | 
			
		||||
 | 
			
		||||
namespace WorkflowConsoleApp.Activities
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
using Dapr.Workflow;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using WorkflowConsoleApp.Models;
 | 
			
		||||
 | 
			
		||||
namespace WorkflowConsoleApp.Activities
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
using Dapr.Client;
 | 
			
		||||
using Dapr.Workflow;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using WorkflowConsoleApp.Models;
 | 
			
		||||
 | 
			
		||||
namespace WorkflowConsoleApp.Activities
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
using Dapr.Client;
 | 
			
		||||
using Dapr.Workflow;
 | 
			
		||||
using WorkflowConsoleApp.Models;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace WorkflowConsoleApp.Activities
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
using Dapr.Workflow;
 | 
			
		||||
using WorkflowConsoleApp.Activities;
 | 
			
		||||
using WorkflowConsoleApp.Models;
 | 
			
		||||
 | 
			
		||||
namespace WorkflowConsoleApp.Workflows
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1296,192 +1296,7 @@ namespace Dapr.Client
 | 
			
		|||
            string resourceId,
 | 
			
		||||
            string lockOwner,
 | 
			
		||||
            CancellationToken cancellationToken = default);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Attempt to start the given workflow with response indicating success.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="workflowName">Name of the workflow to run.</param>
 | 
			
		||||
        /// <param name="instanceId">Identifier of the specific run.</param>
 | 
			
		||||
        /// <param name="input">The JSON-serializeable input for the given workflow.</param>
 | 
			
		||||
        /// <param name="workflowOptions">The list of options that are potentially needed to start a workflow.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task"/> containing a <see cref="StartWorkflowResponse"/></returns>
 | 
			
		||||
        [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<StartWorkflowResponse> StartWorkflowAsync(
 | 
			
		||||
            string workflowComponent,
 | 
			
		||||
            string workflowName,
 | 
			
		||||
            string instanceId = null,
 | 
			
		||||
            object input = null,
 | 
			
		||||
            IReadOnlyDictionary<string, string> workflowOptions = default,
 | 
			
		||||
            CancellationToken cancellationToken = default);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Waits for a workflow to start running and returns a <see cref="GetWorkflowResponse"/> object that contains metadata
 | 
			
		||||
        /// about the started workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// <para>
 | 
			
		||||
        /// A "started" workflow instance is any instance not in the <see cref="WorkflowRuntimeStatus.Pending"/> state.
 | 
			
		||||
        /// </para><para>
 | 
			
		||||
        /// This method will return a completed task if the workflow has already started running or has already completed.
 | 
			
		||||
        /// </para>
 | 
			
		||||
        /// </remarks>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the workflow instance to wait for.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the wait operation.</param>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// Returns a <see cref="GetWorkflowResponse"/> record that describes the workflow instance and its execution status.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        /// <exception cref="OperationCanceledException">
 | 
			
		||||
        /// Thrown if <paramref name="cancellationToken"/> is canceled before the workflow starts running.
 | 
			
		||||
        /// </exception>
 | 
			
		||||
        [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<GetWorkflowResponse> 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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Waits for a workflow to complete and returns a <see cref="GetWorkflowResponse"/>
 | 
			
		||||
        /// object that contains metadata about the started instance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// <para>
 | 
			
		||||
        /// A "completed" workflow instance is any instance in one of the terminal states. For example, the
 | 
			
		||||
        /// <see cref="WorkflowRuntimeStatus.Completed"/>, <see cref="WorkflowRuntimeStatus.Failed"/>, or
 | 
			
		||||
        /// <see cref="WorkflowRuntimeStatus.Terminated"/> states.
 | 
			
		||||
        /// </para><para>
 | 
			
		||||
        /// 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 <paramref name="cancellationToken"/> parameter.
 | 
			
		||||
        /// </para><para>
 | 
			
		||||
        /// If a workflow instance is already complete when this method is called, the method will return immediately.
 | 
			
		||||
        /// </para>
 | 
			
		||||
        /// </remarks>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// Returns a <see cref="GetWorkflowResponse"/> record that describes the workflow instance and its execution status.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        /// <exception cref="OperationCanceledException">
 | 
			
		||||
        /// Thrown if <paramref name="cancellationToken"/> is canceled before the workflow completes.
 | 
			
		||||
        /// </exception>
 | 
			
		||||
        [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<GetWorkflowResponse> 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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Attempt to get information about the given workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the target workflow instance.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task"/> containing a <see cref="GetWorkflowResponse"/></returns>
 | 
			
		||||
        [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<GetWorkflowResponse> GetWorkflowAsync(
 | 
			
		||||
            string instanceId,
 | 
			
		||||
            string workflowComponent,
 | 
			
		||||
            CancellationToken cancellationToken = default);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Attempt to get terminate the given workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the target workflow instance.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task" /> that will complete when the terminate operation has been scheduled. If the wrapped value is true the operation suceeded.</returns>
 | 
			
		||||
        [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);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Attempt to raise an event the given workflow with response indicating success.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">Identifier of the specific run.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="eventName">Name of the event to raise.</param>
 | 
			
		||||
        /// <param name="eventData">The JSON-serializable event payload to include in the raised event.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task" /> that will complete when the raise event operation has been scheduled. If the wrapped value is true the operation suceeded.</returns>
 | 
			
		||||
        [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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Pauses the specified workflow instance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the target workflow instance.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task" /> that will complete when the pause operation has been scheduled. If the wrapped value is true the operation suceeded.</returns>
 | 
			
		||||
        [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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Resumes a paused workflow instance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the target workflow instance.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task" /> that will complete when the resume operation has been scheduled. If the wrapped value is true the operation suceeded.</returns>
 | 
			
		||||
        [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);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delete all state associated with the specified workflow instance. The workflow must be in a non-running state to be purged.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="instanceId">The unique ID of the target workflow instance.</param>
 | 
			
		||||
        /// <param name="workflowComponent">The component to interface with.</param>
 | 
			
		||||
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task" /> that will complete when the purge operation has been scheduled. If the wrapped value is true the operation suceeded.</returns>
 | 
			
		||||
        [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);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2036,287 +2036,6 @@ namespace Dapr.Client
 | 
			
		|||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #region Workflow API
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public async override Task<StartWorkflowResponse> StartWorkflowAsync(
 | 
			
		||||
            string workflowComponent,
 | 
			
		||||
            string workflowName,
 | 
			
		||||
            string instanceId = null,
 | 
			
		||||
            object input = null,
 | 
			
		||||
            IReadOnlyDictionary<string, string> 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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [Obsolete]
 | 
			
		||||
        public async override Task<GetWorkflowResponse> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        [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
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// The response type for the <see cref="DaprClient.GetWorkflowAsync"/> API.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class GetWorkflowResponse
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the instance ID of the workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string InstanceId { get; init; }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name of the workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string WorkflowName { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name of the workflow component.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string WorkflowComponentName { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the time at which the workflow was created.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public DateTime CreatedAt { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the time at which the workflow was last updated.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public DateTime LastUpdatedAt { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the runtime status of the workflow.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public WorkflowRuntimeStatus RuntimeStatus { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the component-specific workflow properties.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public IReadOnlyDictionary<string, string> Properties { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the details associated with the workflow failure, if any.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public WorkflowFailureDetails FailureDetails { get; init; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Deserializes the workflow input into <typeparamref name="T"/> using <see cref="JsonSerializer"/>.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">The type to deserialize the workflow input into.</typeparam>
 | 
			
		||||
        /// <param name="options">Options to control the behavior during parsing.</param>
 | 
			
		||||
        /// <returns>Returns the input as <typeparamref name="T"/>, or returns a default value if the workflow doesn't have an input.</returns>
 | 
			
		||||
        public T ReadInputAs<T>(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<T>(serializedInput, options);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Deserializes the workflow output into <typeparamref name="T"/> using <see cref="JsonSerializer"/>.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">The type to deserialize the workflow output into.</typeparam>
 | 
			
		||||
        /// <param name="options">Options to control the behavior during parsing.</param>
 | 
			
		||||
        /// <returns>Returns the output as <typeparamref name="T"/>, or returns a default value if the workflow doesn't have an output.</returns>
 | 
			
		||||
        public T ReadOutputAs<T>(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<T>(serializedOutput, options);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents workflow failure details.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="ErrorMessage">A summary description of the failure, which is typically an exception message.</param>
 | 
			
		||||
    /// <param name="ErrorType">The error type, which is defined by the workflow component implementation.</param>
 | 
			
		||||
    /// <param name="StackTrace">The stack trace of the failure.</param>
 | 
			
		||||
    public record WorkflowFailureDetails(
 | 
			
		||||
        string ErrorMessage,
 | 
			
		||||
        string ErrorType,
 | 
			
		||||
        string StackTrace = null)
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates a user-friendly string representation of the failure information.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return $"{this.ErrorType}: {this.ErrorMessage}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
// limitations under the License.
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
namespace Dapr.Client
 | 
			
		||||
namespace Dapr.Workflow
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Enum describing the runtime status of a workflow.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,171 +0,0 @@
 | 
			
		|||
// ------------------------------------------------------------------------
 | 
			
		||||
// 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.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Dapr.Client;
 | 
			
		||||
using FluentAssertions;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Dapr.E2E.Test
 | 
			
		||||
{
 | 
			
		||||
    [Obsolete]
 | 
			
		||||
    public partial class E2ETests
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public async Task TestWorkflowLogging()
 | 
			
		||||
        {
 | 
			
		||||
            // This test starts the daprclient and searches through the logfile to ensure the
 | 
			
		||||
            // workflow logger is correctly logging the registered workflow(s) and activity(s)
 | 
			
		||||
 | 
			
		||||
            Dictionary<string, bool> logStrings = new Dictionary<string, bool>();
 | 
			
		||||
            logStrings["PlaceOrder"] = false;
 | 
			
		||||
            logStrings["ShipProduct"] = false;
 | 
			
		||||
            var logFilePath = "../../../../../test/Dapr.E2E.Test.App/log.txt";
 | 
			
		||||
            var allLogsFound = false;
 | 
			
		||||
            var timeout = 30; // 30s
 | 
			
		||||
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout));
 | 
			
		||||
            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");
 | 
			
		||||
 | 
			
		||||
            var searchTask = Task.Run(async () =>
 | 
			
		||||
            {
 | 
			
		||||
                using (StreamReader reader = new StreamReader(logFilePath))
 | 
			
		||||
                {
 | 
			
		||||
                    string line;
 | 
			
		||||
                    while ((line = await reader.ReadLineAsync().WaitAsync(cts.Token)) != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (var entry in logStrings)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (line.Contains(entry.Key))
 | 
			
		||||
                            {
 | 
			
		||||
                                logStrings[entry.Key] = true;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        allLogsFound = logStrings.All(k => k.Value);
 | 
			
		||||
                        if (allLogsFound)
 | 
			
		||||
                        {
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, cts.Token);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                await searchTask;
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(logFilePath);
 | 
			
		||||
            }
 | 
			
		||||
            if (!allLogsFound)
 | 
			
		||||
            {
 | 
			
		||||
                Assert.Fail("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<string, string> workflowOptions = new Dictionary<string, string>();
 | 
			
		||||
            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.Fail("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<string>();
 | 
			
		||||
            deserializedOutput.Should().Be("computers", $"Deserialized output '{deserializedOutput}' was not expected");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue