コード例 #1
0
 private static void CompleteFailedTask(RevaleeTask task, string message)
 {
     Supervisor.State.CompleteTask(task);
     Supervisor.LogEvent(message, TraceEventType.Error);
     Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
     Supervisor.Telemetry.RecordFailedCallback();
 }
コード例 #2
0
 private static TimeSpan CalculateWaitTime(DateTime time, RevaleeTask task)
 {
     if (task.CallbackTime > task.CreatedTime)
     {
         if (task.CallbackTime < time)
         {
             return(time.Subtract(task.CallbackTime));
         }
         else
         {
             return(TimeSpan.Zero);
         }
     }
     else
     {
         if (task.CreatedTime < time)
         {
             return(time.Subtract(task.CreatedTime));
         }
         else
         {
             return(TimeSpan.Zero);
         }
     }
 }
コード例 #3
0
        private void ProcessWebException(RevaleeTask task, WebException wex)
        {
            HttpWebResponse failedResponse = (HttpWebResponse)wex.Response;

            if (failedResponse != null)
            {
                switch (DetermineResult(failedResponse.StatusCode))
                {
                case CallbackResult.NonretryableError:
                    CompleteFailedTask(task, FormatHttpErrorMessage(task, failedResponse.StatusCode));
                    break;

                default:
                    CompleteRetryableTask(task, FormatHttpErrorMessage(task, failedResponse.StatusCode));
                    break;
                }
            }
            else
            {
                switch (DetermineResult(wex.Status))
                {
                case CallbackResult.NonretryableError:
                    CompleteFailedTask(task, FormatWebExceptionMessage(task, wex));
                    break;

                default:
                    CompleteRetryableTask(task, FormatWebExceptionMessage(task, wex));
                    break;
                }
            }
        }
コード例 #4
0
 private static void CompleteFailedTask(RevaleeTask task, Exception exception)
 {
     Supervisor.State.CompleteTask(task);
     Supervisor.LogException(exception, TraceEventType.Error, task.CallbackUrl.OriginalString);
     Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
     Supervisor.Telemetry.RecordFailedCallback();
 }
コード例 #5
0
        private static HttpWebRequest PrepareWebRequest(RevaleeTask task)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FormatCallbackRequestUrl(task.CallbackUrl));

            request.ServicePoint.Expect100Continue = false;
            request.AllowAutoRedirect            = true;
            request.MaximumAutomaticRedirections = 10;
            request.KeepAlive   = false;
            request.Method      = "POST";
            request.Pipelined   = false;
            request.Timeout     = 30000;
            request.UserAgent   = "Revalee";
            request.ContentType = "application/x-www-form-urlencoded";

            if (!string.IsNullOrEmpty(task.AuthorizationCipher))
            {
                string responseCipher = BuildResponseAuthorizationCipher(task.AuthorizationCipher, task.CallbackId);

                if (responseCipher != null)
                {
                    request.Headers.Add("Revalee-Auth", responseCipher);
                }
            }

            string postedData = FormatFormPayload(task);

            request.ContentLength = postedData.Length;

            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(Encoding.UTF8.GetBytes(postedData), 0, postedData.Length);
            }

            return(request);
        }
コード例 #6
0
 private static void CompleteSuccessfulTask(RevaleeTask task)
 {
     Supervisor.State.CompleteTask(task);
     Supervisor.LogEvent(string.Format("Successful callback to {0}. [{1}]", task.CallbackUrl.OriginalString, task.CallbackId), TraceEventType.Verbose);
     Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
     Supervisor.Telemetry.RecordSuccessfulCallback();
     RetryHeuristics.OnSuccess(task.CallbackUrl);
 }
コード例 #7
0
 private static void CompleteFailedTask(RevaleeTask task, HttpStatusCode statusCode)
 {
     Supervisor.State.CompleteTask(task);
     Supervisor.LogEvent(string.Format("Unsuccessful callback to {0} due to HTTP status code {1}. [{2}]",
                                       task.CallbackUrl.OriginalString, (int)statusCode, task.CallbackId), TraceEventType.Error);
     Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
     Supervisor.Telemetry.RecordFailedCallback();
 }
