Task IDurableOrchestrationClient.RaiseEventAsync(string taskHubName, string instanceId, string eventName, object eventData, string connectionName)
        {
            if (string.IsNullOrEmpty(taskHubName))
            {
                throw new ArgumentNullException(nameof(taskHubName));
            }

            if (string.IsNullOrEmpty(eventName))
            {
                throw new ArgumentNullException(nameof(eventName));
            }

            if (string.IsNullOrEmpty(connectionName))
            {
                connectionName = this.attribute.ConnectionName;
            }

            var attribute = new DurableClientAttribute
            {
                TaskHub        = taskHubName,
                ConnectionName = connectionName,
            };

            TaskHubClient taskHubClient = ((DurableClient)this.config.GetClient(attribute)).client;

            return(this.RaiseEventInternalAsync(taskHubClient, taskHubName, instanceId, eventName, eventData));
        }
        private IDurableClient GetClient(HttpRequestMessage request)
        {
            string taskHub        = null;
            string connectionName = null;

            NameValueCollection pairs = request.GetQueryNameValuePairs();

            foreach (string key in pairs.AllKeys)
            {
                if (taskHub == null &&
                    key.Equals(TaskHubParameter, StringComparison.OrdinalIgnoreCase) &&
                    !string.IsNullOrWhiteSpace(pairs[key]))
                {
                    taskHub = pairs[key];
                }
                else if (connectionName == null &&
                         key.Equals(ConnectionParameter, StringComparison.OrdinalIgnoreCase) &&
                         !string.IsNullOrWhiteSpace(pairs[key]))
                {
                    connectionName = pairs[key];
                }
            }

            var attribute = new DurableClientAttribute
            {
                TaskHub        = taskHub,
                ConnectionName = connectionName,
            };

            return(this.GetClient(attribute));
        }
Example #3
0
        private AzureStorageDurabilityProvider GetAzureStorageStorageProvider(DurableClientAttribute attribute)
        {
            string connectionName = attribute.ConnectionName ?? this.defaultConnectionName;
            AzureStorageOrchestrationServiceSettings settings = this.GetAzureStorageOrchestrationServiceSettings(connectionName, attribute.TaskHub);

            AzureStorageDurabilityProvider innerClient;

            // Need to check this.defaultStorageProvider != null for external clients that call GetDurabilityProvider(attribute)
            // which never initializes the defaultStorageProvider.
            if (string.Equals(this.defaultSettings?.TaskHubName, settings.TaskHubName, StringComparison.OrdinalIgnoreCase) &&
                string.Equals(this.defaultSettings?.StorageConnectionString, settings.StorageConnectionString, StringComparison.OrdinalIgnoreCase) &&
                this.defaultStorageProvider != null)
            {
                // It's important that clients use the same AzureStorageOrchestrationService instance
                // as the host when possible to ensure we any send operations can be picked up
                // immediately instead of waiting for the next queue polling interval.
                innerClient = this.defaultStorageProvider;
            }
            else
            {
                ILogger logger = this.loggerFactory.CreateLogger(LoggerName);
                innerClient = new AzureStorageDurabilityProvider(
                    new AzureStorageOrchestrationService(settings),
                    connectionName,
                    this.azureStorageOptions,
                    logger);
            }

            return(innerClient);
        }
        private AzureStorageDurabilityProvider GetAzureStorageStorageProvider(DurableClientAttribute attribute)
        {
            string connectionName = attribute.ConnectionName ?? this.defaultConnectionName;
            AzureStorageOrchestrationServiceSettings settings = this.GetAzureStorageOrchestrationServiceSettings(connectionName, attribute.TaskHub);

            AzureStorageDurabilityProvider innerClient;

            if (string.Equals(this.defaultSettings.TaskHubName, settings.TaskHubName, StringComparison.OrdinalIgnoreCase) &&
                string.Equals(this.defaultSettings.StorageConnectionString, settings.StorageConnectionString, StringComparison.OrdinalIgnoreCase))
            {
                // It's important that clients use the same AzureStorageOrchestrationService instance
                // as the host when possible to ensure we any send operations can be picked up
                // immediately instead of waiting for the next queue polling interval.
                innerClient = this.defaultStorageProvider;
            }
            else
            {
                innerClient = new AzureStorageDurabilityProvider(
                    new AzureStorageOrchestrationService(settings),
                    connectionName,
                    this.azureStorageOptions);
            }

            return(innerClient);
        }
        public Task <IBinding> TryCreateAsync(BindingProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var parameter     = context.Parameter;
            var parameterType = parameter.ParameterType;

            if (parameterType.Name != TypedCodeProvider.ITypedDurableClient)
            {
                return(Task.FromResult <IBinding>(null));
            }

            DurableClientAttribute clientAttr = parameter.GetCustomAttribute <DurableClientAttribute>(inherit: false);

            if (clientAttr == null)
            {
                return(Task.FromResult <IBinding>(null));
            }

            var client = this.clientGenerator(clientAttr);

            if (client == null)
            {
                return(Task.FromResult <IBinding>(null));
            }

            return(Task.FromResult <IBinding>(new TypedDurableClientBinding(this.typedCodeProvider, client, parameter)));
        }
 // Get a response that will point to our webhook handler.
 internal HttpResponseMessage CreateCheckStatusResponse(
     HttpRequestMessage request,
     string instanceId,
     DurableClientAttribute attribute,
     bool returnInternalServerErrorOnFailure = false)
 {
     return(this.httpApiHandler.CreateCheckStatusResponse(request, instanceId, attribute, returnInternalServerErrorOnFailure));
 }
