Пример #1
0
        private void btnRun_Click(object sender, EventArgs e)
        {
            DataTableResponseMessage dtRespMsg = null;

            try
            {
                templateDataGridView.DataSource = null;
                ClearMessage();
                UserMessage("Running");
                ProcessorDTO proc = comboBox1.Items[comboBox1.SelectedIndex] as ProcessorDTO;
                txtID.Text       = proc.UniqueId;
                txtName.Text     = proc.Name;
                txtDesc.Text     = proc.Description;
                txtFileType.Text = proc.InstrumentFileType;

                ProcessorManager procMgr = new ProcessorManager();
                //string output = @"E:\lims\LIMSDesktop\bin\Debug\netcoreapp3.0\Processors\Output\file.csv";
                //string procPaths = @"E:\lims\lims_server\app_files\processors";
                dtRespMsg = procMgr.ExecuteProcessor(proc.Path, txtName.Text, txtInput.Text);
                GC.Collect();
                GC.WaitForPendingFinalizers();

                if (dtRespMsg == null)
                {
                    //dtRespMsg = new DataTableResponseMessage();
                    UserMessage(string.Format("Error processing file {0} with processor {1}", txtInput.Text, txtName.Text));
                    //dtRespMsg.ErrorMessage = string.Format("Error processing file {0} with processor {1}", txtInput.Text, txtName.Text);
                }
                if (dtRespMsg.ErrorMessage != null)
                {
                    LogMessage(dtRespMsg.ErrorMessage);
                }

                if (!string.IsNullOrWhiteSpace(dtRespMsg.LogMessage))
                {
                    LogMessage(dtRespMsg.LogMessage);
                }

                if (dtRespMsg.TemplateData != null)
                {
                    templateDataGridView.DataSource = dtRespMsg.TemplateData;
                    UserMessage("Success");
                }
            }
            catch (Exception ex)
            {
                LogMessage(string.Format("Error executing processor {0} with input {1}", txtID.Text, txtInput.Text));
                LogMessage($"Error: {ex.Message}");
                if (dtRespMsg != null && dtRespMsg.LogMessage != null)
                {
                    LogMessage(dtRespMsg.LogMessage);
                }
            }
        }