コード例 #8
0
        private void ProcessTask(object state)
        {
            RevaleeTask task = (RevaleeTask)state;

            if (!task.AttemptCallback())
            {
                return;
            }

            try
            {
                HttpWebRequest     request      = PrepareWebRequest(task);
                Task <WebResponse> responseTask = Task.Factory.FromAsync <WebResponse>(request.BeginGetResponse, request.EndGetResponse, request);
                responseTask.ContinueWith(t =>
                {
                    HttpWebResponse response = null;
                    try
                    {
                        response = (HttpWebResponse)t.Result;
                        ProcessWebResponse(task, response);
                    }
                    catch (WebException wex)
                    {
                        ProcessWebException(task, wex);
                    }
                    catch (AggregateException aex)
                    {
                        WebException wex = ExtractWebException(aex);

                        if (wex != null)
                        {
                            ProcessWebException(task, wex);
                        }
                        else
                        {
                            // Non-retryable error
                            CompleteFailedTask(task, FormatGenericExceptionMessage(task, aex));
                        }
                    }
                    finally
                    {
                        if (response != null)
                        {
                            response.Close();
                        }
                    }
                });
            }
            catch (WebException wex)
            {
                ProcessWebException(task, wex);
            }
            catch (SecurityException sex)
            {
                // Non-retryable error
                CompleteFailedTask(task, FormatGenericExceptionMessage(task, sex));
            }
        }
コード例 #9
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void ReenlistTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            _AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, task.CallbackTime);
            ResetTaskAlarm();
        }
コード例 #10
0
        private static void RetryTask(RevaleeTask task)
        {
            // Update the persisted attempt counts
            Supervisor.State.UpdateTask(task);

            // Reenlist task to be retried later
            TimeSpan retryDelay          = RetryHeuristics.OnRetryableFailure(task.CallbackUrl);
            DateTime delayedCallbackTime = DateTime.UtcNow.Add(retryDelay);

            Supervisor.State.ReenlistTask(task, delayedCallbackTime);
            Supervisor.LogEvent(string.Format("Retrying callback to {0} after waiting {1}. [{2}]", task.CallbackUrl.OriginalString, retryDelay, task.CallbackId), TraceEventType.Information);
        }
コード例 #11
0
 private static void CompleteRetryableTask(RevaleeTask task, Exception exception)
 {
     if (task.AttemptsRemaining > 0)
     {
         RetryTask(task);
     }
     else
     {
         // Out of attempts
         CompleteFailedTask(task, exception);
     }
 }
コード例 #12
0
 private static void CompleteRetryableTask(RevaleeTask task, HttpStatusCode statusCode)
 {
     if (task.AttemptsRemaining > 0)
     {
         RetryTask(task);
     }
     else
     {
         // Out of attempts
         CompleteFailedTask(task, statusCode);
     }
 }
コード例 #13
0
        private static string FormatFormPayload(RevaleeTask task)
        {
            var payload = new StringBuilder();

            payload.Append("CallbackId=");
            payload.Append(task.CallbackId.ToString("D"));
            payload.Append("&CallbackTime=");
            payload.Append(task.CallbackTime.ToString(@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture));
            payload.Append("&CurrentServiceTime=");
            payload.Append(DateTime.UtcNow.ToString(@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture));
            return(payload.ToString());
        }
コード例 #14
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void CompleteTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            lock (_SyncRoot)
            {
                _PersistenceProvider.RemoveTask(task);
                Supervisor.Telemetry.DecrementAwaitingTasksValue();
            }
        }
コード例 #15
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void UpdateTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            lock (_SyncRoot)
            {
                _PersistenceProvider.RemoveTask(task);
                _PersistenceProvider.AddTask(task);
            }
        }
コード例 #16
0
 private static void CompleteRetryableTask(RevaleeTask task, string message)
 {
     if (task.AttemptsRemaining > 0)
     {
         Supervisor.LogEvent(message, TraceEventType.Warning);
         RetryTask(task);
     }
     else
     {
         // Out of attempts
         CompleteFailedTask(task, message);
     }
 }
コード例 #17
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void ReenlistTask(RevaleeTask task, DateTime due)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (due.Kind != DateTimeKind.Utc)
            {
                throw new ArgumentException("DateTime argument not provided in UTC.", "due");
            }

            _AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, due);
            ResetTaskAlarm();
        }
コード例 #18
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void AddTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            lock (_SyncRoot)
            {
                _PersistenceProvider.AddTask(task);
            }

            _AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, task.CallbackTime);
            Supervisor.Telemetry.IncrementAwaitingTasksValue();
            ResetTaskAlarm();
        }
コード例 #19
0
        private void ProcessWebResponse(RevaleeTask task, HttpWebResponse response)
        {
            switch (DetermineResult(response.StatusCode))
            {
            case CallbackResult.Success:
                CompleteSuccessfulTask(task);
                break;

            case CallbackResult.NonretryableError:
                CompleteFailedTask(task, FormatHttpErrorMessage(task, response.StatusCode));
                break;

            default:
                CompleteRetryableTask(task, FormatHttpErrorMessage(task, response.StatusCode));
                break;
            }
        }
