public DistributeFileResult DistributeFile(DistributionFile distributionFile)
        {
            string errorMessage = null;

            try
            {
                Configuration configuration = Configuration.Read();
                Group         group         = configuration.Groups.FirstOrDefault(x => x.ID == distributionFile.DestinationGroupID);

                if (group == null)
                {
                    Logger.AddAndThrow <DistributeFileException>(LogType.Error, $"Could not find group with ID {distributionFile.DestinationGroupID}");
                }

                string filePath = Path.Combine(group.Path, distributionFile.RelativePath.Trim(Path.DirectorySeparatorChar));

                try
                {
                    FileSystemHandler.PutFileContent(filePath, distributionFile.Content);
                }
                catch (Exception ex)
                {
                    Logger.AddAndThrow <DistributeFileException>($"Failed to persist file content of {filePath}", ex);
                }
            }
            catch (DistributeFileException ex)
            {
                errorMessage = ex.Message;
            }

            return(new DistributeFileResult(distributionFile.RelativePath, distributionFile.DestinationGroupID, errorMessage));
        }
 public static void Stop(Group group, Application application)
 {
     foreach (Process process in GetProcesses(group, application))
     {
         try
         {
             process.Kill();
         }
         catch (Exception ex)
         {
             Logger.AddAndThrow <ProcessActionException>($"Failed to kill process with path {process.GetPathName()}", ex);
         }
     }
 }
        public ProcessActionResult TakeProcessAction(Guid groupID, Guid applicationID, ActionType type)
        {
            string errorMessage = null;

            try
            {
                Configuration configuration = Configuration.Read();
                Group         group         = configuration.Groups.FirstOrDefault(x => x.ID == groupID);
                Application   application   = configuration.Applications.FirstOrDefault(x => x.ID == applicationID);

                if (group == null)
                {
                    Logger.AddAndThrow <ProcessActionException>(LogType.Error, $"Application {type}: Could not find group with ID {groupID}");
                }

                if (application == null)
                {
                    Logger.AddAndThrow <ProcessActionException>(LogType.Error, $"Application {type}: Could not find application with ID {applicationID}");
                }

                switch (type)
                {
                case ActionType.Start:
                    ProcessHandler.Start(group, application);
                    break;

                case ActionType.Stop:
                    ProcessHandler.Stop(group, application);
                    break;

                case ActionType.Restart:
                    ProcessHandler.Restart(group, application);
                    break;

                default:
                    Logger.AddAndThrow <ProcessActionException>(LogType.Error, $"Process action type invalid: {type}");
                    break;
                }
            }
            catch (ProcessActionException ex)
            {
                errorMessage = ex.Message;
            }

            return(new ProcessActionResult(type, errorMessage,
                                           _processStatuses.ContainsKey(groupID) && _processStatuses[groupID].ContainsKey(applicationID) ? _processStatuses[groupID][applicationID] : null));
        }
        public DistributionActionResult TakeDistributionAction(string sourceMachineHostName, Guid groupID, Guid applicationID,
                                                               string destinationMachineHostName, ActionType type, Guid clientId)
        {
            string errorMessage = null;

            try
            {
                Configuration configuration = Configuration.Read();
                Group         group         = configuration.Groups.FirstOrDefault(x => x.ID == groupID);
                Application   application   = configuration.Applications.FirstOrDefault(x => x.ID == applicationID);

                if (string.IsNullOrEmpty(sourceMachineHostName))
                {
                    Logger.AddAndThrow <DistributionActionException>(LogType.Error, $"Application {type}: Missing source machine host name");
                }

                if (group == null)
                {
                    Logger.AddAndThrow <DistributionActionException>(LogType.Error, $"Application {type}: Could not find group with ID {groupID}");
                }

                if (application == null)
                {
                    Logger.AddAndThrow <DistributionActionException>(LogType.Error, $"Application {type}: Could not find application with ID {applicationID}");
                }

                if (string.IsNullOrEmpty(destinationMachineHostName))
                {
                    Logger.AddAndThrow <DistributionActionException>(LogType.Error, $"Application {type}: Missing destination machine host name");
                }

                DistributionWorker.Instance.AddWork(new DistributionWork(type, new Machine(sourceMachineHostName), group, application, new Machine(destinationMachineHostName), clientId));
            }
            catch (DistributionActionException ex)
            {
                errorMessage = ex.Message;
            }

            return(new DistributionActionResult(type, errorMessage));
        }
