public async Task <string> SubmitJob(Common.Entities.Job newJob, string batchId = "")
        {
            var webApiCallUrl = string.Format(string.Concat(_baseUrl, _submitJobUrl), batchId);
            var jobPostResp   = await _httpClient.PostAsync <Job>
                                (
                webApiCallUrl,
                newJob,
                new JsonMediaTypeFormatter()
                                );

            jobPostResp.EnsureSuccessStatusCode();
            var jobId = await jobPostResp.Content.ReadAsAsync <string>();

            return(jobId);
        }
Example #2
0
        public Common.JobProcessResult DoWork(Common.Entities.Job job, string jobPackagePath, string jobWorkingPath, Action <string> progressCallback)
        {
            //
            // Initialize the job
            //
            InitalizeBasics(jobPackagePath, jobWorkingPath);

            //
            // Process the actual job
            //
            ProcessJob(job, _localTemporaryPath);

            //
            // Return the result
            //
            return(new JobProcessResult()
            {
                Output = "succeeded procesing image " + job.Parameters,
                Status = Common.Entities.JobStatus.Finished
            });
        }
Example #3
0
        /// <summary>
        /// Calls the Geres job Worker Process executable and passes the job entity to it
        /// </summary>
        public Common.JobProcessResult DoWork(Common.Entities.Job job, string jobPackagePath, string jobWorkingPath, Action <string> progressCallback)
        {
            var errorMessages = string.Empty;
            var logMessages   = string.Empty;

            //
            // At the starting point, the job has not been cancelled
            //
            _hasBeenCancelled = false;

            //
            // Parameter validations
            //
            if (_executionContext == null)
            {
                throw new InvalidOperationException("Execution context for JobWorkerProcessImplementation is not set correctly!");
            }

            //
            // Copy the worker process files to the job-directory
            //
            var workerProcPath = string.Empty;
            var roleRootPath   = Environment.GetEnvironmentVariable("RoleRoot");

            try
            {
                // Note: in the local emulator, RoleRoot did not have approot in it while in the cloud it did.
                if (roleRootPath[roleRootPath.Length - 1] != '\\')
                {
                    roleRootPath += @"\";
                }
                workerProcPath = Path.Combine(roleRootPath, "approot", "wp");
                foreach (var fileToCopy in Directory.GetFiles(workerProcPath))
                {
                    File.Copy(fileToCopy, Path.Combine(jobPackagePath, Path.GetFileName(fileToCopy)), true);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Unable to copy worker process files to job target directory. Parameters: " +
                                                  "RoleRoot={0}, JobRootPath={1}, Exception Message={2}", roleRootPath, jobPackagePath, ex.Message), ex);
            }

            //
            // First of all write the job file to the filesystem (use XML since it does not require any further dependencies)
            //
            var jobFileName = Path.Combine(jobPackagePath, JobWorkerProcessConstants.JOB_XML_FILE);

            try
            {
                using (var jobStream = new FileStream(jobFileName, FileMode.Create))
                {
                    _jobXmlSerializer.Serialize(jobStream, job);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Unable to serialize job file {0} for passing to job worker process due to exception: {1}!", job.JobId, ex.Message), ex);
            }

            //
            // Now call the executable with the username
            //
            try
            {
                // Compile the start info and make sure stdout and stderr are redirected
                // Note: we assume that we read from stdout, only, in our "private protocol" to reduce complexity of
                //       potenital deadlocks as described here: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx
                _geresWorkerProcessPath = Path.Combine(jobPackagePath, JobWorkerProcessConstants.JOB_WORKERPROC_EXENAME);
                var workerProcessStartInfo = new ProcessStartInfo()
                {
                    FileName               = _geresWorkerProcessPath,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    WorkingDirectory       = jobWorkingPath,
                    LoadUserProfile        = false,
                    CreateNoWindow         = true
                };
                // Set the user name and the password if the tenant manager is configured in a way to execute the process under different credentials
                if (_executionContext.ExecutionAsUserName != null && _executionContext.ExecutionAsUserPassword != null)
                {
                    workerProcessStartInfo.UserName = _executionContext.ExecutionAsUserName;
                    workerProcessStartInfo.Password = _executionContext.ExecutionAsUserPassword;
                }
                // Had to clear environment variables since they were pointing to the "calling users" home directory
                if (workerProcessStartInfo.EnvironmentVariables.ContainsKey("homepath"))
                {
                    workerProcessStartInfo.EnvironmentVariables.Remove("homepath");
                    workerProcessStartInfo.EnvironmentVariables.Add("homepath", jobWorkingPath);
                }
                // Add environmentvariables for the job execution context (path information) for the worker process
                workerProcessStartInfo.EnvironmentVariables.Add(JobWorkerProcessConstants.JOB_ENVIRONMENT_EXEC_PATH, jobPackagePath);
                workerProcessStartInfo.EnvironmentVariables.Add(JobWorkerProcessConstants.JOB_ENVIRONMENT_WORK_PATH, jobWorkingPath);

                //
                // Now start the worker process executable
                //
                _currentWorkerProcess = Process.Start(workerProcessStartInfo);

                //
                // Create the asynchronous tasks to wait for the process, stderr, stdout
                //
                var processWaiter = Task.Run(() => _currentWorkerProcess.WaitForExit());
                _stdOutTask = Task.Run(() =>
                {
                    var msg = string.Empty;
                    do
                    {
                        msg = _currentWorkerProcess.StandardOutput.ReadLine();
                        ProcessConsoleMessage(progressCallback, msg, ref logMessages);
                    } while (!_currentWorkerProcess.HasExited);

                    do
                    {
                        msg = _currentWorkerProcess.StandardOutput.ReadLine();
                        ProcessConsoleMessage(progressCallback, msg, ref logMessages);
                    } while (!string.IsNullOrEmpty(msg));
                });
                _stdErrTask = Task.Run(() =>
                {
                    errorMessages = _currentWorkerProcess.StandardError.ReadToEnd();
                });

                //
                // Wait until stdout and stderr have completly read and the process did exit
                //
                Task.WaitAll(processWaiter, _stdOutTask, _stdErrTask);

                //
                // Compose the job output results
                //
                var outputString = logMessages;
                if (!string.IsNullOrEmpty(errorMessages))
                {
                    outputString = string.Concat(outputString, Environment.NewLine, "--ERRORS--", Environment.NewLine, errorMessages);
                }

                //
                // Try get the job result from the exit code
                //
                Geres.Common.Entities.JobStatus statusFromExitCode = Common.Entities.JobStatus.Finished;
                try
                {
                    statusFromExitCode = (Geres.Common.Entities.JobStatus)_currentWorkerProcess.ExitCode;
                }
                catch
                {
                    statusFromExitCode = Common.Entities.JobStatus.Aborted;
                }

                //
                // If the job has been cancelled, the status should be cancelled
                //
                if (_hasBeenCancelled)
                {
                    statusFromExitCode = Common.Entities.JobStatus.Cancelled;
                }

                //
                // Finally return the result
                //
                return(new Common.JobProcessResult()
                {
                    Output = outputString,
                    Status = statusFromExitCode
                });
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Failed calling the GERES job worker process due to the following reason: {0}!", ex.Message), ex);
            }
        }
 public IJobImplementation Lookup(Common.Entities.Job job)
 {
     return(new JobWorkerProcessImplementation());
 }
