/// <summary> /// Execute scenario in other thread /// </summary> /// <param name="param"></param> /// <param name="cancelToken"></param> public virtual void ExecuteAsyncParallel(ScenarioActionSource source, string param, ExecutionContext parentContext) { CheckRights(source, parentContext); TaskUtils.StartLongRunning(() => { CheckValue(param, parentContext); var output = new OutputChangedDelegates(); ExecutionContext context; var oldVal = GetPreviousValue(); if (parentContext != null) { var cancellationTokenSource = new SafeCancellationToken(); parentContext.CancellationTokenSource.RegisterCallback(cancellationTokenSource.Cancel); context = new ExecutionContext(this, param, oldVal, output, parentContext, cancellationTokenSource); } else { context = new ExecutionContext(this, param, oldVal, output, new SafeCancellationToken()); } CheckContext(context); HandleExecution(() => ExecuteInternal(context)); }, HandleSet); }
public ScenarioBase[] GetScenarios(UserBase user, ScenarioStartupSource source, ScenarioAction action, ValueTypeBase valueType = null, bool rightPart = false) { var actionSource = new ScenarioActionSource(user, source, ScenarioAction.ViewValue); return(Scenarios.Where(x => (valueType == null || valueType.IsCompatibleWith(x.ValueType)) && x.IsAccessAvailable(actionSource) && (rightPart ? !(x.ValueType is ButtonValueType) : true)) .ToArray()); }
/// <summary> /// Current value of scenario execution /// </summary> public virtual void CalculateCurrentValueAsync(ScenarioActionSource source, Action <string> callback, ExecutionContext parentContext) { CheckRights(source, parentContext); TaskUtils.Start( () => { var result = CalculateCurrentValue(source, parentContext); callback(result); }, HandleGet); }
/// <summary> /// Determine that user can execute scenario or view scenario value /// </summary> /// <param name="user"></param> /// <param name="source"></param> /// <returns></returns> public bool IsAccessAvailable(ScenarioActionSource source) { if (source.Action == ScenarioAction.ViewValue) { return(CanViewValue(source)); } else if (source.Action == ScenarioAction.Execute) { return(CanExecute(source)); } throw new NotImplementedException("Invalid action source"); }
protected void CheckRights(ScenarioActionSource source, ExecutionContext context) { try { if (!IsAccessAvailable(source)) { throw new ScenarioExecutionException(ScenarioExecutionError.AccessDenied); } } catch (Exception e) { context?.CancelAll(); //stop execution throw e; } }
/// <summary> /// Raise events when state changed /// </summary> protected void RaiseValueChangedEvents(ScenarioActionSource source, bool onlyIntent) { LastChange = DateTime.Now.ToUniversalTime(); for (int i = 0; i < _valueChangedEvents.Count; i++) { try { _valueChangedEvents[i](this, new EventsArgs <ScenarioValueChangedEventArgs>(new ScenarioValueChangedEventArgs(this, onlyIntent, source))); } catch (Exception e) { Log.InfoFormat(e, "Ошибка во время выполнения событий сценария [{1}][{0}]", Name, Id); } } }
/// <summary> /// Raise events when state changed /// </summary> protected void RaiseValueChangedEvents(ScenarioActionSource source, bool onlyIntent, string value, string prevValue) { LastChange = DateTime.Now; for (int i = 0; i < _valueChangedEvents.Count; i++) { try { _valueChangedEvents[i](this, new EventsArgs <ScenarioValueChangedEventArgs>(new ScenarioValueChangedEventArgs(this, onlyIntent, source, value, prevValue))); } catch (Exception e) { Log.Info($"Ошибка во время выполнения событий сценария [{Name}][{Id}]", e); } } }
/// <summary> /// Determine that user can view scenario value /// </summary> /// <param name="user"></param> /// <param name="source"></param> /// <returns></returns> protected bool CanViewValue(ScenarioActionSource source) { try { if (SecuritySettings == null) { throw new NullReferenceException("Security settings is null"); } return(SecuritySettings.IsAvailableForUser(source.User, source.Source, ScenarioAction.ViewValue)); } catch (Exception e) { Log.ErrorFormat(e, "Ошибка во время вычисления прав для просмотра значения сценария [{0}][{1}]", Name, Id); return(false); } }
/// <summary> /// Determine that user can execute scenario /// </summary> /// <param name="user"></param> /// <param name="source"></param> /// <returns></returns> protected bool CanExecute(ScenarioActionSource source) { try { if (SecuritySettings == null) { throw new NullReferenceException("Security settings is null"); } var writeAvailableForThisSource = !OnlyGetValue || source.Source == ScenarioStartupSource.System; //crutch, scenario can be executed by itself or system return(writeAvailableForThisSource && SecuritySettings.IsAvailableForUser(source.User, source.Source, ScenarioAction.Execute)); } catch (Exception e) { Log.ErrorFormat(e, "Ошибка во время вычисления прав для выполнения сценария [{0}][{1}]", Name, Id); return(false); } }
/// <summary> /// Execute scenario in main execution context /// </summary> /// <param name="param"></param> public virtual void ExecuteAsync(ScenarioActionSource source, string param, out string executionId, ExecutionContext parentContext = null) { executionId = PrepareExecutionId(); CheckRights(source, parentContext); TaskUtils.StartLongRunning(() => { CheckValue(param, parentContext); TryCancelAll(); var context = PrepareExecutionContext(param, parentContext); HandleExecution(() => { SetPreviousValue(GetCurrentValue()); SetCurrentValue(param, source); ExecuteInternal(context); }); }, HandleSet); }
/// <summary> /// Current value of scenario execution /// </summary> public virtual string CalculateCurrentValue(ScenarioActionSource source, ExecutionContext parentContext) { CheckRights(source, parentContext); try { if (parentContext != null) { //empty context, just for stack overflow and circular reference check var context = new ExecutionContext(this, string.Empty, string.Empty, null, parentContext, parentContext.CancellationTokenSource); CheckContext(context); } return(CalculateCurrentValueInternal()); } catch (Exception e) { HandleGet(e); throw e; } }
/// <summary> /// Execute in current thread /// </summary> /// <param name="param"></param> /// <param name="cancelToken"></param> public virtual void Execute(ScenarioActionSource source, string param, out string executionId, ExecutionContext parentContext = null) { executionId = PrepareExecutionId(); CheckRights(source, parentContext); try { CheckValue(param, parentContext); TryCancelAll(); var context = PrepareExecutionContext(param, parentContext); HandleExecution(() => { SetPreviousValue(GetCurrentValue()); SetCurrentValue(param, source); ExecuteInternal(context); }); } catch (Exception e) { HandleSet(e); } }
public ScenarioValueChangedEventArgs(ScenarioBase scenario, bool onlyIntent, ScenarioActionSource source) { Scenario = scenario; OnlyIntent = onlyIntent; Source = source; }
/// <summary> /// Set result of scenario execution /// </summary> public virtual void SetCurrentValue(string value, ScenarioActionSource source) { SetCurrentValueNoEvents(value); RaiseValueChangedEvents(source, false); }
public virtual void NotifyOnlyIntent(ScenarioActionSource source, string value, string prevValue) => RaiseValueChangedEvents(source, true, value, prevValue);
/// <summary> /// Set result of scenario execution /// </summary> public virtual void SetCurrentValue(string value, ScenarioActionSource source) { LastChange = DateTime.Now; SetCurrentValueNoEvents(value); RaiseValueChangedEvents(source, false, value, _previousValue); }
public virtual void NotifyOnlyIntent(ScenarioActionSource source) { RaiseValueChangedEvents(source, true); }