public Task <ExecutionResult> Action(CancellationToken cancellationToken)
        {
            var loadedProcessors = processorLoader.Load();
            var addedProcessors  = new List <IProcessor>();

            foreach (var loadedProcessor in loadedProcessors)
            {
                var isNew = processorDatabase.GetAll().All(processor => processor.DisplayName != loadedProcessor.DisplayName);
                if (!isNew)
                {
                    continue;
                }
                processorDatabase.Add(loadedProcessor);
                addedProcessors.Add(loadedProcessor);
            }
            if (!addedProcessors.Any())
            {
                return(Task.FromResult(new ExecutionResult(true, false, "No new processors found")));
            }

            var aggregatedProcessorDisplayNames = string.Join(", ", addedProcessors.Select(processor => processor.DisplayName));
            var summary = $"Added processors {aggregatedProcessorDisplayNames}";

            return(Task.FromResult(new ExecutionResult(true, true, summary)));
        }
        public DataProcessingServiceSetup(
            IDataApiClient dataApiClient,
            LoginInformation apiLoginInformation,
            NameValueCollection appSettings)
        {
            var authenticationResult = dataApiClient.Login(apiLoginInformation.Username, apiLoginInformation.Password);

            if (authenticationResult == null)
            {
                throw new Exception($"DataAPI-authentication result was null for user '{apiLoginInformation.Username}'");
            }
            if (!authenticationResult.IsAuthenticated)
            {
                throw new Exception("Could not log into Data API");
            }
            var dataProcessingServiceLogger = new DataProcessingServiceLogger(dataApiClient);

            try
            {
                var processorDefinitionDirectory = appSettings["ProcessorDefinitionDirectory"];
                var processorLoader = new ProcessorLoader(processorDefinitionDirectory);
                Processors = new List <IProcessor>
                {
                    new PostponedProcessingObjectUpdateProcessor(dataApiClient),
                    new DataServiceProcessor(dataApiClient)
                }.Concat(processorLoader.Load()).ToList();
                PostponedProcessingRunner = new PostponedProcessingRunner(
                    dataApiClient,
                    Processors,
                    dataProcessingServiceLogger);
                var processorDatabase = new ProcessorDatabase(Processors.Concat(new [] { PostponedProcessingRunner }));
                Distributor = new Distributor(
                    dataApiClient,
                    processorDatabase,
                    dataProcessingServiceLogger);


                var taskDefinitionDirectory = appSettings["TaskDefinitionDirectory"];
                var taskLoader   = new TaskLoader(taskDefinitionDirectory);
                var taskDatabase = new TaskDatabase();
                Tasks = new List <ITask>
                {
                    new LogTruncationTask(dataApiClient, TimeSpan.FromDays(3)),
                    new TaskLoadingTask(taskLoader, taskDatabase),
                    new ProcessorLoadingTask(processorLoader, processorDatabase),
                }.Concat(taskLoader.Load()).ToList();
                Tasks.ForEach(taskDatabase.Add);
                PeriodicTasksRunner = new PeriodicTasksRunner(
                    dataApiClient,
                    taskDatabase,
                    dataProcessingServiceLogger);
            }
            catch (Exception e)
            {
                dataProcessingServiceLogger.Log(
                    new DataProcessingServiceLog(
                        $"Startup of DataProcessing service failed: {e}",
                        new CrashLogEntryDetails("DataProcessingService", e.InnermostException().Message)))
                .Wait();
                throw;
            }
        }