コード例 #1
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;
            }
        }
コード例 #2
0
ファイル: RecipeExecutor.cs プロジェクト: bpun/Orchard2
        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;
            }
        }
コード例 #3
0
ファイル: RecipeExecutor.cs プロジェクト: LongBaoLee/Orchard2
        public async Task <string> ExecuteAsync(string executionId, RecipeDescriptor recipeDescriptor)
        {
            await _eventBus.NotifyAsync <IRecipeEventHandler>(x => x.RecipeExecutingAsync(executionId, recipeDescriptor));

            try
            {
                RecipeResult result = new RecipeResult {
                    ExecutionId = executionId
                };
                List <RecipeStepResult> stepResults = new List <RecipeStepResult>();

                using (StreamReader file = File.OpenText(recipeDescriptor.RecipeFileInfo.PhysicalPath))
                {
                    using (var reader = new JsonTextReader(file))
                    {
                        VariablesMethodProvider variablesMethodProvider = null;

                        // 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)
                            {
                                int stepId = 0;
                                while (reader.Read() && reader.Depth > 1)
                                {
                                    if (reader.Depth == 2)
                                    {
                                        var child = JToken.Load(reader);

                                        var recipeStep = new RecipeStepDescriptor
                                        {
                                            Id   = (stepId++).ToString(),
                                            Name = child.Value <string>("name"),
                                            Step = child
                                        };

                                        var shellContext = _orchardHost.GetOrCreateShellContext(_shellSettings);
                                        using (var scope = shellContext.CreateServiceScope())
                                        {
                                            if (!shellContext.IsActivated)
                                            {
                                                var eventBus = scope.ServiceProvider.GetService <IEventBus>();
                                                await eventBus.NotifyAsync <IOrchardShellEvents>(x => x.ActivatingAsync());

                                                await eventBus.NotifyAsync <IOrchardShellEvents>(x => x.ActivatedAsync());

                                                shellContext.IsActivated = true;
                                            }

                                            var recipeStepExecutor = scope.ServiceProvider.GetRequiredService <IRecipeStepExecutor>();
                                            var scriptingManager   = scope.ServiceProvider.GetRequiredService <IScriptingManager>();

                                            if (variablesMethodProvider != null)
                                            {
                                                variablesMethodProvider.ScriptingManager = scriptingManager;
                                                scriptingManager.GlobalMethodProviders.Add(variablesMethodProvider);
                                            }

                                            if (_applicationLifetime.ApplicationStopping.IsCancellationRequested)
                                            {
                                                throw new OrchardException(T["Recipe cancelled, application is restarting"]);
                                            }

                                            EvaluateJsonTree(scriptingManager, recipeStep.Step);

                                            await recipeStepExecutor.ExecuteAsync(executionId, recipeStep);
                                        }

                                        // The recipe execution might have invalidated the shell by enabling new features,
                                        // so the deferred tasks need to run on an updated shell context if necessary.
                                        shellContext = _orchardHost.GetOrCreateShellContext(_shellSettings);
                                        using (var scope = shellContext.CreateServiceScope())
                                        {
                                            var recipeStepExecutor = scope.ServiceProvider.GetRequiredService <IRecipeStepExecutor>();

                                            var deferredTaskEngine = scope.ServiceProvider.GetService <IDeferredTaskEngine>();

                                            // The recipe might have added some deferred tasks to process
                                            if (deferredTaskEngine != null && deferredTaskEngine.HasPendingTasks)
                                            {
                                                var taskContext = new DeferredTaskContext(scope.ServiceProvider);
                                                await deferredTaskEngine.ExecuteTasksAsync(taskContext);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

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

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

                throw;
            }
        }