public async Task <IActionResult> Details(string id, string returnUrl, CancellationToken cancellationToken) { var instance = await workflowInstanceStore.GetByIdAsync(id, cancellationToken); if (instance == null) { return(NotFound()); } var definition = await workflowDefinitionStore.GetByIdAsync( instance.DefinitionId, VersionOptions.SpecificVersion(instance.Version), cancellationToken ); var workflow = new WorkflowModel { Activities = definition.Activities.Select(x => CreateActivityModel(x, instance)).ToList(), Connections = definition.Connections.Select(x => new ConnectionModel(x)).ToList() }; var model = new WorkflowInstanceDetailsModel( instance, definition, workflow, options.Value.ActivityDefinitions, returnUrl); return(View("Details", model)); }
public async Task <WorkflowDefinitionVersion> UpdateAsync(WorkflowDefinitionVersion definition, CancellationToken cancellationToken) { var existingDefinition = await GetByIdAsync(definition.Id, VersionOptions.SpecificVersion(definition.Version), cancellationToken); var index = definitions.IndexOf(existingDefinition); definitions[index] = definition; return(definition); }
public async Task AddAsync(WorkflowDefinitionVersion definition, CancellationToken cancellationToken = default) { var existingDefinition = await GetByIdAsync(definition.Id, VersionOptions.SpecificVersion(definition.Version), cancellationToken); if (existingDefinition != null) { throw new ArgumentException($"A workflow definition with ID '{definition.Id}' and version '{definition.Version}' already exists."); } definitions.Add(definition); }
public async Task <WorkflowExecutionContext> ResumeAsync( WorkflowInstance workflowInstance, Variables input = null, IEnumerable <string> startActivityIds = default, CancellationToken cancellationToken = default) { var definition = await workflowRegistry.GetWorkflowDefinitionAsync( workflowInstance.DefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); var workflow = workflowFactory.CreateWorkflow(definition, input, workflowInstance); return(await ResumeAsync(workflow, startActivityIds, cancellationToken)); }
public async Task <RunWorkflowResult> ResumeWorkflowAsync(WorkflowInstance workflowInstance, string?activityId = default, object?input = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync( workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); if (workflowBlueprint == null) { throw new WorkflowException($"Workflow instance {workflowInstance.Id} references workflow definition {workflowInstance.DefinitionId} version {workflowInstance.Version}, but no such workflow definition was found."); } return(await _workflowRunner.RunWorkflowAsync(workflowBlueprint, workflowInstance, activityId, input, cancellationToken)); }
public async Task <WorkflowDefinitionVersion> SaveAsync(WorkflowDefinitionVersion definition, CancellationToken cancellationToken = default) { var existingDefinition = await GetByIdAsync(definition.Id, VersionOptions.SpecificVersion(definition.Version), cancellationToken); if (existingDefinition == null) { await AddAsync(definition, cancellationToken); } else { await UpdateAsync(definition, cancellationToken); } return(definition); }
public async Task <WorkflowDefinitionVersion> UpdateAsync( WorkflowDefinitionVersion definition, CancellationToken cancellationToken) { var query = session .Query <WorkflowDefinitionVersionDocument, WorkflowDefinitionIndex>() .Where(x => x.WorkflowDefinitionId == definition.DefinitionId) .WithVersion(VersionOptions.SpecificVersion(definition.Version)); var document = await query.FirstOrDefaultAsync(); document = mapper.Map(definition, document); session.Save(document); await session.CommitAsync(); return(mapper.Map <WorkflowDefinitionVersion>(document)); }
public async Task <RunWorkflowResult?> FindAndRestartTestWorkflowAsync( string workflowDefinitionId, string activityId, int version, string signalRConnectionId, string lastWorkflowInstanceId, string?tenantId = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.FindAsync(workflowDefinitionId, VersionOptions.SpecificVersion(version), tenantId, cancellationToken); if (workflowBlueprint == null) { return(null); } var lastWorkflowInstance = await _workflowInstanceStore.FindAsync(new EntityIdSpecification <WorkflowInstance>(lastWorkflowInstanceId), cancellationToken); if (lastWorkflowInstance == null) { return(null); } var startActivity = workflowBlueprint.Activities.First(x => x.Id == activityId); var startableWorkflowDefinition = new StartableWorkflowDefinition(workflowBlueprint, startActivity.Id); var workflow = await InstantiateStartableWorkflow(startableWorkflowDefinition, cancellationToken); var previousActivityData = GetActivityDataFromLastWorkflowInstance(lastWorkflowInstance, workflowBlueprint, activityId); MergeActivityDataIntoInstance(workflow.WorkflowInstance, previousActivityData); SetMetadata(workflow.WorkflowInstance, signalRConnectionId); //if previousActivityOutput has any items, then the first one is from activity closest to the starting one var previousActivityOutput = previousActivityData.Count == 0 ? null : previousActivityData.First().Value?.GetItem("Output"); return(await ExecuteStartableWorkflowAsync(workflow, new WorkflowInput(previousActivityOutput), cancellationToken)); }
public async Task <StartableWorkflow?> FindStartableWorkflowAsync( string workflowDefinitionId, int version, string?activityId, string?correlationId = default, string?contextId = default, string?tenantId = default, CancellationToken cancellationToken = default) { var workflowBlueprint = await _workflowRegistry.GetAsync(workflowDefinitionId, tenantId, VersionOptions.SpecificVersion(version), cancellationToken); if (workflowBlueprint == null || workflowBlueprint.IsDisabled) { return(null); } return(await FindStartableWorkflowAsync(workflowBlueprint, activityId, correlationId, contextId, tenantId, cancellationToken)); }
public async Task DispatchAsync(ExecuteWorkflowInstanceRequest request, CancellationToken cancellationToken = default) { var workflowInstance = await _workflowInstanceStore.FindByIdAsync(request.WorkflowInstanceId, cancellationToken); if (workflowInstance == null) { _logger.LogWarning("Cannot dispatch a workflow instance ID that does not exist"); return; } var workflowBlueprint = await _workflowRegistry.FindAsync(workflowInstance.DefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), workflowInstance.TenantId, cancellationToken); if (workflowBlueprint == null) { _logger.LogWarning("Workflow instance {WorkflowInstanceId} references workflow blueprint {WorkflowDefinitionId} with version {Version}, but could not be found", workflowInstance.Id, workflowInstance.DefinitionId, workflowInstance.Version); return; } var channel = _workflowChannelOptions.GetChannelOrDefault(workflowBlueprint.Channel); var queue = ServiceBusOptions.FormatChannelQueueName <ExecuteWorkflowInstanceRequest>(channel); await _commandSender.SendAsync(request, queue, cancellationToken : cancellationToken); }
private async Task <ScheduledActivity> GetActivityToScheduleAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken) { var currentActivity = workflowInstance.CurrentActivity; if (currentActivity != null) { return(currentActivity); } var workflowBlueprint = await _workflowRegistry.GetWorkflowAsync(workflowInstance.DefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); if (workflowBlueprint == null) { throw new WorkflowException($"Could not find associated workflow definition {workflowInstance.DefinitionId} with version {workflowInstance.Version}"); } var startActivity = _startingActivitiesProvider.GetStartActivities(workflowBlueprint).FirstOrDefault(); if (startActivity == null) { throw new WorkflowException($"Cannot revive workflow {workflowInstance.Id} because it has no start activities"); } return(new ScheduledActivity(startActivity.Id)); }
private async Task <IWorkflowBlueprint?> GetWorkflowBlueprintAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken) => await _workflowRegistry.GetAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);