private static async Task <StatusCodeResult> RedisUpsert(ProcessingUpdate update, AppInsightsLogger appInsightsLogger, string redisOperation)
        {
            IDatabase db = null;

            try
            {
                db = RedisConnection.GetDatabase();
            }
            catch (Exception ex)
            {
                appInsightsLogger.LogError(ex, update.ApiPath);
                appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, DateTime.UtcNow.ToString(), update.ApiPath);
                return(new StatusCodeResult(500));
            }

            try
            {
                var keyname  = APP_INSIGHTS_REQUESTS_KEY_NAME + "/" + update.ServiceCluster + update.ApiPath;
                var newCount = await db.StringIncrementAsync(keyname, update.IncrementBy - update.DecrementBy);

                appInsightsLogger.LogMetric(keyname, newCount, update.ApiPath);
                return(new StatusCodeResult(200));
            }
            catch (Exception ex)
            {
                appInsightsLogger.LogError(ex, update.ApiPath);
                appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, DateTime.UtcNow.ToString(), update.ApiPath);
                return(new StatusCodeResult(500));
            }
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger logger)
        {
            AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION);
            var redisOperation = "increment";

            if (req.Body != null)
            {
                string body = string.Empty;
                try
                {
                    using (StreamReader reader = new StreamReader(req.Body))
                    {
                        if (reader.BaseStream.Length > 0)
                        {
                            body = reader.ReadToEnd();
                            ProcessingUpdate update = null;

                            try
                            {
                                update = JsonConvert.DeserializeObject <ProcessingUpdate>(body);
                            }
                            catch
                            {
                                update = JsonConvert.DeserializeObject <ProcessingUpdate[]>(body)[0];
                            }

                            if (update == null)
                            {
                                appInsightsLogger.LogWarning("Parameters missing. Unable to update processing count.");
                                return(new BadRequestResult());
                            }
                            else
                            {
                                return(await RedisUpsert(update, appInsightsLogger, redisOperation));
                            }
                        }
                        else
                        {
                            appInsightsLogger.LogWarning("Parameters missing. Unable to update processing count.");
                            return(new BadRequestResult());
                        }
                    }
                }
                catch (Exception ex)
                {
                    appInsightsLogger.LogError(ex);
                    appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, DateTime.UtcNow.ToString(), body);
                    return(new StatusCodeResult(500));
                }
            }
            else
            {
                return(new BadRequestResult());
            }
        }
        public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger logger)
        {
            IDatabase         db = null;
            AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION);
            var redisOperation = "insert";

            APITask task = null;

            if (req.Body != null)
            {
                string body = string.Empty;
                try
                {
                    using (StreamReader reader = new StreamReader(req.Body))
                    {
                        if (reader.BaseStream.Length > 0)
                        {
                            body = reader.ReadToEnd();
                            logger.LogInformation("body: " + body);

                            try
                            {
                                appInsightsLogger.LogInformation("DeserializeObject<APITask>(body)");
                                task = JsonConvert.DeserializeObject <APITask>(body);
                            }
                            catch
                            {
                                appInsightsLogger.LogInformation("DeserializeObject<APITask>(body[])");
                                task = JsonConvert.DeserializeObject <APITask[]>(body)[0];
                            }

                            appInsightsLogger.LogInformation("task.PublishToGrid: " + task.PublishToGrid.ToString(), task.Endpoint, task.TaskId);
                        }
                        else
                        {
                            appInsightsLogger.LogWarning("Parameters missing. Unable to create task.");
                            return(new BadRequestResult());
                        }
                    }
                }
                catch (Exception ex)
                {
                    appInsightsLogger.LogError(ex);
                    appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, body);
                    return(new StatusCodeResult(500));
                }
            }
            else
            {
                appInsightsLogger.LogWarning("Parameters missing. Unable to create task.");
                return(new BadRequestResult());
            }

            if (!String.IsNullOrWhiteSpace(task.TaskId))
            {
                appInsightsLogger.LogInformation("Updating status", task.Endpoint, task.TaskId);
                redisOperation = "update";
            }
            else
            {
                task.TaskId = Guid.NewGuid().ToString();
                appInsightsLogger.LogInformation("Generated new taskId: " + task.TaskId, task.Endpoint, task.TaskId);
            }

            task.Timestamp = DateTime.UtcNow.ToString();

            try
            {
                db = RedisConnection.GetDatabase();
            }
            catch (Exception ex)
            {
                appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId);
                appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, task.Endpoint, task.TaskId);
                return(new StatusCodeResult(500));
            }

            string serializedTask = string.Empty;

            try
            {
                var taskBody = task.Body;
                task.Body = null;

                serializedTask = JsonConvert.SerializeObject(task);
                RedisValue res = RedisValue.Null;

                appInsightsLogger.LogInformation("Setting Redis task record", task.Endpoint, task.TaskId);
                var upsertTransaction = db.CreateTransaction();
                upsertTransaction.StringSetAsync(task.TaskId, serializedTask);

                // Get seconds since epoch
                TimeSpan ts        = (DateTime.UtcNow - new DateTime(1970, 1, 1));
                int      timestamp = (int)ts.TotalSeconds;

                appInsightsLogger.LogInformation(string.Format("Adding backend status '{0}' for endpoint.", task.BackendStatus), task.Endpoint, task.TaskId);
                upsertTransaction.SortedSetAddAsync(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), new SortedSetEntry[] { new SortedSetEntry(task.TaskId, timestamp) });

                if (task.BackendStatus.Equals(BACKEND_STATUS_RUNNING))
                {
                    upsertTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_CREATED), task.TaskId);
                }
                else if (task.BackendStatus.Equals(BACKEND_STATUS_COMPLETED) || task.BackendStatus.Equals(BACKEND_STATUS_FAILED))
                {
                    upsertTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_RUNNING), task.TaskId);
                }

                bool isSubsequentPipelineCall = false;

                bool isPublish = false;
                bool.TryParse(task.PublishToGrid.ToString(), out isPublish);

                if (isPublish == true || task.PublishToGrid == true)
                {
                    if (string.IsNullOrEmpty(taskBody))
                    {
                        appInsightsLogger.LogInformation("It IS a pipeline call", task.Endpoint, task.TaskId);
                        // This is a subsequent pipeline publish.
                        isSubsequentPipelineCall = true;
                    }
                    else
                    {
                        appInsightsLogger.LogInformation("Adding body to redis: " + taskBody, task.Endpoint, task.TaskId);
                        upsertTransaction.StringSetAsync(string.Format("{0}_{1}", task.TaskId, GRID_PUBLISH_RECORD_KEY), taskBody);
                    }
                }

                ExecuteTransaction(upsertTransaction, task, appInsightsLogger);

                if (isSubsequentPipelineCall)
                {
                    // We have to get the original body, since it's currently empty.
                    taskBody = db.StringGet(string.Format("{0}_{1}", task.TaskId, GRID_PUBLISH_RECORD_KEY));
                    appInsightsLogger.LogInformation("Stored body: " + taskBody, task.Endpoint, task.TaskId);
                }

                if (task.PublishToGrid)
                {
                    if (PublishEvent(task, taskBody, appInsightsLogger) == false)
                    {
                        // Move task to failed
                        var updateTransaction = db.CreateTransaction();
                        task.Status        = "Failed - unable to send to backend service.";
                        task.BackendStatus = BACKEND_STATUS_FAILED;
                        string updateBody = JsonConvert.SerializeObject(task);

                        updateTransaction.StringSetAsync(task.TaskId, updateBody);
                        updateTransaction.SortedSetAddAsync(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), new SortedSetEntry[] { new SortedSetEntry(task.TaskId, timestamp) });
                        updateTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_CREATED), task.TaskId);

                        ExecuteTransaction(updateTransaction, task, appInsightsLogger);
                    }
                }

                //LogSetCount(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), task, db, appInsightsLogger);
                appInsightsLogger.LogRedisUpsert("Redis upsert successful.", redisOperation, task.Timestamp, serializedTask, task.Endpoint, task.TaskId);
            }
            catch (Exception ex)
            {
                appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId);
                appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, serializedTask, task.Endpoint, task.TaskId);
                return(new StatusCodeResult(500));
            }

            return(new OkObjectResult(serializedTask));
        }