Beispiel #5
0
        private void DistributeSourceFilesThread(Machine machine)
        {
            List <DistributionWork> processedDistributionWork = new List <DistributionWork>();

            while (ConnectionStore.ConnectionCreated(machine))
            {
                DistributionWork work;

                lock (_pendingDistributionWork)
                {
                    work = _pendingDistributionWork
                           .Where(pendingWork => Comparer.MachinesEqual(pendingWork.DestinationMachine, machine))
                           .FirstOrDefault(pendingWork => !processedDistributionWork.Contains(pendingWork));
                }

                if (work == null)
                {
                    Thread.Sleep(10);
                    continue;
                }

                processedDistributionWork.Add(work);

                Task.Run(() =>
                {
                    try
                    {
                        try
                        {
                            Group destinationGroup = ConnectionStore.Connections[work.DestinationMachine].Configuration.Groups
                                                     .FirstOrDefault(group => Comparer.GroupsEqual(group, work.Group));

                            if (destinationGroup == null)
                            {
                                Logger.AddAndThrow <DistributionActionException>(LogType.Warning, $"Could not distribute application {work.Application.Name} in group {work.Group.Name}" +
                                                                                 $" to destination machine {work.DestinationMachine.HostName}. Destination machine does not contain a matching group.");
                            }

                            List <string> errorMessages = new List <string>();
                            foreach (DistributionFile file in work.Files)
                            {
                                file.DestinationGroupID = destinationGroup.ID;
                                file.Content            = FileSystemHandler.GetFileContent(Path.Combine(work.Group.Path, file.RelativePath.Trim(Path.DirectorySeparatorChar)));

                                DistributeFileResult result = ConnectionStore.Connections[work.DestinationMachine].ServiceHandler.Service.DistributeFile(new DTODistributionFile(file)).FromDTO();

                                try
                                {
                                    if (result.Success)
                                    {
                                        Logger.Add(LogType.Verbose, $"Distribution of file to {work.DestinationMachine.HostName} succeeded: {file.RelativePath}, {file.Content.Length} bytes");
                                    }
                                    else
                                    {
                                        Logger.AddAndThrow <DistributionActionException>(LogType.Error, $"Distribution of file to {work.DestinationMachine.HostName} failed: {Path.GetFileName(file.RelativePath)} | {result.ErrorMessage}");
                                    }
                                }
                                catch (DistributionActionException ex)
                                {
                                    errorMessages.Add(ex.Message);
                                }

                                file.IsDistributed = true;
                            }

                            if (errorMessages.Any())
                            {
                                throw new DistributionActionException(string.Join(Environment.NewLine, errorMessages.Select(x => x.Replace(" | ", Environment.NewLine + "\t"))));
                            }

                            RaiseDistributionCompletedEvent(new DistributionResult(work, DistributionResultValue.Success), work.ClientId);
                        }
                        catch (DistributionActionException) { throw; }
                        catch (ThreadAbortException) { }
                        catch (Exception ex)
                        {
                            Logger.AddAndThrow <DistributionActionException>("An unexpected error occurred while distributing source files, aborting..", ex);
                        }
                        finally
                        {
                            lock (_pendingDistributionWork)
                                _pendingDistributionWork.Remove(work);
                        }
                    }
                    catch (DistributionActionException ex)
                    {
                        RaiseDistributionCompletedEvent(new DistributionResult(work, DistributionResultValue.Failure, ex.Message), work.ClientId);
                    }
                });
            }
        }
        private static void Start(Group group, Application application, bool waitUntilStopped)
        {
            if (waitUntilStopped)
            {
                WaitForProcessToTerminate(group, application);
            }

            if (ProcessExists(group, application))
            {
                throw new ProcessActionException("Could not start process as it is already running");
            }

            string  fullPath = Path.Combine(group.Path, application.RelativePath.TrimStart('\\'));
            Process process  = new Process()
            {
                StartInfo = { FileName = fullPath, Arguments = application.Arguments }
            };

            try
            {
                process.Start();
            }
            catch (Exception ex)
            {
                Logger.AddAndThrow <ProcessActionException>($"Failed to start process with path {fullPath}", ex);
            }

            if (!application.WaitForExit)
            {
                return;
            }

            if (process.WaitForExit(WAIT_FOR_EXIT_TIMEOUT))
            {
                switch (application.SuccessExitCode)
                {
                case SuccessExitCode.Zero:
                    if (process.ExitCode != 0)
                    {
                        throw new ProcessActionException($"Process exit code was {process.ExitCode} (expected zero)");
                    }
                    break;

                case SuccessExitCode.Positive:
                    if (process.ExitCode < 0)
                    {
                        throw new ProcessActionException($"Process exit code was {process.ExitCode} (expected positive)");
                    }
                    break;

                case SuccessExitCode.Negative:
                    if (process.ExitCode >= 0)
                    {
                        throw new ProcessActionException($"Process exit code was {process.ExitCode} (expected negative)");
                    }
                    break;
                }
            }
            else
            {
                throw new ProcessActionException($"Process did not exit within {WAIT_FOR_EXIT_TIMEOUT} milliseconds");
            }
        }