コード例 #20
0
ファイル: StateManager.cs プロジェクト: javafun/Revalee
        public void CancelTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            RevaleeTask awaitingTask;

            if (_AwaitingTaskCollection.TryGetValue(task.CallbackId, out awaitingTask))
            {
                if (awaitingTask.CallbackUrl.ToString().StartsWith(task.CallbackUrl.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    RevaleeTask removedTask;
                    bool        wasTaskRemoved = _AwaitingTaskCollection.TryRemove(awaitingTask.CallbackId, out removedTask);

                    lock (_SyncRoot)
                    {
                        _PersistenceProvider.RemoveTask(awaitingTask);
                    }

                    if (wasTaskRemoved)
                    {
                        Supervisor.Telemetry.DecrementAwaitingTasksValue();
                    }
                }
            }
            else
            {
                RevaleeTask storedTask = RetrieveTask(task.CallbackId);

                if (storedTask != null)
                {
                    if (storedTask.CallbackUrl.ToString().StartsWith(task.CallbackUrl.ToString(), StringComparison.OrdinalIgnoreCase))
                    {
                        lock (_SyncRoot)
                        {
                            _PersistenceProvider.RemoveTask(storedTask);
                        }
                    }
                }
            }
        }
コード例 #21
0
		public void AddTask(RevaleeTask Task)
		{
			return;
		}
コード例 #22
0
 private static string FormatHttpErrorMessage(RevaleeTask task, HttpStatusCode statusCode)
 {
     return(string.Format("Unsuccessful callback to {0} due to HTTP status code {1}. [{2}]",
                          task.CallbackUrl.OriginalString, (int)statusCode, task.CallbackId));
 }
コード例 #23
0
		public void RemoveTask(RevaleeTask Task)
		{
			return;
		}
コード例 #24
0
        private void ProcessTask(object state)
        {
            RevaleeTask task = (RevaleeTask)state;

            if (!task.AttemptCallback())
            {
                return;
            }

            try
            {
                HttpWebRequest     request      = PrepareWebRequest(task);
                Task <WebResponse> responseTask = Task.Factory.FromAsync <WebResponse>(request.BeginGetResponse, request.EndGetResponse, request);
                responseTask.ContinueWith(t =>
                {
                    try
                    {
                        HttpWebResponse response = null;
                        try
                        {
                            response = (HttpWebResponse)t.Result;
                            ProcessWebResponse(task, response);
                        }
                        catch (AggregateException aex)
                        {
                            if (aex.InnerExceptions.Count == 1 && aex.InnerExceptions[0] is WebException)
                            {
                                ProcessWebException(task, aex.InnerExceptions[0] as WebException);
                            }
                            else
                            {
                                aex = aex.Flatten();

                                if (aex.InnerExceptions.Count > 0)
                                {
                                    throw aex.InnerExceptions[0];
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                        finally
                        {
                            if (response != null)
                            {
                                response.Close();
                            }
                        }
                    }
                    catch (WebException wex)
                    {
                        ProcessWebException(task, wex);
                    }
                    catch (AggregateException aex)
                    {
                        // Non-retryable error
                        CompleteFailedTask(task, aex);
                    }
                });
            }
            catch (WebException wex)
            {
                ProcessWebException(task, wex);
            }
            catch (SecurityException sex)
            {
                // Non-retryable error
                CompleteFailedTask(task, sex);
            }
        }
コード例 #25
0
        public void Process(HttpListenerRequest request, HttpListenerResponse response)
        {
            try
            {
                if (request.HttpMethod != "PUT" && request.HttpMethod != "DELETE")
                {
                    FinalizeRejectedResponse(request, response, 405, "Method Not Supported", null);
                    return;
                }

                if (request.QueryString.Count < 2)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
                    return;
                }

                Guid?guid = RetrieveGuidParameter(request);
                if (!guid.HasValue)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
                    return;
                }

                Uri url = RetrieveUrlParameter(request);
                if (url == null)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
                    return;
                }

                if (UrlContainsDangerousMarkup(url))
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", url);
                    return;
                }

                RevaleeUrlAuthorization authorization = Supervisor.Configuration.AuthorizedTargets.Match(url);
                if (authorization == null)
                {
                    // Keep all authorization errors homogeneous from the client perspective
                    RevaleeUrlAuthorization.ObfuscateExecutionTime();
                    FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
                    return;
                }

                if (!authorization.IsAuthorizedRequestSource(request.RemoteEndPoint.Address))
                {
                    // Keep all authorization errors homogeneous from the client perspective
                    RevaleeUrlAuthorization.ObfuscateExecutionTime();
                    FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
                    return;
                }

                if (Supervisor.Work.IsOverloaded)
                {
                    FinalizeRejectedResponse(request, response, 503, "Service Unavailable", url);
                    return;
                }

                RevaleeTask taskToCancel = RevaleeTask.Revive(DateTime.MinValue, url, DateTime.UtcNow, guid.Value, 0, null);
                Supervisor.State.CancelTask(taskToCancel);

                FinalizeAcceptedResponse(request, response, guid.Value, url);
                return;
            }
            catch (HttpListenerException hlex)
            {
                Supervisor.LogException(hlex, TraceEventType.Error, request.RawUrl);
                FinalizeRejectedResponse(request, response, 500, "Error Occurred", null);
                return;
            }
        }
