mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Added IRecipeResultAccessor for programmatically obtaining result of recipe execution.
This commit is contained in:
@@ -5,5 +5,5 @@ Website: http://orchardproject.net
|
|||||||
Version: 1.9.1
|
Version: 1.9.1
|
||||||
OrchardVersion: 1.9
|
OrchardVersion: 1.9
|
||||||
Description: The dashboard module is providing the reports screen of the application.
|
Description: The dashboard module is providing the reports screen of the application.
|
||||||
FeatureDescription: Reports management (deprecated).
|
FeatureDescription: Reports management.
|
||||||
Category: Core
|
Category: Core
|
||||||
|
|||||||
@@ -16,15 +16,18 @@ namespace Orchard.ImportExport.Controllers {
|
|||||||
private readonly IImportExportService _importExportService;
|
private readonly IImportExportService _importExportService;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly ICustomExportStep _customExportStep;
|
private readonly ICustomExportStep _customExportStep;
|
||||||
|
private readonly IRecipeResultAccessor _recipeResultAccessor;
|
||||||
|
|
||||||
public AdminController(
|
public AdminController(
|
||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
IImportExportService importExportService,
|
IImportExportService importExportService,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
ICustomExportStep customExportStep) {
|
ICustomExportStep customExportStep,
|
||||||
|
IRecipeResultAccessor recipeResultAccessor) {
|
||||||
_importExportService = importExportService;
|
_importExportService = importExportService;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_customExportStep = customExportStep;
|
_customExportStep = customExportStep;
|
||||||
|
_recipeResultAccessor = recipeResultAccessor;
|
||||||
Services = services;
|
Services = services;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
}
|
}
|
||||||
@@ -50,11 +53,22 @@ namespace Orchard.ImportExport.Controllers {
|
|||||||
|
|
||||||
if (ModelState.IsValid) {
|
if (ModelState.IsValid) {
|
||||||
var executionId = _importExportService.Import(new StreamReader(Request.Files["RecipeFile"].InputStream).ReadToEnd());
|
var executionId = _importExportService.Import(new StreamReader(Request.Files["RecipeFile"].InputStream).ReadToEnd());
|
||||||
// TODO: Figure out how to report the result. Probably add notifications from the actual import and then redirect to another action, which will display those notifications.
|
return RedirectToAction("ImportResult", new { executionId = executionId });
|
||||||
}
|
}
|
||||||
|
|
||||||
return View(new ImportViewModel());
|
return View(new ImportViewModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ActionResult ImportResult(string executionId) {
|
||||||
|
var result = _recipeResultAccessor.GetResult(executionId);
|
||||||
|
|
||||||
|
var viewModel = new ImportResultViewModel() {
|
||||||
|
Result = result
|
||||||
|
};
|
||||||
|
|
||||||
|
return View(viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResult Export() {
|
public ActionResult Export() {
|
||||||
var customSteps = new List<string>();
|
var customSteps = new List<string>();
|
||||||
_customExportStep.Register(customSteps);
|
_customExportStep.Register(customSteps);
|
||||||
@@ -96,6 +110,7 @@ namespace Orchard.ImportExport.Controllers {
|
|||||||
exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true);
|
exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true);
|
||||||
}
|
}
|
||||||
var exportFilePath = _importExportService.Export(contentTypesToExport, exportOptions);
|
var exportFilePath = _importExportService.Export(contentTypesToExport, exportOptions);
|
||||||
|
|
||||||
return File(exportFilePath, "text/xml", "export.xml");
|
return File(exportFilePath, "text/xml", "export.xml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@
|
|||||||
<Compile Include="Services\IImportExportService.cs" />
|
<Compile Include="Services\IImportExportService.cs" />
|
||||||
<Compile Include="Services\ImportExportService.cs" />
|
<Compile Include="Services\ImportExportService.cs" />
|
||||||
<Compile Include="ViewModels\ExportViewModel.cs" />
|
<Compile Include="ViewModels\ExportViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\ImportResultViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ImportViewModel.cs" />
|
<Compile Include="ViewModels\ImportViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -109,7 +110,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\Admin\Export.cshtml" />
|
<Content Include="Views\Admin\Export.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\Admin\ImportResult.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class ImportResultViewModel {
|
||||||
|
public RecipeResult Result { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
@model Orchard.ImportExport.ViewModels.ImportResultViewModel
|
||||||
|
@{
|
||||||
|
Layout.Title = T("Import Result").ToString();
|
||||||
|
}
|
||||||
|
@if (Model.Result.IsSuccessful) {
|
||||||
|
<div class="message message-Information">
|
||||||
|
@T("The recipe file was successfully imported.")
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<div class="message message-Error">
|
||||||
|
@T("The recipe file import failed. Check the logs (recipe execution ID <strong>{0}</strong>) for more information.", Model.Result.ExecutionId)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<h2>@T("Recipe steps")</h2>
|
||||||
|
<table class="items" style="width: auto;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>@T("Step")</th>
|
||||||
|
<th>@T("Executed")</th>
|
||||||
|
<th>@T("Result")</th>
|
||||||
|
<th>@T("Message")</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var step in Model.Result.Steps) {
|
||||||
|
<tr>
|
||||||
|
<td>@step.StepName</td>
|
||||||
|
<td>@step.IsCompleted</td>
|
||||||
|
<td>@if (step.IsSuccessful) { @T("Successful") } else if (step.IsCompleted) { <strong>@T("Failed")</strong> }</td>
|
||||||
|
<td><strong>@step.ErrorMessage</strong></td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
32
src/Orchard.Web/Modules/Orchard.Recipes/Migrations.cs
Normal file
32
src/Orchard.Web/Modules/Orchard.Recipes/Migrations.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Orchard.Data.Migration;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes {
|
||||||
|
public class Migrations : DataMigrationImpl {
|
||||||
|
public int Create() {
|
||||||
|
//SchemaBuilder.CreateTable("RecipeResultRecord", table => table
|
||||||
|
// .Column<int>("Id", c => c.PrimaryKey().Identity())
|
||||||
|
// .Column<string>("ExecutionId", c => c.WithLength(128).Unique().NotNull())
|
||||||
|
// .Column<bool>("IsCompleted", c => c.NotNull())
|
||||||
|
//);
|
||||||
|
|
||||||
|
SchemaBuilder.CreateTable("RecipeStepResultRecord", table => table
|
||||||
|
.Column<int>("Id", c => c.PrimaryKey().Identity())
|
||||||
|
.Column<string>("ExecutionId", c => c.WithLength(128).NotNull())
|
||||||
|
.Column<string>("StepName", c => c.WithLength(256).NotNull())
|
||||||
|
.Column<bool>("IsCompleted", c => c.NotNull())
|
||||||
|
.Column<bool>("IsSuccessful", c => c.NotNull())
|
||||||
|
.Column<string>("ErrorMessage", c => c.Unlimited().Nullable())
|
||||||
|
);
|
||||||
|
|
||||||
|
SchemaBuilder.AlterTable("RecipeStepResultRecord", table => table
|
||||||
|
.CreateIndex("IDX_RecipeStepResultRecord_ExecutionId", "ExecutionId")
|
||||||
|
);
|
||||||
|
|
||||||
|
SchemaBuilder.AlterTable("RecipeStepResultRecord", table => table
|
||||||
|
.CreateIndex("IDX_RecipeStepResultRecord_ExecutionId_StepName", "ExecutionId", "StepName")
|
||||||
|
);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
//namespace Orchard.Recipes.Models {
|
||||||
|
// public class RecipeResultRecord {
|
||||||
|
// public virtual int Id { get; set; }
|
||||||
|
// public virtual string ExecutionId { get; set; }
|
||||||
|
// public virtual bool IsCompleted { get; set; }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Orchard.Recipes.Models {
|
||||||
|
public class RecipeStepResultRecord {
|
||||||
|
public virtual int Id { get; set; }
|
||||||
|
public virtual string ExecutionId { get; set; }
|
||||||
|
public virtual string StepName { get; set; }
|
||||||
|
public virtual bool IsCompleted { get; set; }
|
||||||
|
public virtual bool IsSuccessful { get; set; }
|
||||||
|
public virtual string ErrorMessage { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,6 +72,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Commands\RecipesCommands.cs" />
|
<Compile Include="Commands\RecipesCommands.cs" />
|
||||||
|
<Compile Include="Migrations.cs" />
|
||||||
|
<Compile Include="Models\RecipeResultRecord.cs" />
|
||||||
|
<Compile Include="Models\RecipeStepResultRecord.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
|
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
|
||||||
<Compile Include="RecipeHandlers\DataRecipeHandler.cs" />
|
<Compile Include="RecipeHandlers\DataRecipeHandler.cs" />
|
||||||
@@ -85,6 +88,7 @@
|
|||||||
<Compile Include="Services\RecipeHarvester.cs" />
|
<Compile Include="Services\RecipeHarvester.cs" />
|
||||||
<Compile Include="Services\RecipeManager.cs" />
|
<Compile Include="Services\RecipeManager.cs" />
|
||||||
<Compile Include="Services\RecipeParser.cs" />
|
<Compile Include="Services\RecipeParser.cs" />
|
||||||
|
<Compile Include="Services\RecipeResultAccessor.cs" />
|
||||||
<Compile Include="Services\RecipeScheduler.cs" />
|
<Compile Include="Services\RecipeScheduler.cs" />
|
||||||
<Compile Include="Services\RecipeStepExecutor.cs" />
|
<Compile Include="Services\RecipeStepExecutor.cs" />
|
||||||
<Compile Include="Services\RecipeStepQueue.cs" />
|
<Compile Include="Services\RecipeStepQueue.cs" />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Orchard.Data;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.Recipes.Events;
|
using Orchard.Recipes.Events;
|
||||||
@@ -9,14 +10,17 @@ namespace Orchard.Recipes.Services {
|
|||||||
private readonly IRecipeStepQueue _recipeStepQueue;
|
private readonly IRecipeStepQueue _recipeStepQueue;
|
||||||
private readonly IRecipeScheduler _recipeScheduler;
|
private readonly IRecipeScheduler _recipeScheduler;
|
||||||
private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler;
|
private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler;
|
||||||
|
private readonly IRepository<RecipeStepResultRecord> _recipeStepResultRecordRepository;
|
||||||
|
|
||||||
public RecipeManager(
|
public RecipeManager(
|
||||||
IRecipeStepQueue recipeStepQueue,
|
IRecipeStepQueue recipeStepQueue,
|
||||||
IRecipeScheduler recipeScheduler,
|
IRecipeScheduler recipeScheduler,
|
||||||
IRecipeExecuteEventHandler recipeExecuteEventHandler) {
|
IRecipeExecuteEventHandler recipeExecuteEventHandler,
|
||||||
|
IRepository<RecipeStepResultRecord> recipeStepResultRecordRepository) {
|
||||||
_recipeStepQueue = recipeStepQueue;
|
_recipeStepQueue = recipeStepQueue;
|
||||||
_recipeScheduler = recipeScheduler;
|
_recipeScheduler = recipeScheduler;
|
||||||
_recipeExecuteEventHandler = recipeExecuteEventHandler;
|
_recipeExecuteEventHandler = recipeExecuteEventHandler;
|
||||||
|
_recipeStepResultRecordRepository = recipeStepResultRecordRepository;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -35,6 +39,10 @@ namespace Orchard.Recipes.Services {
|
|||||||
|
|
||||||
foreach (var recipeStep in recipe.RecipeSteps) {
|
foreach (var recipeStep in recipe.RecipeSteps) {
|
||||||
_recipeStepQueue.Enqueue(executionId, recipeStep);
|
_recipeStepQueue.Enqueue(executionId, recipeStep);
|
||||||
|
_recipeStepResultRecordRepository.Create(new RecipeStepResultRecord() {
|
||||||
|
ExecutionId = executionId,
|
||||||
|
StepName = recipeStep.Name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_recipeScheduler.ScheduleWork(executionId);
|
_recipeScheduler.ScheduleWork(executionId);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.Data;
|
||||||
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Services {
|
||||||
|
public class RecipeResultAccessor : IRecipeResultAccessor {
|
||||||
|
private readonly IRepository<RecipeStepResultRecord> _recipeStepResultRecordRepository;
|
||||||
|
|
||||||
|
public RecipeResultAccessor(IRepository<RecipeStepResultRecord> recipeStepResultRecordRepository) {
|
||||||
|
_recipeStepResultRecordRepository = recipeStepResultRecordRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecipeResult GetResult(string executionId) {
|
||||||
|
var query =
|
||||||
|
from record in _recipeStepResultRecordRepository.Table
|
||||||
|
where record.ExecutionId == executionId
|
||||||
|
select record;
|
||||||
|
|
||||||
|
var records = query.ToArray();
|
||||||
|
|
||||||
|
if (!records.Any())
|
||||||
|
throw new Exception(String.Format("No records were found in the database for recipe execution ID {0}.", executionId));
|
||||||
|
|
||||||
|
var result = new RecipeResult() {
|
||||||
|
ExecutionId = executionId,
|
||||||
|
Steps =
|
||||||
|
from record in records
|
||||||
|
select new RecipeStepResult() {
|
||||||
|
StepName = record.StepName,
|
||||||
|
IsCompleted = record.IsCompleted,
|
||||||
|
IsSuccessful = record.IsSuccessful,
|
||||||
|
ErrorMessage = record.ErrorMessage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.Data;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.Recipes.Events;
|
using Orchard.Recipes.Events;
|
||||||
@@ -10,14 +12,17 @@ namespace Orchard.Recipes.Services {
|
|||||||
private readonly IRecipeStepQueue _recipeStepQueue;
|
private readonly IRecipeStepQueue _recipeStepQueue;
|
||||||
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
|
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
|
||||||
private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler;
|
private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler;
|
||||||
|
private readonly IRepository<RecipeStepResultRecord> _recipeStepResultRecordRepository;
|
||||||
|
|
||||||
public RecipeStepExecutor(
|
public RecipeStepExecutor(
|
||||||
IRecipeStepQueue recipeStepQueue,
|
IRecipeStepQueue recipeStepQueue,
|
||||||
IEnumerable<IRecipeHandler> recipeHandlers,
|
IEnumerable<IRecipeHandler> recipeHandlers,
|
||||||
IRecipeExecuteEventHandler recipeExecuteEventHandler) {
|
IRecipeExecuteEventHandler recipeExecuteEventHandler,
|
||||||
|
IRepository<RecipeStepResultRecord> recipeStepResultRecordRepository) {
|
||||||
_recipeStepQueue = recipeStepQueue;
|
_recipeStepQueue = recipeStepQueue;
|
||||||
_recipeHandlers = recipeHandlers;
|
_recipeHandlers = recipeHandlers;
|
||||||
_recipeExecuteEventHandler = recipeExecuteEventHandler;
|
_recipeExecuteEventHandler = recipeExecuteEventHandler;
|
||||||
|
_recipeStepResultRecordRepository = recipeStepResultRecordRepository;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -33,19 +38,24 @@ namespace Orchard.Recipes.Services {
|
|||||||
_recipeExecuteEventHandler.ExecutionComplete(executionId);
|
_recipeExecuteEventHandler.ExecutionComplete(executionId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Information("Running all recipe handlers for step '{0}'.", nextRecipeStep.Name);
|
Logger.Information("Running all recipe handlers for step '{0}'.", nextRecipeStep.Name);
|
||||||
|
|
||||||
var recipeContext = new RecipeContext { RecipeStep = nextRecipeStep, Executed = false, ExecutionId = executionId };
|
var recipeContext = new RecipeContext { RecipeStep = nextRecipeStep, Executed = false, ExecutionId = executionId };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_recipeExecuteEventHandler.RecipeStepExecuting(executionId, recipeContext);
|
_recipeExecuteEventHandler.RecipeStepExecuting(executionId, recipeContext);
|
||||||
foreach (var recipeHandler in _recipeHandlers) {
|
foreach (var recipeHandler in _recipeHandlers) {
|
||||||
recipeHandler.ExecuteRecipeStep(recipeContext);
|
recipeHandler.ExecuteRecipeStep(recipeContext);
|
||||||
}
|
}
|
||||||
|
UpdateStepResultRecord(executionId, nextRecipeStep.Name, isSuccessful: true);
|
||||||
_recipeExecuteEventHandler.RecipeStepExecuted(executionId, recipeContext);
|
_recipeExecuteEventHandler.RecipeStepExecuted(executionId, recipeContext);
|
||||||
}
|
}
|
||||||
catch (Exception exception) {
|
catch (Exception ex) {
|
||||||
Logger.Error(exception, "Recipe execution {0} failed because the step '{1}' failed.", executionId, nextRecipeStep.Name);
|
UpdateStepResultRecord(executionId, nextRecipeStep.Name, isSuccessful: false, errorMessage: ex.Message);
|
||||||
|
Logger.Error(ex, "Recipe execution {0} failed because the step '{1}' failed.", executionId, nextRecipeStep.Name);
|
||||||
while (_recipeStepQueue.Dequeue(executionId) != null);
|
while (_recipeStepQueue.Dequeue(executionId) != null);
|
||||||
var message = T("Recipe execution with ID {0} failed because the step '{1}' failed to execute. The following exception was thrown:\n{2}\nRefer to the error logs for more information.", executionId, nextRecipeStep.Name, exception.Message);
|
var message = T("Recipe execution with ID {0} failed because the step '{1}' failed to execute. The following exception was thrown:\n{2}\nRefer to the error logs for more information.", executionId, nextRecipeStep.Name, ex.Message);
|
||||||
throw new OrchardCoreException(message);
|
throw new OrchardCoreException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,5 +68,20 @@ namespace Orchard.Recipes.Services {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateStepResultRecord(string executionId, string stepName, bool isSuccessful, string errorMessage = null) {
|
||||||
|
var query =
|
||||||
|
from record in _recipeStepResultRecordRepository.Table
|
||||||
|
where record.ExecutionId == executionId && record.StepName == stepName
|
||||||
|
select record;
|
||||||
|
|
||||||
|
var stepResultRecord = query.Single();
|
||||||
|
|
||||||
|
stepResultRecord.IsCompleted = true;
|
||||||
|
stepResultRecord.IsSuccessful = isSuccessful;
|
||||||
|
stepResultRecord.ErrorMessage = errorMessage;
|
||||||
|
|
||||||
|
_recipeStepResultRecordRepository.Update(stepResultRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,9 @@
|
|||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Recipes\Models\RecipeResult.cs" />
|
||||||
|
<Compile Include="Recipes\Models\RecipeStepResult.cs" />
|
||||||
|
<Compile Include="Recipes\Services\IRecipeResultAccessor.cs" />
|
||||||
<Compile Include="Reports\Report.cs" />
|
<Compile Include="Reports\Report.cs" />
|
||||||
<Compile Include="Reports\ReportEntry.cs" />
|
<Compile Include="Reports\ReportEntry.cs" />
|
||||||
<Compile Include="Reports\ReportExtentions.cs" />
|
<Compile Include="Reports\ReportExtentions.cs" />
|
||||||
|
|||||||
19
src/Orchard/Recipes/Models/RecipeResult.cs
Normal file
19
src/Orchard/Recipes/Models/RecipeResult.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Models {
|
||||||
|
public class RecipeResult {
|
||||||
|
public string ExecutionId { get; set; }
|
||||||
|
public IEnumerable<RecipeStepResult> Steps { get; set; }
|
||||||
|
public bool IsCompleted {
|
||||||
|
get {
|
||||||
|
return Steps.All(s => s.IsCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsSuccessful {
|
||||||
|
get {
|
||||||
|
return IsCompleted && Steps.All(s => s.IsSuccessful);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/Orchard/Recipes/Models/RecipeStepResult.cs
Normal file
10
src/Orchard/Recipes/Models/RecipeStepResult.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Models {
|
||||||
|
public class RecipeStepResult {
|
||||||
|
public string StepName { get; set; }
|
||||||
|
public bool IsCompleted { get; set; }
|
||||||
|
public bool IsSuccessful { get; set; }
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/Orchard/Recipes/Services/IRecipeResultAccessor.cs
Normal file
10
src/Orchard/Recipes/Services/IRecipeResultAccessor.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Services {
|
||||||
|
/// <summary>
|
||||||
|
/// Provides information about the result of recipe execution.
|
||||||
|
/// </summary>
|
||||||
|
public interface IRecipeResultAccessor : IDependency {
|
||||||
|
RecipeResult GetResult(string executionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user