Example #7
0
        public virtual DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute)
        {
            if (!attribute.ExternalClient)
            {
                this.EnsureDefaultClientSettingsInitialized();
            }

            return(this.GetAzureStorageStorageProvider(attribute));
        }
 internal DurableClient(
     DurabilityProvider serviceClient,
     DurableTaskExtension config,
     HttpApiHandler httpHandler,
     DurableClientAttribute attribute)
     : this(serviceClient, httpHandler, attribute, config.MessageDataConverter, config.TraceHelper, config.Options)
 {
     this.config = config;
 }
        internal async Task <HttpResponseMessage> WaitForCompletionOrCreateCheckStatusResponseAsync(
            HttpRequestMessage request,
            string instanceId,
            DurableClientAttribute attribute,
            TimeSpan timeout,
            TimeSpan retryInterval)
        {
            if (retryInterval > timeout)
            {
                throw new ArgumentException($"Total timeout {timeout.TotalSeconds} should be bigger than retry timeout {retryInterval.TotalSeconds}");
            }

            HttpManagementPayload httpManagementPayload = this.GetClientResponseLinks(request, instanceId, attribute?.TaskHub, attribute?.ConnectionName);

            IDurableOrchestrationClient client = this.GetClient(request);
            Stopwatch stopwatch = Stopwatch.StartNew();

            while (true)
            {
                DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);

                if (status != null)
                {
                    if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed)
                    {
                        return(request.CreateResponse(HttpStatusCode.OK, status.Output));
                    }

                    if (status.RuntimeStatus == OrchestrationRuntimeStatus.Canceled ||
                        status.RuntimeStatus == OrchestrationRuntimeStatus.Failed ||
                        status.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
                    {
                        return(await this.HandleGetStatusRequestAsync(request, instanceId));
                    }
                }

                TimeSpan elapsed = stopwatch.Elapsed;
                if (elapsed < timeout)
                {
                    TimeSpan remainingTime = timeout.Subtract(elapsed);
                    await Task.Delay(remainingTime > retryInterval?retryInterval : remainingTime);
                }
                else
                {
                    return(this.CreateCheckStatusResponseMessage(
                               request,
                               instanceId,
                               httpManagementPayload.StatusQueryGetUri,
                               httpManagementPayload.SendEventPostUri,
                               httpManagementPayload.TerminatePostUri,
                               httpManagementPayload.PurgeHistoryDeleteUri));
                }
            }
        }
