Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OperationManager{TSessionState, TOperationState}"/> class.
        /// </summary>
        /// <param name="sessionId">Session id.</param>
        /// <param name="sessionState">Initial session state.</param>
        /// <param name="sessionManager">Owner session manager.</param>
        /// <param name="executionOptions">Optional execution options. Also can be provided in Start method.</param>
        /// <param name="logger">Logger.</param>
        /// <param name="metadata">Optional metadata.</param>
        public OperationManager(
            OperationId sessionId,
            [DisallowNull] TSessionState sessionState,
            ISessionManager <TSessionState, TOperationState> sessionManager,
            IExecutionOptions <TSessionState, TOperationState>?executionOptions = null,
            ILogger?logger = null,
            IPropertyContainer?metadata = null)
        {
            sessionState.AssertArgumentNotNull(nameof(sessionState));
            sessionManager.AssertArgumentNotNull(nameof(sessionManager));

            _sessionManager = sessionManager;
            _logger         = logger ?? GetLoggerFactory().CreateLogger(sessionId.Value);
            _operations     = new ConcurrentDictionary <OperationId, IOperation <TOperationState> >();

            _session = Operation
                       .CreateNotStarted(sessionId, sessionState, metadata)
                       .ToSession(getOperations: GetOperations);

            if (executionOptions != null)
            {
                _session = _session.With(executionOptions: executionOptions);
            }

            ILoggerFactory GetLoggerFactory() =>
            (ILoggerFactory?)_sessionManager.Services.GetService(typeof(ILoggerFactory)) ?? NullLoggerFactory.Instance;
        }
Пример #2
0
        public bool Validate(IExecutionOptions options)
        {
            if (options.Files == null)
            {
                throw new ApplicationException("Files not specified.");
            }
            if (options.Files.Length == 0)
            {
                throw new ApplicationException("Files not specified.");
            }
            if (options.Logger == null)
            {
                throw new ApplicationException("Logger not specified.");
            }
            if (options.ResultsFormatter == null)
            {
                throw new ApplicationException("Results formatter not specified.");
            }

            foreach (var file in options.Files.Where(file => !File.Exists(file)))
            {
                throw new FileNotFoundException(string.Format("Assembly file {0} not found.", file));
            }
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Engine distructor.
        /// </summary>
        /// <param name="options">The options to use.</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public Engine(IExecutionOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            _options = options;
        }
