protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity) { if (contextActivity == null) { throw new ArgumentNullException("contextActivity"); } ValidationErrorCollection errors = new ValidationErrorCollection(); CompositeActivity ownerActivity = contextActivity.TraverseDottedPathFromRoot(this.OwnerActivityDottedPath) as CompositeActivity; if (ownerActivity != null && WorkflowChanges.IsActivityExecutable(ownerActivity)) { foreach (Validator validator in ComponentDispenser.CreateComponents(ownerActivity.GetType(), typeof(ActivityValidatorAttribute))) { ValidationError error = validator.ValidateActivityChange(ownerActivity, this); if (error != null) { errors.Add(error); } } } return(errors); }
private void NotifyChangesCompletedToChildExecutors(IWorkflowCoreRuntime workflowCoreRuntime, Activity contextActivity) { Queue compositeActivities = new Queue(); compositeActivities.Enqueue(contextActivity); while (compositeActivities.Count > 0) { CompositeActivity compositeActivity = compositeActivities.Dequeue() as CompositeActivity; if (compositeActivity == null || !WorkflowChanges.IsActivityExecutable(compositeActivity)) { continue; } ISupportWorkflowChanges compositeActivityExecutor = ActivityExecutors.GetActivityExecutor(compositeActivity) as ISupportWorkflowChanges; if (compositeActivityExecutor != null) { using (workflowCoreRuntime.SetCurrentActivity(compositeActivity)) { using (ActivityExecutionContext executionContext = new ActivityExecutionContext(compositeActivity)) compositeActivityExecutor.OnWorkflowChangesCompleted(executionContext); } } foreach (Activity activity in compositeActivity.Activities) { if (activity is CompositeActivity) { compositeActivities.Enqueue(activity); } } } }
private void OnAddApprovalStep(object sender, EventArgs e) { InvokeWorkflowActivity invokeApprovalStepWorkflow = new InvokeWorkflowActivity(); // // use WorkflowChanges class to author dynamic change // WorkflowChanges changes = new WorkflowChanges(this); // // setup to invoke ApprovalStepWorkflow type Type type = typeof(ApprovalStepWorkflow); invokeApprovalStepWorkflow.Name = "AddApprovalStepWorkflow"; invokeApprovalStepWorkflow.TargetWorkflow = type; // // insert invokeApprovalStepWorkflow in ifElseApproval transient activity collection // CompositeActivity checkApproval = changes.TransientWorkflow.Activities["CheckApproval"] as CompositeActivity; CompositeActivity approvedBranch = checkApproval.Activities["Approved"] as CompositeActivity; approvedBranch.Activities.Add(invokeApprovalStepWorkflow); // // apply transient changes to instance // this.ApplyWorkflowChanges(changes); Console.WriteLine(" Added an InvokeWorkflow activity within the workflow to approve the PO"); }
public void ApplyWorkflowChanges(WorkflowChanges workflowChanges) { using (new WorkflowTraceTransfer(this.InstanceId)) { WorkflowExecutor executor; Label_000C: executor = this._runtime.Load(this); if (!executor.IsInstanceValid) { goto Label_000C; } try { executor.ApplyWorkflowChanges(workflowChanges); } catch (InvalidOperationException) { if (executor.IsInstanceValid) { throw; } goto Label_000C; } } }
protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity) { ValidationErrorCollection errors = base.ValidateChanges(contextActivity); Activity removedActivityInContext = contextActivity.TraverseDottedPathFromRoot(this.originalRemovedActivity.DottedPath); if (WorkflowChanges.IsActivityExecutable(removedActivityInContext) && removedActivityInContext.ExecutionStatus == ActivityExecutionStatus.Executing) { errors.Add(new ValidationError(SR.GetString(SR.Error_RemoveExecutingActivity, this.originalRemovedActivity.QualifiedName), ErrorNumbers.Error_RemoveExecutingActivity)); } return(errors); }
protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity) { ValidationErrorCollection errors = base.ValidateChanges(contextActivity); Activity activity = contextActivity.TraverseDottedPathFromRoot(this.originalRemovedActivity.DottedPath); if (WorkflowChanges.IsActivityExecutable(activity) && (activity.ExecutionStatus == ActivityExecutionStatus.Executing)) { errors.Add(new ValidationError(SR.GetString("Error_RemoveExecutingActivity", new object[] { this.originalRemovedActivity.QualifiedName }), 0x11d)); } return(errors); }
private void NotifyChangesToChildExecutors(IWorkflowCoreRuntime workflowCoreRuntime, Activity contextActivity, IList <WorkflowChangeAction> changeActions) { foreach (WorkflowChangeAction action in changeActions) { if (!(action is ActivityChangeAction)) { continue; } CompositeActivity ownerActivity = contextActivity.TraverseDottedPathFromRoot(((ActivityChangeAction)action).OwnerActivityDottedPath) as CompositeActivity; if (ownerActivity == null || !WorkflowChanges.IsActivityExecutable(ownerActivity)) { continue; } ISupportWorkflowChanges compositeActivityExecutor = ActivityExecutors.GetActivityExecutor(ownerActivity) as ISupportWorkflowChanges; if (compositeActivityExecutor == null) { throw new ApplicationException(SR.GetString(SR.Error_WorkflowChangesNotSupported, ownerActivity.GetType().FullName)); } using (workflowCoreRuntime.SetCurrentActivity(ownerActivity)) { using (ActivityExecutionContext executionContext = new ActivityExecutionContext(ownerActivity)) { if (action is AddedActivityAction) { Activity addedActivity = ownerActivity.Activities[((AddedActivityAction)action).Index]; if (WorkflowChanges.IsActivityExecutable(addedActivity)) { addedActivity.OnActivityExecutionContextLoad(executionContext.Activity.RootActivity.WorkflowCoreRuntime); executionContext.InitializeActivity(addedActivity); compositeActivityExecutor.OnActivityAdded(executionContext, addedActivity); } } else if (action is RemovedActivityAction) { RemovedActivityAction removedActivityAction = (RemovedActivityAction)action; if (WorkflowChanges.IsActivityExecutable(removedActivityAction.OriginalRemovedActivity)) { compositeActivityExecutor.OnActivityRemoved(executionContext, removedActivityAction.OriginalRemovedActivity); if (removedActivityAction.OriginalRemovedActivity.ExecutionResult != ActivityExecutionResult.Uninitialized) { removedActivityAction.OriginalRemovedActivity.Uninitialize(executionContext.Activity.RootActivity.WorkflowCoreRuntime); removedActivityAction.OriginalRemovedActivity.SetValue(Activity.ExecutionResultProperty, ActivityExecutionResult.Uninitialized); } removedActivityAction.OriginalRemovedActivity.OnActivityExecutionContextUnload(executionContext.Activity.RootActivity.WorkflowCoreRuntime); removedActivityAction.OriginalRemovedActivity.Dispose(); } } } } } }
protected void ApplyWorkflowChanges(WorkflowChanges workflowChanges) { if (workflowChanges == null) { throw new ArgumentNullException("workflowChanges"); } if (base.Parent != null) { throw new InvalidOperationException(SR.GetString("Error_InvalidActivityForWorkflowChanges")); } if (base.RootActivity == null) { throw new InvalidOperationException(SR.GetString("Error_MissingRootActivity")); } if (base.WorkflowCoreRuntime == null) { throw new InvalidOperationException(SR.GetString("Error_NoRuntimeAvailable")); } workflowChanges.ApplyTo(this); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="bIsManage"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool bIsManage) { if (bIsManage) { this.InnerWorkflowChanges = null; this.WorkflowEntity = null; this.InstanceId = Guid.Empty; this.TransientWorkflow = null; } }
protected internal override bool ApplyTo(Activity rootActivity) { if (rootActivity == null) { throw new ArgumentNullException("rootActivity"); } if (!(rootActivity is CompositeActivity)) { throw new ArgumentException(SR.GetString(SR.Error_RootActivityTypeInvalid), "rootActivity"); } CompositeActivity ownerActivity = rootActivity.TraverseDottedPathFromRoot(this.OwnerActivityDottedPath) as CompositeActivity; if (ownerActivity == null) { return(false); } // !!!work around: ownerActivity.DynamicUpdateMode = true; CompositeActivity addedActivityOwner = this.addedActivity.Parent; try { this.addedActivity.SetParent(ownerActivity); Activity clonedAddedActivity = this.addedActivity; if (!this.addedActivity.DesignMode) { clonedAddedActivity = this.addedActivity.Clone(); } // We need to serialize and deserialize in order to clone during design mode else { TypeProvider typeProvider = WorkflowChanges.CreateTypeProvider(rootActivity); ServiceContainer serviceContainer = new ServiceContainer(); serviceContainer.AddService(typeof(ITypeProvider), typeProvider); DesignerSerializationManager manager = new DesignerSerializationManager(serviceContainer); WorkflowMarkupSerializer xomlSerializer = new WorkflowMarkupSerializer(); string addedActivityText = string.Empty; // serialize dynamic updates using (manager.CreateSession()) { using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) { using (XmlWriter xmlWriter = Helpers.CreateXmlWriter(sw)) { WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager); xomlSerializer.Serialize(xomlSerializationManager, xmlWriter, this.addedActivity); addedActivityText = sw.ToString(); } } // deserialize those using (StringReader sr = new StringReader(addedActivityText)) { using (XmlReader xmlReader = XmlReader.Create(sr)) { WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager); clonedAddedActivity = xomlSerializer.Deserialize(xomlSerializationManager, xmlReader) as Activity; } } } if (clonedAddedActivity == null) { throw new InvalidOperationException(SR.GetString(SR.Error_ApplyDynamicChangeFailed)); } } if (ownerActivity.WorkflowCoreRuntime != null) { ((IDependencyObjectAccessor)clonedAddedActivity).InitializeInstanceForRuntime(ownerActivity.WorkflowCoreRuntime); } clonedAddedActivity.SetParent(null); ownerActivity.Activities.Insert(this.index, clonedAddedActivity); } finally { this.addedActivity.SetParent(addedActivityOwner); ownerActivity.DynamicUpdateMode = false; } return(true); }
public void ApplyWorkflowChanges(WorkflowChanges workflowChanges) { using (new WorkflowTraceTransfer(this.InstanceId)) { while (true) { WorkflowExecutor executor = _runtime.Load(this); if (executor.IsInstanceValid) { try { executor.ApplyWorkflowChanges(workflowChanges); break; } catch (InvalidOperationException) { if (executor.IsInstanceValid) throw; } } } } }
static void OnWorkflowIdled(object sender, WorkflowEventArgs e) { WorkflowInstance workflowInstance = e.WorkflowInstance; Activity wRoot = workflowInstance.GetWorkflowDefinition(); // // use WorkflowChanges class to author dynamic change // WorkflowChanges changes = new WorkflowChanges(wRoot); Console.WriteLine(" Host is denying all PO requests - Removing POCreated step"); // // remove POCreated activity // changes.TransientWorkflow.Activities.Remove(changes.TransientWorkflow.Activities["POCreated"]); // // apply transient changes to instance // workflowInstance.ApplyWorkflowChanges(changes); }
private void AddOrderOnHoldState() { // Get a reference to the WorkflowInstance for the selected workflow WorkflowInstance instance = this.runtime.GetWorkflow(this.GetSelectedWorkflowInstanceID()); // Get a reference to the root activity for the workflow Activity root = instance.GetWorkflowDefinition(); // Create a new instance of the WorkflowChanges class for managing // the in-memory changes to the workflow WorkflowChanges changes = new WorkflowChanges(root); // Create a new State activity to the workflow StateActivity orderOnHoldState = new StateActivity(); orderOnHoldState.Name = "OrderOnHoldState"; // Add a new EventDriven activity to the State EventDrivenActivity eventDrivenDelay = new EventDrivenActivity(); eventDrivenDelay.Name = "DelayOrderEvent"; orderOnHoldState.Activities.Add(eventDrivenDelay); // Add a new Delay, initialized to 5 seconds DelayActivity delayOrder = new DelayActivity(); delayOrder.Name = "delayOrder"; delayOrder.TimeoutDuration = new TimeSpan(0, 0, 5); eventDrivenDelay.Activities.Add(delayOrder); // Add a new SetState to the OrderOpenState SetStateActivity setStateOrderOpen = new SetStateActivity(); setStateOrderOpen.TargetStateName = "OrderOpenState"; eventDrivenDelay.Activities.Add(setStateOrderOpen); // Add the OnHoldState to the workflow changes.TransientWorkflow.Activities.Add(orderOnHoldState); // Apply the changes to the workflow instance try { instance.ApplyWorkflowChanges(changes); } catch (WorkflowValidationFailedException) { // New state has already been added MessageBox.Show("On Hold state has already been added to this workflow."); } }
static void OnWorkflowIdle(object sender, WorkflowEventArgs e) { if (wasChanged) return; wasChanged = true; WorkflowInstance workflowInstance = e.WorkflowInstance; Int32 newAmount = 15000; Console.WriteLine("Dynamically change approved amount to {0:c}", newAmount); // Dynamic update of order rule WorkflowChanges workflowchanges = new WorkflowChanges(workflowInstance.GetWorkflowDefinition()); CompositeActivity transient = workflowchanges.TransientWorkflow; RuleDefinitions ruleDefinitions = (RuleDefinitions)transient.GetValue(RuleDefinitions.RuleDefinitionsProperty); RuleConditionCollection conditions = ruleDefinitions.Conditions; RuleExpressionCondition condition1 = (RuleExpressionCondition)conditions["Check"]; (condition1.Expression as CodeBinaryOperatorExpression).Right = new CodePrimitiveExpression(newAmount); workflowInstance.ApplyWorkflowChanges(workflowchanges); }
private void btnCreateSequentialWorkflow_Click(Object sender, EventArgs e) { ConnectionStringSettings persistenceConnectionString = cboPersistenceService.SelectedItem as ConnectionStringSettings; ConnectionStringSettings trackingConnectionString = cboTrackingService.SelectedItem as ConnectionStringSettings; if (persistenceConnectionString == null) { MessageBox.Show("No connection string selected for persistence service.", "WFTools Samples", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } String workflowRuntimeKey = String.Format("{0}_{1}_{2}", persistenceConnectionString.Name, trackingConnectionString == null ? "None" : trackingConnectionString.Name, chkUseLocalTransactions.Checked); SampleWorkFlowRuntime workflowRuntime; if (!this.loadedWorkflowRuntimes.TryGetValue(workflowRuntimeKey, out workflowRuntime)) { workflowRuntime = new SampleWorkFlowRuntime(persistenceConnectionString, trackingConnectionString, chkUseLocalTransactions.Checked); workflowRuntime.WorkflowTerminated += workflowRuntime_WorkflowTerminated; workflowRuntime.ServicesExceptionNotHandled += workflowRuntime_ServicesExceptionNotHandled; this.loadedWorkflowRuntimes.Add(workflowRuntimeKey, workflowRuntime); } // create a new sequential workflow WorkflowInstance workflowInstance = workflowRuntime.CreateSequentialWorkflow(); if (chkModifyWorkflow.Checked) { Activity rootActivity = workflowInstance.GetWorkflowDefinition(); WorkflowChanges workflowChanges = new WorkflowChanges(rootActivity); // modify the workflow Activity activityToRemove = workflowChanges.TransientWorkflow.GetActivityByName("codeActivity3"); CompositeActivity parentActivity = activityToRemove.Parent; parentActivity.Activities.Remove(activityToRemove); CodeActivity codeActivity = new CodeActivity("TestChangeActivity"); codeActivity.ExecuteCode += delegate { Trace.WriteLine("Test Change Activity executed..."); }; parentActivity.Activities.Add(codeActivity); workflowInstance.ApplyWorkflowChanges(workflowChanges); } workflowInstance.Start(); ManualWorkflowSchedulerService schedulerService = workflowRuntime.GetService<ManualWorkflowSchedulerService>(); schedulerService.RunWorkflow(workflowInstance.InstanceId); }
protected internal override bool ApplyTo(Activity rootActivity) { if (rootActivity == null) { throw new ArgumentNullException("rootActivity"); } if (!(rootActivity is CompositeActivity)) { throw new ArgumentException(SR.GetString("Error_RootActivityTypeInvalid"), "rootActivity"); } CompositeActivity compositeActivity = rootActivity.TraverseDottedPathFromRoot(base.OwnerActivityDottedPath) as CompositeActivity; if (compositeActivity == null) { return(false); } compositeActivity.DynamicUpdateMode = true; CompositeActivity parent = this.addedActivity.Parent; try { this.addedActivity.SetParent(compositeActivity); Activity addedActivity = this.addedActivity; if (!this.addedActivity.DesignMode) { addedActivity = this.addedActivity.Clone(); } else { TypeProvider serviceInstance = WorkflowChanges.CreateTypeProvider(rootActivity); ServiceContainer provider = new ServiceContainer(); provider.AddService(typeof(ITypeProvider), serviceInstance); DesignerSerializationManager manager = new DesignerSerializationManager(provider); WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer(); string s = string.Empty; using (manager.CreateSession()) { using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture)) { using (XmlWriter writer2 = Helpers.CreateXmlWriter(writer)) { WorkflowMarkupSerializationManager serializationManager = new WorkflowMarkupSerializationManager(manager); serializer.Serialize(serializationManager, writer2, this.addedActivity); s = writer.ToString(); } } using (StringReader reader = new StringReader(s)) { using (XmlReader reader2 = XmlReader.Create(reader)) { WorkflowMarkupSerializationManager manager3 = new WorkflowMarkupSerializationManager(manager); addedActivity = serializer.Deserialize(manager3, reader2) as Activity; } } } if (addedActivity == null) { throw new InvalidOperationException(SR.GetString("Error_ApplyDynamicChangeFailed")); } } if (compositeActivity.WorkflowCoreRuntime != null) { ((IDependencyObjectAccessor)addedActivity).InitializeInstanceForRuntime(compositeActivity.WorkflowCoreRuntime); } addedActivity.SetParent(null); compositeActivity.Activities.Insert(this.index, addedActivity); } finally { this.addedActivity.SetParent(parent); compositeActivity.DynamicUpdateMode = false; } return(true); }
/// <summary> /// Tries the load from ms workflow. /// </summary> /// <returns></returns> private bool TryLoadFromMsWorkflow() { try { WorkflowInstance instance = GlobalWorkflowRuntime.WorkflowRuntime.GetWorkflow(this.InstanceId); Activity root = instance.GetWorkflowDefinition(); if(this.WorkflowEntity == null) this.WorkflowEntity = BusinessManager.Load(WorkflowInstanceEntity.ClassName, new PrimaryKeyId(this.InstanceId)); this.InnerWorkflowChanges = new WorkflowChanges(root); this.TransientWorkflow = this.InnerWorkflowChanges.TransientWorkflow; } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString(), "Mediachase.Ibn.Assignments::TryLoadFromMsWorkflow"); return false; } return true; }
public void Load(String path) { _tx = new System.Workflow.ComponentModel.WorkflowChanges(this); _tx.TransientWorkflow.Activities.Clear(); this.AddButton("b1"); this.AddButton("b2"); this._serviceInterface = this.CreateServiceInterface(); this._serviceImplementation = this.CreateServiceImplementation(this._serviceInterface); PressState ps1 = new ImageState("ps1", "img.png", this._serviceInterface); PressState ps2 = new AnimationState("ps2", "", 123, this._serviceInterface); this.AddState(ps1); this.AddState(ps2); ps1.AddTrigger("b1", "ps2"); ps2.AddTrigger("b2", "ps1"); this.SetInitial(ps1); }
internal void ApplyWorkflowChanges(WorkflowChanges workflowChanges) { // Accessing InstanceId is not thread safe here! //WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a dynamic update request from outside for instance {0}", this.InstanceIdString); DiagnosticStackTrace("dynamic update request"); // check arguments if (workflowChanges == null) throw new ArgumentNullException("workflowChanges"); // check if this is a valid in-memory instance if (!this.IsInstanceValid) throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); if (this.currentAtomicActivity != null) throw new InvalidOperationException(ExecutionStringManager.Error_InsideAtomicScope); try { using (ScheduleWork work = new ScheduleWork(this)) { // block other instance operations from outside using (this._executorLock.Enter()) { // check if this is a valid in-memory instance if (!this.IsInstanceValid) throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); // get the instance to stop running this.Scheduler.CanRun = false; using (new SchedulerLockGuard(this._schedulerLock, this)) { using (new ServiceEnvironment(this.rootActivity)) { bool localSuspend = false; // check if this is a valid in-memory instance if (!this.IsInstanceValid) throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); try { // check the status of the schedule switch (this.WorkflowStatus) { ////case ActivityExecutionStatus.Completed: // case WorkflowStatus.Completed: case WorkflowStatus.Terminated: throw new InvalidOperationException( ExecutionStringManager.InvalidOperationRequest); case WorkflowStatus.Suspended: // instance already suspended localSuspend = false; break; default: // suspend the instance this.SuspendOnIdle(null); localSuspend = true; break; } // apply the changes workflowChanges.ApplyTo(this.rootActivity); } finally { if (localSuspend) { // @undone: for now this will not return till the instance is done // Once Kumar has fixed 4335, we can enable this. this.ResumeOnIdle(true); } } } } // release lock on scheduler } } } catch (Exception e) { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: dynamic update attempt from outside on instance '{0}' threw an exception '{1}' at {2}", this.InstanceIdString, e.Message, e.StackTrace); throw; } }
internal void ApplyWorkflowChanges(WorkflowChanges workflowChanges) { if (workflowChanges == null) { throw new ArgumentNullException("workflowChanges"); } if (!this.IsInstanceValid) { throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); } if (this.currentAtomicActivity != null) { throw new InvalidOperationException(ExecutionStringManager.Error_InsideAtomicScope); } try { using (new ScheduleWork(this)) { using (this._executorLock.Enter()) { if (!this.IsInstanceValid) { throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); } this.Scheduler.CanRun = false; using (new SchedulerLockGuard(this._schedulerLock, this)) { using (new ServiceEnvironment(this.rootActivity)) { bool flag = false; if (!this.IsInstanceValid) { throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid); } try { switch (this.WorkflowStatus) { case System.Workflow.Runtime.WorkflowStatus.Completed: case System.Workflow.Runtime.WorkflowStatus.Terminated: throw new InvalidOperationException(ExecutionStringManager.InvalidOperationRequest); case System.Workflow.Runtime.WorkflowStatus.Suspended: flag = false; break; default: this.SuspendOnIdle(null); flag = true; break; } workflowChanges.ApplyTo(this.rootActivity); } finally { if (flag) { this.ResumeOnIdle(true); } } } } } } } catch (Exception exception) { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: dynamic update attempt from outside on instance '{0}' threw an exception '{1}' at {2}", new object[] { this.InstanceIdString, exception.Message, exception.StackTrace }); throw; } }