Example #10
0
        /// <summary>
        /// Gets a <see cref="IDurableClient"/> using configuration from a <see cref="DurableClientAttribute"/> instance.
        /// </summary>
        /// <param name="attribute">The attribute containing the client configuration parameters.</param>
        /// <returns>Returns a <see cref="IDurableClient"/> instance. The returned instance may be a cached instance.</returns>
        protected internal virtual IDurableClient GetClient(DurableClientAttribute attribute)
        {
            DurableClient client = this.cachedClients.GetOrAdd(
                attribute,
                attr =>
            {
                DurabilityProvider innerClient = this.durabilityProviderFactory.GetDurabilityProvider(attribute);
                return(new DurableClient(innerClient, this, this.HttpApiHandler, attr));
            });

            return(client);
        }
        // Get a response that will point to our webhook handler.
        internal HttpResponseMessage CreateCheckStatusResponse(
            HttpRequestMessage request,
            string instanceId,
            DurableClientAttribute attribute,
            bool returnInternalServerErrorOnFailure = false)
        {
            if (this.httpApiHandler == null)
            {
                throw new InvalidOperationException("IDurableClient.CreateCheckStatusResponse is not supported for IDurableClient instances created outside of a Durable Functions application.");
            }

            return(this.httpApiHandler.CreateCheckStatusResponse(request, instanceId, attribute, returnInternalServerErrorOnFailure));
        }
 // Get a response that will wait for response from the durable function for predefined period of time before
 // pointing to our webhook handler.
 internal async Task <HttpResponseMessage> WaitForCompletionOrCreateCheckStatusResponseAsync(
     HttpRequestMessage request,
     string instanceId,
     DurableClientAttribute attribute,
     TimeSpan timeout,
     TimeSpan retryInterval)
 {
     return(await this.httpApiHandler.WaitForCompletionOrCreateCheckStatusResponseAsync(
                request,
                instanceId,
                attribute,
                timeout,
                retryInterval));
 }
        private readonly DurableClientAttribute attribute; // for rehydrating a Client after a webhook

        internal DurableClient(
            DurabilityProvider serviceClient,
            DurableTaskExtension config,
            HttpApiHandler httpHandler,
            DurableClientAttribute attribute)
        {
            this.config = config ?? throw new ArgumentNullException(nameof(config));

            this.client             = new TaskHubClient(serviceClient);
            this.durabilityProvider = serviceClient;
            this.traceHelper        = config.TraceHelper;
            this.httpApiHandler     = httpHandler;
            this.hubName            = attribute.TaskHub ?? config.Options.HubName;
            this.attribute          = attribute;
        }
        internal HttpResponseMessage CreateCheckStatusResponse(
            HttpRequestMessage request,
            string instanceId,
            DurableClientAttribute attribute,
            bool returnInternalServerErrorOnFailure = false)
        {
            HttpManagementPayload httpManagementPayload = this.GetClientResponseLinks(request, instanceId, attribute?.TaskHub, attribute?.ConnectionName, returnInternalServerErrorOnFailure);

            return(this.CreateCheckStatusResponseMessage(
                       request,
                       httpManagementPayload.Id,
                       httpManagementPayload.StatusQueryGetUri,
                       httpManagementPayload.SendEventPostUri,
                       httpManagementPayload.TerminatePostUri,
                       httpManagementPayload.PurgeHistoryDeleteUri));
        }
        internal DurableClient(
            DurabilityProvider serviceClient,
            HttpApiHandler httpHandler,
            DurableClientAttribute attribute,
            MessagePayloadDataConverter messageDataConverter,
            EndToEndTraceHelper traceHelper,
            DurableTaskOptions durableTaskOptions)
        {
            this.messageDataConverter = messageDataConverter;

            this.client             = new TaskHubClient(serviceClient, this.messageDataConverter);
            this.durabilityProvider = serviceClient;
            this.traceHelper        = traceHelper;
            this.httpApiHandler     = httpHandler;
            this.durableTaskOptions = durableTaskOptions;
            this.hubName            = attribute.TaskHub ?? this.durableTaskOptions.HubName;
            this.attribute          = attribute;
        }
