Esempio n. 1
0
        public async Task <string> ExecuteAsync(string executionId, RecipeDescriptor recipeDescriptor, object environment)
        {
            await _eventBus.NotifyAsync <IRecipeEventHandler>(x => x.RecipeExecutingAsync(executionId, recipeDescriptor));

            try
            {
                _environmentMethodProvider = new ParametersMethodProvider(environment);

                var result = new RecipeResult {
                    ExecutionId = executionId
                };

                await _recipeStore.CreateAsync(result);

                using (StreamReader file = File.OpenText(recipeDescriptor.RecipeFileInfo.PhysicalPath))
                {
                    using (var reader = new JsonTextReader(file))
                    {
                        // Go to Steps, then iterate.
                        while (reader.Read())
                        {
                            if (reader.Path == "variables")
                            {
                                reader.Read();

                                var variables = JObject.Load(reader);
                                _variablesMethodProvider = new VariablesMethodProvider(variables);
                            }

                            if (reader.Path == "steps" && reader.TokenType == JsonToken.StartArray)
                            {
                                while (reader.Read() && reader.Depth > 1)
                                {
                                    if (reader.Depth == 2)
                                    {
                                        var child = JObject.Load(reader);

                                        var recipeStep = new RecipeExecutionContext
                                        {
                                            Name        = child.Value <string>("name"),
                                            Step        = child,
                                            ExecutionId = executionId,
                                            Environment = environment
                                        };

                                        var stepResult = new RecipeStepResult {
                                            StepName = recipeStep.Name
                                        };
                                        result.Steps.Add(stepResult);
                                        await _recipeStore.UpdateAsync(result);

                                        ExceptionDispatchInfo capturedException = null;
                                        try
                                        {
                                            await ExecuteStepAsync(recipeStep);

                                            stepResult.IsSuccessful = true;
                                        }
                                        catch (Exception e)
                                        {
                                            stepResult.IsSuccessful = false;
                                            stepResult.ErrorMessage = e.ToString();

                                            // Because we can't do some async processing the in catch or finally
                                            // blocks, we store the exception to throw it later.

                                            capturedException = ExceptionDispatchInfo.Capture(e);
                                        }

                                        stepResult.IsCompleted = true;
                                        await _recipeStore.UpdateAsync(result);

                                        if (stepResult.IsSuccessful == false)
                                        {
                                            capturedException.Throw();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                await _eventBus.NotifyAsync <IRecipeEventHandler>(x => x.RecipeExecutedAsync(executionId, recipeDescriptor));

                return(executionId);
            }
            catch (Exception)
            {
                await _eventBus.NotifyAsync <IRecipeEventHandler>(x => x.ExecutionFailedAsync(executionId, recipeDescriptor));

                throw;
            }
        }
Esempio n. 2
0
        public async Task <string> ExecuteAsync(string executionId, RecipeDescriptor recipeDescriptor, object environment, CancellationToken cancellationToken)
        {
            await _recipeEventHandlers.InvokeAsync((handler, executionId, recipeDescriptor) => handler.RecipeExecutingAsync(executionId, recipeDescriptor), executionId, recipeDescriptor, _logger);

            try
            {
                _environmentMethodProvider   = new ParametersMethodProvider(environment);
                _configurationMethodProvider = new ConfigurationMethodProvider(_shellSettings.ShellConfiguration);

                var result = new RecipeResult {
                    ExecutionId = executionId
                };

                using (var stream = recipeDescriptor.RecipeFileInfo.CreateReadStream())
                {
                    using (var file = new StreamReader(stream))
                    {
                        using (var reader = new JsonTextReader(file))
                        {
                            // Go to Steps, then iterate.
                            while (await reader.ReadAsync())
                            {
                                if (reader.Path == "variables")
                                {
                                    await reader.ReadAsync();

                                    var variables = await JObject.LoadAsync(reader);

                                    _variablesMethodProvider = new VariablesMethodProvider(variables);
                                }

                                if (reader.Path == "steps" && reader.TokenType == JsonToken.StartArray)
                                {
                                    while (await reader.ReadAsync() && reader.Depth > 1)
                                    {
                                        if (reader.Depth == 2)
                                        {
                                            var child = await JObject.LoadAsync(reader);

                                            var recipeStep = new RecipeExecutionContext
                                            {
                                                Name             = child.Value <string>("name"),
                                                Step             = child,
                                                ExecutionId      = executionId,
                                                Environment      = environment,
                                                RecipeDescriptor = recipeDescriptor
                                            };

                                            if (cancellationToken.IsCancellationRequested)
                                            {
                                                _logger.LogError("Recipe interrupted by cancellation token.");
                                                return(null);
                                            }

                                            var stepResult = new RecipeStepResult {
                                                StepName = recipeStep.Name
                                            };
                                            result.Steps.Add(stepResult);

                                            ExceptionDispatchInfo capturedException = null;
                                            try
                                            {
                                                await ExecuteStepAsync(recipeStep);

                                                stepResult.IsSuccessful = true;
                                            }
                                            catch (Exception e)
                                            {
                                                stepResult.IsSuccessful = false;
                                                stepResult.ErrorMessage = e.ToString();

                                                // Because we can't do some async processing the in catch or finally
                                                // blocks, we store the exception to throw it later.

                                                capturedException = ExceptionDispatchInfo.Capture(e);
                                            }

                                            stepResult.IsCompleted = true;

                                            if (stepResult.IsSuccessful == false)
                                            {
                                                capturedException.Throw();
                                            }

                                            if (recipeStep.InnerRecipes != null)
                                            {
                                                foreach (var descriptor in recipeStep.InnerRecipes)
                                                {
                                                    var innerExecutionId = Guid.NewGuid().ToString();
                                                    await ExecuteAsync(innerExecutionId, descriptor, environment, cancellationToken);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                await _recipeEventHandlers.InvokeAsync((handler, executionId, recipeDescriptor) => handler.RecipeExecutedAsync(executionId, recipeDescriptor), executionId, recipeDescriptor, _logger);

                return(executionId);
            }
            catch (Exception)
            {
                await _recipeEventHandlers.InvokeAsync((handler, executionId, recipeDescriptor) => handler.ExecutionFailedAsync(executionId, recipeDescriptor), executionId, recipeDescriptor, _logger);

                throw;
            }
        }