Пример #2
0
        public async System.Threading.Tasks.Task RunTask(string id)
        {
            var task = await _context.Tasks.SingleAsync(t => t.id == id);

            Log.Information("Executing Task. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}", task.workflowID, task.id, task.taskID);

            // Step 1: If status!="SCHEDULED" cancel task

            if (!task.status.Equals("SCHEDULED"))
            {
                Log.Information("Task Cancelled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Current Status: {3}, Message: {4}", task.workflowID, task.id, task.taskID, task.status, "Task status is not marked as schedulled.");
                await this.UpdateStatus(task.id, "CANCELLED", "Task status was set to: " + task.status);

                return;
            }
            // Step 2: Change status to "STARTING"
            await this.UpdateStatus(task.id, "STARTING", "");

            var workflow = await _context.Workflows.Where(w => w.id == task.workflowID).FirstOrDefaultAsync();

            if (workflow == null)
            {
                Log.Information("Task Cancelled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Message: {3}", task.workflowID, task.id, task.taskID, "Unable to find Workflow for the Task.");
                await this.UpdateStatus(task.id, "CANCELLED", "Error attempting to get workflow of this task. Workflow ID: " + task.workflowID);

                return;
            }

            // Step 3: Check source directory for files
            List <string> files          = new List <string>();
            string        dirFileMessage = "";

            if (new DirectoryInfo(@workflow.inputFolder).Exists)
            {
                files = Directory.GetFiles(@workflow.inputFolder).ToList();
            }
            else
            {
                dirFileMessage = String.Format("Input directory {0} not found", workflow.inputFolder);
                Log.Information(dirFileMessage);
            }
            // Step 4: If directory or files do not exist reschedule task
            if (files.Count == 0)
            {
                dirFileMessage = (dirFileMessage.Length > 0) ? dirFileMessage : String.Format("No files found in directory: {0}", workflow.inputFolder);
                await this.UpdateStatus(task.id, "SCHEDULED", dirFileMessage);

                var newSchedule = new Hangfire.States.ScheduledState(TimeSpan.FromMinutes(workflow.interval));
                task.start = DateTime.Now.AddMinutes(workflow.interval);
                await _context.SaveChangesAsync();

                try
                {
                    BackgroundJobClient backgroundClient = new BackgroundJobClient();
                    backgroundClient.ChangeState(task.taskID, newSchedule);
                    Log.Information("Task Rescheduled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Input Directory: {3}, Message: {4}", task.workflowID, task.id, task.taskID, workflow.inputFolder, "No files found in input directory.");
                }
                catch (Exception)
                {
                    Log.Warning("Error attempting to reschedule Hangfire job. Workflow ID: {0}, task ID: {1}", task.workflowID, task.id);
                }
                return;
            }

            // Step 5: If file does exist, update task inputFile then compare against previous Tasks.
            task.inputFile = files.First();
            task.status    = "PROCESSING";
            await _context.SaveChangesAsync();

            bool alreadyCompleted = await this.InputFileCheck(task.inputFile, task.workflowID);

            if (alreadyCompleted)
            {
                Log.Information("Hash input file match for WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Input File: {3}, Message: {4}", task.workflowID, task.id, task.taskID, task.inputFile, "Rerunning task after removing file.");
                try
                {
                    File.Delete(task.inputFile);
                    Log.Information("Hash input file match successfully deleted. WorkflowID: {0}, ID: {1}, Input File: {2}", task.workflowID, task.id, task.inputFile);
                }
                catch (FileNotFoundException ex)
                {
                    Log.Warning("Error unable to delete input file after hash file match with previous input file. Workflow ID: {0}, ID: {1}", task.workflowID, task.id);
                }

                string statusMessage = String.Format("Input file: {0} matches previously processed input file", task.inputFile);
                await this.UpdateStatus(task.id, "SCHEDULED", statusMessage);

                await this.RunTask(task.id);

                return;
            }


            ProcessorManager pm        = new ProcessorManager();
            string           config    = "./app_files/processors";
            ProcessorDTO     processor = pm.GetProcessors(config).Find(p => p.Name.ToLower() == workflow.processor.ToLower());

            if (processor == null)
            {
                Log.Information("Task Cancelled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Message: {3}, Processor: {4}", task.workflowID, task.id, task.taskID, "Unable to find Processor for the Task.", workflow.processor);
                await this.UpdateStatus(task.id, "CANCELLED", "Error, invalid processor name. Name: " + workflow.processor);

                return;
            }

            try
            {
                // Step 6: Run processor on source file
                if (!new DirectoryInfo(@workflow.outputFolder).Exists)
                {
                    Directory.CreateDirectory(@workflow.outputFolder);
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                Log.Warning("Task unable to create output directory, unauthorized access exception. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Output Directory: {3}", task.workflowID, task.id, task.taskID, workflow.outputFolder);
            }

            Dictionary <string, ResponseMessage> outputs = new Dictionary <string, ResponseMessage>();
            string file = task.inputFile;
            DataTableResponseMessage result = pm.ExecuteProcessor(processor.Path, processor.Name, file);

            GC.Collect();
            GC.WaitForPendingFinalizers();

            if (result.ErrorMessage == null && result.TemplateData != null)
            {
                var output = pm.WriteTemplateOutputFile(workflow.outputFolder, result.TemplateData);
                outputs.Add(file, output);
            }
            else
            {
                string errorMessage = "";
                string logMessage   = "";
                if (result.TemplateData == null)
                {
                    errorMessage = "Processor results template data is null. ";
                }
                if (result.ErrorMessage != null)
                {
                    errorMessage = errorMessage + result.ErrorMessage;
                    logMessage   = errorMessage;
                }
                if (result.LogMessage != null)
                {
                    logMessage = result.LogMessage;
                }
                await this.UpdateStatus(task.id, "CANCELLED", "Error processing data: " + errorMessage);

                Log.Information("Task Cancelled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Message: {3}", task.workflowID, task.id, task.taskID, logMessage);
                return;
            }

            // Step 7: Check if output file exists
            bool processed = false;

            for (int i = 0; i < outputs.Count; i++)
            {
                var    output     = outputs.ElementAt(i);
                string outputPath = output.Value.OutputFile;
                // Step 8: If output file does exist, update task outputFile and delete input file
                if (File.Exists(outputPath))
                {
                    processed = true;
                    string fileName  = System.IO.Path.GetFileName(output.Key);
                    string inputPath = System.IO.Path.Combine(workflow.inputFolder, fileName);

                    DataBackup dbBackup = new DataBackup();
                    dbBackup.DumpData(id, inputPath, outputPath);
                    try
                    {
                        File.Delete(inputPath);
                    }
                    catch (Exception ex)
                    {
                        Log.Warning("Error unable to delete input file after successful processing. Workflow ID: {0}, ID: {1}", task.workflowID, task.id);
                    }
                    task.outputFile = outputPath;
                    await _context.SaveChangesAsync();
                }
                else
                {
                    await this.UpdateStatus(task.id, "SCHEDULED", "Error unable to export output. Error Messages: " + output.Value.ErrorMessage);
                }
            }

            // Step 9: Change task status to COMPLETED
            // Step 10: Create new Task and schedule
            string newStatus = "";

            if (processed)
            {
                newStatus = "COMPLETED";
                Log.Information("Task Completed. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}", task.workflowID, task.id, task.taskID);
                try
                {
                    if (files.Count > 1)
                    {
                        await this.CreateNewTask(workflow.id, 0);
                    }
                    else
                    {
                        await this.CreateNewTask(workflow.id, workflow.interval);
                    }
                }
                catch (Exception)
                {
                    Log.Warning("Error creating new Hangfire job after successful job. Workflow ID: {0}, ID: {1}", task.workflowID, task.id);
                }
            }
            else
            {
                newStatus = "CANCELLED";
                Log.Information("Task Cancelled. WorkflowID: {0}, ID: {1}, Hangfire ID: {2}, Message: {3}", task.workflowID, task.id, task.taskID, "Failed to process input file.");
            }
            await this.UpdateStatus(task.id, newStatus);
        }