//public static async Task getWorkflowFailedOperations(CancellationToken ct)
        //{
        //    string storageAccountString = CloudConfigurationManager.GetSetting(Configuration.ButlerStorageConnectionConfigurationKey);
        //    await getWorkflowFailedOperations(ct, storageAccountString);
        //}
        public static async Task getWorkflowFailedOperations(CancellationToken ct, string storageAccountString)
        {
            ButlerJob job             = new ButlerJob();
            var       pollingInterval = TimeSpan.FromSeconds(Configuration.FailedQueuePollingInterval);

            try
            {
                while (!ct.IsCancellationRequested)
                {
                    // Wake up and do some background processing if not canceled.
                    processMessageBack(storageAccountString, Configuration.ButlerFailedQueue, Configuration.WorkflowStatus.Failed);
                    // Go back to sleep for a period of time unless asked to cancel.
                    // Task.Delay will throw an OperationCanceledException when canceled.
                    await Task.Delay(pollingInterval, ct);
                }
            }
            catch (OperationCanceledException ocEx)
            {
                // Expect this exception to be thrown in normal circumstances or check
                // the cancellation token. If the role instances are shutting down, a
                // cancellation request will be signaled.
                Trace.TraceInformation("Stopping service, cancellation requested");

                // Re-throw the Operation cancellation exception
                throw ocEx;
            }
        }
        /// <summary>
        /// This needs to be called from an Azure Worker as it gets the connection string from the context
        /// </summary>
        /// <param name="j">Job to submit</param>
        /// <returns>the Guid of the JOB if submission was successful</returns>
        //public static Guid Submit(ButlerJob j)
        //{
        //    //string storageAccountString = CloudConfigurationManager.GetSetting(Configuration.ButlerStorageConnectionConfigurationKey);
        //    //string storageAccountString = CloudConfigurationManager.GetSetting(Configuration.ButlerStorageConnectionConfigurationKey);
        //    return Submit(j, storageAccountString);
        //}
        /// <summary>
        /// Submit this job to the Butler Request queue
        /// </summary>
        /// <param name="j">Job to submit</param>
        /// <returns>the Guid of the JOB if submission was successful</returns>
        public static Guid Submit(ButlerJob j, string storageAccountString)
        {
            CloudStorageAccount account         = CloudStorageAccount.Parse(storageAccountString);
            CloudQueueClient    sendQueueClient = account.CreateCloudQueueClient();

            try
            {
                CloudQueue sendQueue = sendQueueClient.GetQueueReference(Configuration.ButlerSendQueue);
                sendQueue.CreateIfNotExists();

                var message = new ButlerRequest
                {
                    MessageId               = j.JobId,
                    MezzanineFiles          = new List <string> {
                    },
                    StorageConnectionString = storageAccountString,
                    WorkflowName            = "",
                    TimeStampUTC            = String.Format("{0:o}", DateTime.Now.ToUniversalTime()),
                    ControlFileUri          = ""
                };
                if (j.JobMediaFiles.Count > 0)
                {
                    var blob = new CloudBlockBlob(j.JobMediaFiles[0]);
                    message.WorkflowName = blob.Container.Name;
                }
                foreach (Uri blobUri in j.JobMediaFiles)
                {
                    message.MezzanineFiles.Add(blobUri.ToString());
                }

                if (j.JobControlFile != null)
                {
                    message.ControlFileUri = j.JobControlFile.ToString();
                    if (message.WorkflowName == "")
                    {
                        //Process with only ControlFile
                        try
                        {
                            Uri controlUri = new Uri(message.ControlFileUri);
                            message.WorkflowName = controlUri.Segments[1].Substring(0, controlUri.Segments[1].Length - 1);
                        }
                        catch (Exception)
                        {
                        }
                    }
                }

                CloudQueueMessage butlerRequestMessage = new CloudQueueMessage(JsonConvert.SerializeObject(message));
                sendQueue.AddMessageAsync(butlerRequestMessage);
            }
            catch (Exception)
            {
                throw;
            }

            return(j.JobId);
        }
        /// <summary>
        /// Create a job object for a multipart job -- one that consists of
        /// multiple mezannine files.
        /// </summary>
        /// <param name="mediaAssets">The list of mezannine Assets</param>
        /// <param name="controlFile">Butler control file.</param>
        /// <returns>the new Butler job object</returns>
        public static ButlerJob CreateJob(IList <Uri> mediaAssets, Uri controlFile)
        {
            var b = new ButlerJob()
            {
                JobControlFile = controlFile,
                JobMediaFiles  = mediaAssets,
            };

            return(b);
        }
        /// <summary>
        /// Create a Butler job object for the case of a single mezannine
        /// file.  No control file provided.
        /// </summary>
        /// <param name="mediaAsset">The Uri of the single mezannine file (e.g.,
        /// for .../Incoming/myVid.mp4).</param>
        /// <returns></returns>
        public static ButlerJob CreateSimpleJob(Uri mediaAsset)
        {
            var b = new ButlerJob()
            {
                JobControlFile = null,
                JobMediaFiles  = new List <Uri>()
                {
                    mediaAsset
                }
            };

            return(b);
        }