コード例 #26
0
        public void Process(HttpListenerRequest request, HttpListenerResponse response)
        {
            try
            {
                if (request.HttpMethod != "PUT")
                {
                    FinalizeRejectedResponse(request, response, 405, "Method Not Supported", null);
                    return;
                }

                if (request.QueryString.Count < 2)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
                    return;
                }

                Uri url = RetrieveUrlParameter(request);
                if (url == null)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
                    return;
                }

                DateTime?time = RetrieveTimeParameter(request);
                if (!time.HasValue)
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", url);
                    return;
                }

                if (UrlContainsDangerousMarkup(url))
                {
                    FinalizeRejectedResponse(request, response, 400, "Bad Request", url);
                    return;
                }

                RevaleeUrlAuthorization authorization = Supervisor.Configuration.AuthorizedTargets.Match(url);
                if (authorization == null)
                {
                    // Keep all authorization errors homogeneous from the client perspective
                    RevaleeUrlAuthorization.ObfuscateExecutionTime();
                    FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
                    return;
                }

                if (!authorization.IsAuthorizedRequestSource(request.RemoteEndPoint.Address))
                {
                    // Keep all authorization errors homogeneous from the client perspective
                    RevaleeUrlAuthorization.ObfuscateExecutionTime();
                    FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
                    return;
                }

                if (Supervisor.Work.IsOverloaded)
                {
                    FinalizeRejectedResponse(request, response, 503, "Service Unavailable", url);
                    return;
                }

                string authorizationCipher = RetrieveAuthorizationHeader(request);

                RevaleeTask newTask = new RevaleeTask(time.Value, url, authorization.RetryCount, authorizationCipher);
                Supervisor.State.AddTask(newTask);

                FinalizeAcceptedResponse(request, response, newTask);
                return;
            }
            catch (HttpListenerException hlex)
            {
                Supervisor.LogException(hlex, TraceEventType.Error, request.RawUrl);
                FinalizeRejectedResponse(request, response, 500, "Error Occurred", null);
                return;
            }
        }
コード例 #27
0
 private static string FormatGenericExceptionMessage(RevaleeTask task, Exception exception)
 {
     return(string.Format("{0} [{1}]", exception.Message, task.CallbackUrl.OriginalString));
 }
コード例 #28
0
 private static string FormatWebExceptionMessage(RevaleeTask task, WebException webException)
 {
     return(string.Format("Unsuccessful callback to {0} with status '{1}'. [{2}]",
                          task.CallbackUrl.OriginalString, webException.Status.ToString(), task.CallbackId));
 }
コード例 #29
0
        private static void FinalizeAcceptedResponse(HttpListenerRequest request, HttpListenerResponse response, RevaleeTask task)
        {
            string remoteAddress = request.RemoteEndPoint.Address.ToString();

            try
            {
                response.StatusCode        = 200;
                response.StatusDescription = "OK";
                byte[] confirmation_number = Encoding.UTF8.GetBytes(task.CallbackId.ToString());
                response.ContentLength64 = confirmation_number.LongLength;
                response.OutputStream.Write(confirmation_number, 0, confirmation_number.Length);
            }
            finally
            {
                response.Close();
            }

            Supervisor.Telemetry.RecordAcceptedRequest();
            Supervisor.LogEvent(string.Format("Request accepted for {0} @ {1:d} {1:t} from {2}. [{3}]", task.CallbackUrl.OriginalString, task.CallbackTime, remoteAddress, task.CallbackId), TraceEventType.Verbose);
        }