Пример #4
0
        /// <inheritdoc />
        public async Task Start(IExecutionOptions <TSessionState, TOperationState>?executionOptions = null)
        {
            if (_runtime != null)
            {
                throw new OperationManagerException(Errors.SessionIsAlreadyStarted(_session.Id));
            }

            if (_session.ExecutionOptions is IExecutionOptions <TSessionState, TOperationState> sessionExecutionOptions)
            {
                // Merge params provided on initialization and on start.
                executionOptions = new ExecutionOptions <TSessionState, TOperationState>()
                {
                    MaxConcurrencyLevel = executionOptions?.MaxConcurrencyLevel ?? sessionExecutionOptions.MaxConcurrencyLevel ?? Environment.ProcessorCount,
                    SessionTimeout      = executionOptions?.SessionTimeout ?? sessionExecutionOptions.SessionTimeout ?? TimeSpan.FromHours(24),

                    Executor            = executionOptions?.Executor ?? sessionExecutionOptions.Executor,
                    ExecutorExtended    = executionOptions?.ExecutorExtended ?? sessionExecutionOptions.ExecutorExtended,
                    OnOperationFinished = executionOptions?.OnOperationFinished ?? sessionExecutionOptions.OnOperationFinished,
                    OnSessionFinished   = executionOptions?.OnSessionFinished ?? sessionExecutionOptions.OnSessionFinished,

                    CancellationToken = executionOptions?.CancellationToken ?? CancellationToken.None,
                };
            }

            if (executionOptions == null)
            {
                throw new ArgumentNullException(nameof(executionOptions), "Provide executionOptions on start or initialization.");
            }
            if (executionOptions.ExecutorExtended == null && executionOptions.Executor == null)
            {
                throw new ArgumentException($"ExecutionOptions: {nameof(executionOptions.ExecutorExtended)} or {nameof(executionOptions.Executor)} should be provided.", nameof(executionOptions));
            }
            if (executionOptions.ExecutorExtended != null && executionOptions.Executor != null)
            {
                throw new ArgumentException($"ExecutionOptions: Only one of {nameof(executionOptions.ExecutorExtended)}, {nameof(executionOptions.Executor)} should be provided.", nameof(executionOptions));
            }

            using var updateLock = await _updateLock.WaitAsyncAndGetLockReleaser();

            _session = _session.With(
                status: OperationStatus.InProgress,
                startedAt: DateTime.Now.ToLocalDateTime(),
                executionOptions: executionOptions);

            var cts = CreateCancellation(executionOptions);

            var pipeline = new Pipeline <IOperation <TOperationState> >()
                           .AddStep(operation => ProcessOperation(operation), settings =>
            {
                settings.MaxDegreeOfParallelism             = executionOptions.MaxConcurrencyLevel !.Value;
                settings.ExecutionOptions.CancellationToken = cts.Token;
            })
Пример #5
0
 public Runtime(
     IExecutionOptions <TSessionState, TOperationState> options,
     CancellationTokenSource cts,
     Pipeline <IOperation <TOperationState> > pipeline,
     SessionTracer sessionTracer,
     Func <Task, ISession <TSessionState, TOperationState> > onSessionFinished)
 {
     Options            = options;
     Cts                = cts;
     Pipeline           = pipeline;
     SessionTracer      = sessionTracer;
     _onSessionFinished = onSessionFinished;
 }
Пример #6
0
        public ExecutionContext(IExecutionOptions executionOptions, IValidatorsFactory validatorsFactory)
        {
            CollectionForceKey = executionOptions.CollectionForceKey;
            RequiredError      = executionOptions.RequiredError;
            DefaultError       = executionOptions.DefaultError;
            MaxDepth           = executionOptions.MaxDepth;
            ValidatorsFactory  = validatorsFactory;

            _defaultErrorCollection = new Lazy <ErrorsCollection>(() =>
            {
                if (DefaultError == null)
                {
                    return(null);
                }

                var defaultErrorCollection = new ErrorsCollection();
                defaultErrorCollection.AddError(DefaultError);

                return(defaultErrorCollection);
            });
        }
Пример #7
0
 /// <summary>
 /// Disposes the Engine.
 /// </summary>
 public void Dispose()
 {
     _options   = null;
     _validator = null;
 }
Пример #8
0
        // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
        private static IModelReport BuildModelReport(IErrorsCollection errorsCollection, Translator translator, int depth, IExecutionOptions executionOptions)
        {
            if (depth > executionOptions.MaxDepth)
            {
                throw new MaxDepthExceededException(executionOptions.MaxDepth);
            }

            if (errorsCollection.IsEmpty)
            {
                return(ModelReport.Empty);
            }

            var errorsList = new ModelReportErrorsList();

            if (errorsCollection.Errors.Any())
            {
                var errors = errorsCollection.Errors
                             .Select(e => translator(e))
                             .Distinct()
                             .ToList();

                errorsList.AddRange(errors);
            }

            if (!errorsCollection.Members.Any())
            {
                return(errorsList);
            }

            var report = errorsList.Any()
                ? new ModelReport {
                { string.Empty, errorsList }
            }
                : new ModelReport();

            foreach (var memberPair in errorsCollection.Members)
            {
                var memberReport = BuildModelReport(memberPair.Value, translator, depth + 1, executionOptions);

                if (memberReport != null)
                {
                    report.Add(memberPair.Key, memberReport);
                }
            }

            return(report);
        }
Пример #9
0
 static ExecutionFlow()
 {
     Options = new ExecutionOptions();
 }
Пример #10
0
        internal ValidationResult(Guid validationContextId, ITranslationProxy translationProxy, IExecutionOptions executionOptions, T model = null, IErrorsCollection errorsCollection = null)
        {
            TranslationProxy = translationProxy ?? throw new ArgumentNullException(nameof(translationProxy));
            ErrorsCollection = errorsCollection ?? Errors.ErrorsCollection.Empty;
            ExecutionOptions = executionOptions ?? throw new ArgumentNullException(nameof(executionOptions));

            ValidationDate      = DateTime.UtcNow;
            ValidationContextId = validationContextId;

            Model = model;
        }
Пример #11
0
        // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
        private static void BuildListReport(ListReport listReport, string path, IErrorsCollection errorsCollection, Translator translator, int depth, IExecutionOptions executionOptions)
        {
            if (depth > executionOptions.MaxDepth)
            {
                throw new MaxDepthExceededException(executionOptions.MaxDepth);
            }

            if (errorsCollection.IsEmpty)
            {
                return;
            }

            if (errorsCollection.Errors.Any())
            {
                listReport.AddRange(errorsCollection.Errors
                                    .Select(m => string.IsNullOrWhiteSpace(path)
                        ? translator(m)
                        : $"{path}: {translator(m)}")
                                    .Distinct()
                                    .ToList()
                                    );
            }

            foreach (var memberPair in errorsCollection.Members)
            {
                var currentPath = string.IsNullOrEmpty(path) ? string.Empty : $"{path}.";

                BuildListReport(listReport, $"{currentPath}{memberPair.Key}", memberPair.Value, translator, depth + 1, executionOptions);
            }
        }