Example #1
0
        async Task <DurableHttpResponse> IDurableOrchestrationContext.CallHttpAsync(DurableHttpRequest req)
        {
            DurableHttpResponse durableHttpResponse = await this.ScheduleDurableHttpActivityAsync(req);

            HttpStatusCode currStatusCode = durableHttpResponse.StatusCode;

            while (currStatusCode == HttpStatusCode.Accepted && req.AsynchronousPatternEnabled)
            {
                Dictionary <string, StringValues> headersDictionary = new Dictionary <string, StringValues>(durableHttpResponse.Headers);
                DateTime fireAt = default(DateTime);
                if (headersDictionary.ContainsKey("Retry-After"))
                {
                    fireAt = this.InnerContext.CurrentUtcDateTime.AddSeconds(int.Parse(headersDictionary["Retry-After"]));
                }
                else
                {
                    fireAt = this.InnerContext.CurrentUtcDateTime.AddMilliseconds(this.Config.Options.HttpSettings.DefaultAsyncRequestSleepTimeMilliseconds);
                }

                this.IncrementActionsOrThrowException();
                await this.InnerContext.CreateTimer(fireAt, CancellationToken.None);

                DurableHttpRequest durableAsyncHttpRequest = this.CreateHttpRequestMessageCopy(req, durableHttpResponse.Headers["Location"]);
                durableHttpResponse = await this.ScheduleDurableHttpActivityAsync(durableAsyncHttpRequest);

                currStatusCode = durableHttpResponse.StatusCode;
            }

            return(durableHttpResponse);
        }
Example #2
0
        public async override Task <string> RunAsync(TaskContext context, string rawInput)
        {
            DurableHttpRequest durableHttpRequest = ReconstructDurableHttpRequest(rawInput);
            HttpRequestMessage requestMessage     = await this.ConvertToHttpRequestMessage(durableHttpRequest);

            HttpResponseMessage response;

            if (durableHttpRequest.Timeout == null)
            {
                response = await this.httpClient.SendAsync(requestMessage);
            }
            else
            {
                try
                {
                    using (CancellationTokenSource cts = new CancellationTokenSource())
                    {
                        cts.CancelAfter(durableHttpRequest.Timeout.Value);
                        response = await this.httpClient.SendAsync(requestMessage, cts.Token);
                    }
                }
                catch (OperationCanceledException ex)
                {
                    TimeoutException e = new TimeoutException(ex.Message + $" Reached user specified timeout: {durableHttpRequest.Timeout.Value}.");

                    string details = Utils.SerializeCause(e, this.config.ErrorDataConverter);
                    throw new TaskFailureException(e.Message, e, details);
                }
            }

            DurableHttpResponse durableHttpResponse = await DurableHttpResponse.CreateDurableHttpResponseWithHttpResponseMessage(response);

            return(JsonConvert.SerializeObject(durableHttpResponse));
        }
Example #3
0
        Task <DurableHttpResponse> IDurableOrchestrationContext.CallHttpAsync(HttpMethod method, Uri uri, string content)
        {
            DurableHttpRequest req = new DurableHttpRequest(
                method: method,
                uri: uri,
                content: content);

            return(((IDurableOrchestrationContext)this).CallHttpAsync(req));
        }
Example #4
0
        private async Task <HttpRequestMessage> ConvertToHttpRequestMessage(DurableHttpRequest durableHttpRequest)
        {
            string             contentType    = "";
            HttpRequestMessage requestMessage = new HttpRequestMessage(durableHttpRequest.Method, durableHttpRequest.Uri);

            if (durableHttpRequest.Headers != null)
            {
                foreach (KeyValuePair <string, StringValues> entry in durableHttpRequest.Headers)
                {
                    if (entry.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
                    {
                        foreach (string value in entry.Value)
                        {
                            if (value.Contains("multipart"))
                            {
                                throw new FunctionFailedException("Multipart content is not supported with CallHttpAsync.");
                            }
                            else
                            {
                                contentType = value;
                            }
                        }
                    }
                    else
                    {
                        requestMessage.Headers.Add(entry.Key, (IEnumerable <string>)entry.Value);
                    }
                }
            }

            if (durableHttpRequest.Content != null)
            {
                if (contentType == "")
                {
                    contentType = "text/plain";
                }

                if (string.Equals(contentType, "application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
                {
                    requestMessage.Content = new StringContent(durableHttpRequest.Content, Encoding.UTF8, contentType);
                }
                else
                {
                    requestMessage.Content = new StringContent(durableHttpRequest.Content);
                    requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                }
            }

            if (durableHttpRequest.TokenSource != null)
            {
                string accessToken = await durableHttpRequest.TokenSource.GetTokenAsync();

                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            }

            return(requestMessage);
        }
Example #5
0
        private static DurableHttpRequest ReconstructDurableHttpRequest(string serializedRequest)
        {
            // DeserializeObject deserializes into a List and then the first element
            // of that list is the DurableHttpRequest
            IList <DurableHttpRequest> input = JsonConvert.DeserializeObject <IList <DurableHttpRequest> >(serializedRequest);
            DurableHttpRequest         durableHttpRequest = input.First();

            return(durableHttpRequest);
        }
Example #6
0
        private DurableHttpRequest CreateHttpRequestMessageCopy(DurableHttpRequest durableHttpRequest, string locationUri)
        {
            DurableHttpRequest newDurableHttpRequest = new DurableHttpRequest(
                method: HttpMethod.Get,
                uri: new Uri(locationUri),
                headers: durableHttpRequest.Headers,
                content: durableHttpRequest.Content,
                tokenSource: durableHttpRequest.TokenSource);

            return(newDurableHttpRequest);
        }
Example #7
0
        private async Task <DurableHttpResponse> ScheduleDurableHttpActivityAsync(DurableHttpRequest req)
        {
            DurableHttpResponse durableHttpResponse = await this.CallDurableTaskFunctionAsync <DurableHttpResponse>(
                functionName : HttpOptions.HttpTaskActivityReservedName,
                functionType : FunctionType.Activity,
                oneWay : false,
                instanceId : null,
                operation : null,
                retryOptions : null,
                input : req);

            return(durableHttpResponse);
        }
Example #8
0
        private DurableHttpRequest CreateLocationPollRequest(DurableHttpRequest durableHttpRequest, string locationUri)
        {
            DurableHttpRequest newDurableHttpRequest = new DurableHttpRequest(
                method: HttpMethod.Get,
                uri: new Uri(locationUri),
                headers: durableHttpRequest.Headers,
                content: durableHttpRequest.Content,
                tokenSource: durableHttpRequest.TokenSource);

            // Do not copy over the x-functions-key header, as in many cases, the
            // functions key used for the initial request will be a Function-level key
            // and the status endpoint requires a master key.
            newDurableHttpRequest.Headers.Remove("x-functions-key");

            return(newDurableHttpRequest);
        }