/// <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> /// Send back to watcher a "Posion messsage" and delete from in queue /// </summary> /// <param name="poisonMessage">the poison message</param> /// <returns>Sueccess or not</returns> private bool SendPoisonMessage(CloudQueueMessage poisonMessage) { bool sw = false; try { CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_Configuration.ProcessConfigConn); CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CloudQueue poisonQueue = queueClient.GetQueueReference(_Configuration.poisonQueue); poisonQueue.CreateIfNotExists(); Common.ResourceAccess.IButlerStorageManager storageManager = Common.ResourceAccess.BlobManagerFactory.CreateBlobManager(_Configuration.ProcessConfigConn); //1. Create Butler Response ButlerRequest myButlerRequest = Newtonsoft.Json.JsonConvert.DeserializeObject <ButlerRequest>(poisonMessage.AsString); ButlerResponse myButlerResponse = new Common.ButlerResponse(); myButlerResponse.MezzanineFiles = myButlerRequest.MezzanineFiles; ////Add to Mezzamine Files the control File URL if it exist //Becouse it is needed to move/delete the control file from processing to succes or fail if (!string.IsNullOrEmpty(myButlerRequest.ControlFileUri)) { myButlerResponse.MezzanineFiles.Add(myButlerRequest.ControlFileUri); } myButlerResponse.TimeStampProcessingCompleted = DateTime.Now.ToString(); myButlerResponse.TimeStampProcessingStarted = DateTime.Now.ToString(); myButlerResponse.WorkflowName = myButlerRequest.WorkflowName; myButlerResponse.MessageId = myButlerRequest.MessageId; myButlerResponse.TimeStampRequestSubmitted = myButlerRequest.TimeStampUTC; myButlerResponse.StorageConnectionString = myButlerRequest.StorageConnectionString; myButlerResponse.Log = "Poison Message"; //2. Lookin for Errors in Table Status string processId = myProcessHandler.getProcessId(myButlerRequest.ControlFileUri, myButlerRequest.MessageId.ToString()); var processSnap = storageManager.readProcessSanpShot(myButlerRequest.WorkflowName, processId); if (processSnap != null) { //2.1 Load Erros dynamic dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject((processSnap).jsonContext); var errorList = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >((dynObj.Exceptions.ToString())); foreach (var errorTxt in errorList) { myButlerResponse.Log += "\r\n" + errorTxt; } //2.2 Update status processSnap.CurrentStep = Configuration.poisonFinishProcessStep; storageManager.PersistProcessStatus(processSnap); } else { //No process execution, fatal error //Update satus no process Status workflow.ProcessSnapShot psPoison = new workflow.ProcessSnapShot(myButlerResponse.WorkflowName, processId); psPoison.CurrentStep = Configuration.workflowFatalError; storageManager.PersistProcessStatus(psPoison); } //3. Send Poison Mesagge CloudQueueMessage poison = new CloudQueueMessage(Newtonsoft.Json.JsonConvert.SerializeObject(myButlerResponse)); poisonQueue.AddMessage(poison); sw = true; //4. Send On Error HTTP Callback Notification try { var StorageManager = ResourceAccess.BlobManagerFactory.CreateBlobManager(_Configuration.ProcessConfigConn); string jsonProcessConfiguration = StorageManager.GetButlerConfigurationValue( ProcessConfigKeys.DefualtPartitionKey, myButlerRequest.WorkflowName + ".config"); var processConfiguration = new ResourceAccess.jsonKeyValue(jsonProcessConfiguration); if (processConfiguration.Read(ProcessConfigKeys.MediaButlerHostHttpCallBackOnError) != "") { //POST string url = processConfiguration.Read(ProcessConfigKeys.MediaButlerHostHttpCallBackOnError); using (var client = new HttpClient()) { var content = new StringContent( StorageManager.readProcessSanpShot(myButlerRequest.WorkflowName, processId).jsonContext, Encoding.UTF8, "application/json"); var result = client.PostAsync(url, content).Result; Trace.TraceInformation("Http Post Notification Result: " + result.ToString()); } } } catch (Exception X) { Trace.TraceError("HTTP CALLBACK ERROR " + X.Message); } } catch (Exception X) { string txt = string.Format("[{0}] at {1} has an error: {2}", this.GetType().FullName, "GetNewMessage", X.Message); Trace.TraceError(txt); } return(sw); }