private ProcessRequest restoreRequestOrCreateMetadata(ProcessRequest currentRequest, List <StepHandler> currentSteps) { Common.ResourceAccess.IButlerStorageManager storageManager = Common.ResourceAccess.BlobManagerFactory.CreateBlobManager(currentRequest.ProcessConfigConn); var processSnap = storageManager.readProcessSanpShot(currentRequest.ProcessTypeId, currentRequest.ProcessInstanceId); if (processSnap == null) { //First time Execution string workflowStepListData = Newtonsoft.Json.JsonConvert.SerializeObject(currentSteps); currentRequest.MetaData.Add(Configuration.workflowStepListKey, workflowStepListData); currentRequest.MetaData.Add(Configuration.workflowStepLength, currentSteps.Count.ToString()); } else { //Second or other time execution //load Metadata dynamic dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject((processSnap).jsonContext); //Dictionary<string, string> dynMetaData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>((dynObj.MetaData.ToString())); currentRequest.MetaData = Newtonsoft.Json.JsonConvert.DeserializeObject <Dictionary <string, string> >((dynObj.MetaData.ToString())); //load Errors currentRequest.Exceptions = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >((dynObj.Exceptions.ToString())); //Load LOGS Log currentRequest.Log = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >((dynObj.Log.ToString())); } return(currentRequest); }
/// <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); }
private void execute(CloudQueueMessage currentMessage) { ProcessRequest myRequest = null; string txt; Common.ResourceAccess.IButlerStorageManager storageManager = null; try { lock (myLock) { currentProcessRunning += 1; } MediaButler.Common.ButlerRequest watcherRequest = Newtonsoft.Json.JsonConvert.DeserializeObject <ButlerRequest>(currentMessage.AsString); //Load Workflow's steps List <StepHandler> mysteps = BuildChain(watcherRequest.WorkflowName); myRequest = GetCurrentContext(watcherRequest.WorkflowName); myRequest.CurrentMessage = currentMessage; myRequest.ProcessTypeId = watcherRequest.WorkflowName; //ProcessInstanceId: //Single File: MessageID Guid (random) //multiFile package: Container folder guid ID (set for client) myRequest.ProcessInstanceId = this.getProcessId(watcherRequest.ControlFileUri, watcherRequest.MessageId.ToString()); myRequest.ProcessConfigConn = this.myProcessConfigConn; myRequest.IsResumeable = (this.ReadConfigOrDefault(myRequest.ProcessTypeId + ".IsResumeable") == "1"); //Restore Status storageManager = Common.ResourceAccess.BlobManagerFactory.CreateBlobManager(myRequest.ProcessConfigConn); myRequest = restoreRequestOrCreateMetadata(myRequest, mysteps); //2.Execute Chain txt = string.Format("[{0}] Starting new Process, type {1} and ID {2}", this.GetType().FullName, myRequest.ProcessTypeId, myRequest.ProcessInstanceId); Trace.TraceInformation(txt); mysteps.FirstOrDefault().HandleRequest(myRequest); //FinishProcess(); txt = string.Format("[{0}] Finish Process, type {1} and ID {2}", this.GetType().FullName, myRequest.ProcessTypeId, myRequest.ProcessInstanceId); Trace.TraceInformation(txt); //Finish Status myRequest.CurrentStepIndex = Configuration.successFinishProcessStep; storageManager.PersistProcessStatus(myRequest); lock (myLock) { currentProcessRunning -= 1; } } catch (Exception xxx) { if (myRequest != null) { //foreach (Exception item in myRequest.Exceptions) foreach (string errorTxt in myRequest.Exceptions) { //Full Rollback? txt = string.Format("[{0}] Error list process {1} intance {2} error: {3}", this.GetType().FullName, myRequest.ProcessTypeId, myRequest.ProcessInstanceId, errorTxt); Trace.TraceError(txt); } txt = string.Format("[{0}] Error list process {1} intance {2} error: {3}", this.GetType().FullName, myRequest.ProcessTypeId, myRequest.ProcessInstanceId, xxx.Message); myRequest.Exceptions.Add(txt); //Update Status myRequest.CurrentStepIndex = Configuration.failFinishProcessStep; storageManager.PersistProcessStatus(myRequest); } else { txt = string.Format("[{0}] Error {1} without context Request yet", this.GetType().FullName, xxx.Message); Trace.TraceError(xxx.Message); } //Exception no Managed lock (myLock) { currentProcessRunning -= 1; } } //3.return control if (myRequest != null) { myRequest.DisposeRequest(); } else { Trace.TraceError("myRequest is null raw message " + currentMessage.AsString); } myRequest = null; Trace.Flush(); }