private async Task ParseStepsAsync( Stream stream, RecipeDescriptor descriptor, Func<RecipeDescriptor, RecipeStepDescriptor, Task> stepActionAsync) { var serializer = new JsonSerializer(); StreamReader streamReader = new StreamReader(stream); JsonTextReader reader = new JsonTextReader(streamReader); // Go to Steps, then iterate. while (reader.Read()) { 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); await stepActionAsync(descriptor, new RecipeStepDescriptor { Id = (stepId++).ToString(CultureInfo.InvariantCulture), RecipeName = descriptor.Name, Name = child.Value<string>("name"), Step = child }); } } } } }
public async Task<string> ExecuteAsync(string executionId, RecipeDescriptor recipeDescriptor) { await _eventBus.NotifyAsync<IRecipeEventHandler>(x => x.RecipeExecutingAsync(executionId, recipeDescriptor)); try { using (var stream = _fileSystem.GetFileInfo(recipeDescriptor.Location).CreateReadStream()) { RecipeResult result = new RecipeResult { ExecutionId = executionId }; List<RecipeStepResult> stepResults = new List<RecipeStepResult>(); await _recipeParser.ProcessRecipeAsync(stream, (recipe, recipeStep) => { // TODO, create Result prior to run stepResults.Add(new RecipeStepResult { ExecutionId = executionId, RecipeName = recipeDescriptor.Name, StepId = recipeStep.Id, StepName = recipeStep.Name }); return Task.CompletedTask; }); result.Steps = stepResults; _session.Save(result); } using (var stream = _fileSystem.GetFileInfo(recipeDescriptor.Location).CreateReadStream()) { await _recipeParser.ProcessRecipeAsync(stream, async (recipe, recipeStep) => { 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>(); if (_applicationLifetime.ApplicationStopping.IsCancellationRequested) { throw new OrchardException(T["Recipe cancelled, application is restarting"]); } await recipeStepExecutor.ExecuteAsync(executionId, recipeStep); } }); } await _eventBus.NotifyAsync<IRecipeEventHandler>(x => x.RecipeExecutedAsync(executionId, recipeDescriptor)); return executionId; } catch (Exception) { await _eventBus.NotifyAsync<IRecipeEventHandler>(x => x.ExecutionFailedAsync(executionId, recipeDescriptor)); throw; } }
public async Task<string> ExecuteAsync(string executionId, RecipeDescriptor recipeDescriptor) { await _eventBus.NotifyAsync<IRecipeEventHandler>(x => x.RecipeExecutingAsync(executionId, recipeDescriptor)); try { var fileInfo = _fileSystem.GetFileInfo(recipeDescriptor.Location); var parsersForFileExtension = _recipeOptions .RecipeFileExtensions .Where(rfx => Path.GetExtension(rfx.Key) == Path.GetExtension(fileInfo.PhysicalPath)); using (var stream = fileInfo.CreateReadStream()) { RecipeResult result = new RecipeResult { ExecutionId = executionId }; List<RecipeStepResult> stepResults = new List<RecipeStepResult>(); foreach (var parserForFileExtension in parsersForFileExtension) { var recipeParser = _recipeParsers.First(x => x.GetType() == parserForFileExtension.Value); await recipeParser.ProcessRecipeAsync(stream, (recipe, recipeStep) => { // TODO, create Result prior to run stepResults.Add(new RecipeStepResult { ExecutionId = executionId, RecipeName = recipeDescriptor.Name, StepId = recipeStep.Id, StepName = recipeStep.Name }); return Task.CompletedTask; }); } result.Steps = stepResults; _session.Save(result); } using (var stream = fileInfo.CreateReadStream()) { foreach (var parserForFileExtension in parsersForFileExtension) { var recipeParser = _recipeParsers.First(x => x.GetType() == parserForFileExtension.Value); await recipeParser.ProcessRecipeAsync(stream, async (recipe, recipeStep) => { 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>(); if (_applicationLifetime.ApplicationStopping.IsCancellationRequested) { throw new OrchardException(T["Recipe cancelled, application is restarting"]); } 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 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; } }