Example #5
0
        private void ProcessJob(Common.Entities.Job jobDetails, string localTempPath)
        {
            //
            // Temporary files used for processing by the legacy app
            //
            var sourceFileName = Path.Combine(localTempPath, "source_" + jobDetails.JobId);
            var targetFileName = Path.Combine(localTempPath, "result_" + jobDetails.JobId);

            try
            {
                //
                // Parse the parameters passed in for the job
                //
                var parametersFromJob        = jobDetails.Parameters.Split('|');
                var storageAccountConnString = parametersFromJob[0];
                var sourceBlobContainerName  = parametersFromJob[1];
                var sourceImageName          = parametersFromJob[2];
                var targetBlobContainerName  = parametersFromJob[3];

                //
                // Create the storage account proxies used for downloading and uploading the image
                //
                var storageAccount = CloudStorageAccount.Parse(storageAccountConnString);
                var blobClient     = storageAccount.CreateCloudBlobClient();

                //
                // Next download the source image to the local directory
                //
                var blobSourceContainer = blobClient.GetContainerReference(sourceBlobContainerName);
                var sourceImage         = blobSourceContainer.GetBlobReferenceFromServer(sourceImageName);
                sourceImage.DownloadToFile(sourceFileName, FileMode.Create);

                //
                // Then execute the legacy application for creating the thumbnail
                //
                _runningApp = Process.Start
                              (
                    _legacyAppExecutable,
                    string.Format("\"{0}\" \"{1}\" Custom 100 100", sourceFileName, targetFileName)
                              );
                // You should set a timeout to wait for the external process and kill if timeout exceeded
                _runningApp.WaitForExit();

                //
                // Evaluate the result of execution and throw exception on failure
                //
                if (_runningApp.ExitCode != 0)
                {
                    var errorMessage = string.Format("Legacy app did exit with code {0}, processing failed!", _runningApp.ExitCode);
                    Console.WriteLine(errorMessage, "Warning");
                    throw new Exception(errorMessage);
                }

                //
                // Processing succeeded, Now upload the result file to blob storage and update the jobs table
                //
                using (FileStream resultFile = new FileStream(targetFileName, FileMode.Open))
                {
                    var blobContainer = blobClient.GetContainerReference(targetBlobContainerName);
                    blobContainer.CreateIfNotExists();

                    // Save it to the targetBlobContainerName with the same name as the original one
                    var blob = blobContainer.GetBlockBlobReference(sourceImageName);

                    // Upload the resulting file to the blob storage
                    blob.UploadFromStream(resultFile);
                }
            }
            finally
            {
                //
                // No app is running anymore
                //
                try
                {
                    _runningApp.Dispose();
                }
                catch { }
                _runningApp = null;

                //
                // Deletes all temporary files that have been created as part of processing
                // It would also be good to run that time-controlled in regular intervals in case of this fails
                //
                TryCleanUpTempFiles(sourceFileName, targetFileName);
            }
        }