Example #16
0
        public DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute)
        {
            if (string.IsNullOrEmpty(attribute.TaskHub) && string.IsNullOrEmpty(attribute.ConnectionName))
            {
                return(this.defaultProvider);
            }

            if (string.Equals(attribute.TaskHub, this.defaultHubName) && string.Equals(attribute.ConnectionName, this.defaultConnectionName))
            {
                return(this.defaultProvider);
            }

            string redisConnectionString     = this.connectionResolver.Resolve(attribute.ConnectionName);
            var    redisOrchestartionService = new RedisOrchestrationService(new RedisOrchestrationServiceSettings()
            {
                TaskHubName           = attribute.TaskHub,
                RedisConnectionString = redisConnectionString,
            });

            return(new DurabilityProvider("Redis", redisOrchestartionService, redisOrchestartionService, attribute.ConnectionName));
        }
        /// <inheritdoc />
        Task IDurableEntityClient.SignalEntityAsync(EntityId entityId, string operationName, object operationInput, string taskHubName, string connectionName)
        {
            if (string.IsNullOrEmpty(taskHubName))
            {
                return(this.SignalEntityAsync(this.client, this.TaskHubName, entityId, operationName, operationInput));
            }
            else
            {
                if (string.IsNullOrEmpty(connectionName))
                {
                    connectionName = this.attribute.ConnectionName;
                }

                var attribute = new DurableClientAttribute
                {
                    TaskHub        = taskHubName,
                    ConnectionName = connectionName,
                };

                TaskHubClient taskHubClient = ((DurableClient)this.config.GetClient(attribute)).client;
                return(this.SignalEntityAsync(taskHubClient, taskHubName, entityId, operationName, operationInput));
            }
        }
        Task <EntityStateResponse <T> > IDurableEntityClient.ReadEntityStateAsync <T>(EntityId entityId, string taskHubName, string connectionName)
        {
            if (string.IsNullOrEmpty(taskHubName))
            {
                return(this.ReadEntityStateAsync <T>(this.DurabilityProvider, entityId));
            }
            else
            {
                if (string.IsNullOrEmpty(connectionName))
                {
                    connectionName = this.attribute.ConnectionName;
                }

                var attribute = new DurableClientAttribute
                {
                    TaskHub        = taskHubName,
                    ConnectionName = connectionName,
                };

                DurabilityProvider durabilityProvider = ((DurableClient)this.config.GetClient(attribute)).DurabilityProvider;
                return(this.ReadEntityStateAsync <T>(durabilityProvider, entityId));
            }
        }
        /// <inheritdoc />
        Task IDurableEntityClient.SignalEntityAsync(EntityId entityId, DateTime scheduledTimeUtc, string operationName, object operationInput, string taskHubName, string connectionName)
        {
            if (string.IsNullOrEmpty(taskHubName))
            {
                return(this.SignalEntityAsyncInternal(this, this.TaskHubName, entityId, scheduledTimeUtc, operationName, operationInput));
            }
            else
            {
                if (string.IsNullOrEmpty(connectionName))
                {
                    connectionName = this.attribute.ConnectionName;
                }

                var attribute = new DurableClientAttribute
                {
                    TaskHub        = taskHubName,
                    ConnectionName = connectionName,
                };

                var durableClient = (DurableClient)this.config.GetClient(attribute);
                return(this.SignalEntityAsyncInternal(durableClient, taskHubName, entityId, scheduledTimeUtc, operationName, operationInput));
            }
        }
 public StartOrchestrationArgs StringToStartOrchestrationArgs(string input, DurableClientAttribute attr)
 {
     return(!string.IsNullOrEmpty(input) ? JsonConvert.DeserializeObject <StartOrchestrationArgs>(input) : null);
 }
 public StartOrchestrationArgs JObjectToStartOrchestrationArgs(JObject input, DurableClientAttribute attr)
 {
     return(input?.ToObject <StartOrchestrationArgs>());
 }
        public string DurableOrchestrationClientToString(IDurableOrchestrationClient client, DurableClientAttribute attr)
        {
            var payload = new OrchestrationClientInputData
            {
                TaskHubName    = client.TaskHubName,
                CreationUrls   = this.config.HttpApiHandler.GetInstanceCreationLinks(),
                ManagementUrls = this.config.HttpApiHandler.CreateHttpManagementPayload(InstanceIdPlaceholder, attr?.TaskHub, attr?.ConnectionName),
                BaseUrl        = this.config.HttpApiHandler.GetBaseUrl(),
                RequiredQueryStringParameters = this.config.HttpApiHandler.GetUniversalQueryStrings(),
            };

            if (this.config.HttpApiHandler.TryGetRpcBaseUrl(out Uri rpcBaseUrl))
            {
                // If an RPC URL is not available, the out-of-proc durable client SDK is expected to fail.
                // In the case of JavaScript, however, the client SDK is expected to revert to legacy behavior.
                payload.RpcBaseUrl = rpcBaseUrl.OriginalString;
            }

            return(JsonConvert.SerializeObject(payload));
        }
        public IAsyncCollector <StartOrchestrationArgs> CreateAsyncCollector(DurableClientAttribute clientAttribute)
        {
            IDurableOrchestrationClient client = this.config.GetClient(clientAttribute);

            return(new OrchestrationClientAsyncCollector(client));
        }
        public string DurableOrchestrationClientToString(IDurableOrchestrationClient client, DurableClientAttribute attr)
        {
            var payload = new OrchestrationClientInputData
            {
                TaskHubName    = client.TaskHubName,
                CreationUrls   = this.config.HttpApiHandler.GetInstanceCreationLinks(),
                ManagementUrls = this.config.HttpApiHandler.CreateHttpManagementPayload(InstanceIdPlaceholder, attr?.TaskHub, attr?.ConnectionName),
                BaseUrl        = this.config.HttpApiHandler.GetBaseUrl(),
                RequiredQueryStringParameters = this.config.HttpApiHandler.GetUniversalQueryStrings(),
            };

            return(JsonConvert.SerializeObject(payload));
        }
 public DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute)
 {
     return(this.GetAzureStorageStorageProvider(attribute));
 }
 // protected virtual to allow mocking in unit tests.
 protected virtual IDurableClient GetClient(DurableClientAttribute attribute)
 {
     return(this.config.GetClient(attribute));
 }
 public DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute)
 {
     this.EnsureInitialized();
     return(this.GetAzureStorageStorageProvider(attribute));
 }
Example #28
0
 public DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute)
 {
     return(this.provider);
 }