private async Task <FlowResult> ValidateSourceDestinationAsync(IStateManager stateManager,
                                                                       MoveModel model)
        {
            var transitionSet = stateManager.GetFlowSet <FlowTransition>();
            var transition    = await transitionSet.GetByIdAsync(model.TransitionId);

            if (transition == null)
            {
                return(FlowResult.Failed(
                           new FlowError(FlowErrors.ItemNotFound, args: nameof(FlowTransition))));
            }

            var stateSet = stateManager.GetFlowSet <FlowState>();

            if (transition.SourceId.HasValue == true)
            {
                var source = await stateSet.GetByIdAsync(transition.SourceId.Value);

                if (source == null)
                {
                    return(FlowResult.Failed(new FlowError(FlowErrors.ItemNotFound, args: nameof(source))));
                }
            }

            var destination = await stateSet.GetByIdAsync(transition.DestinationId);

            if (destination == null)
            {
                return(FlowResult.Failed(new FlowError(FlowErrors.ItemNotFound, args: nameof(destination))));
            }

            return(FlowResult.Success);
        }
        public async Task <FlowResult <FlowInstance> > DoAsync(InitFlowModel model)
        {
            var taskResult = await InstanceService.CreateFlowInstanceAsync(model);

            var transitionSet   = _stateManager.GetFlowSet <FlowTransition>();
            var startTransition = await transitionSet
                                  .FirstOrDefaultAsync(x => x.TypeId.Equals(taskResult.Result.TypeId) &&
                                                       x.TransitionType == FlowTransitionTypes.Start);

            if (startTransition == null)
            {
                return(FlowResult <FlowInstance>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, "Start transition")));
            }

            var stepResult = await StepService.CreateFlowStepAsync(new MoveModel()
            {
                Comment      = null,
                IdentityId   = model.InitializerId,
                InstanceId   = taskResult.Result.Id,
                Payload      = null,
                TransitionId = startTransition.Id
            });

            return(taskResult.Merge(stepResult));
        }
Exemple #3
0
        public async Task <FlowResult <FlowInstance> > CreateFlowInstanceAsync(InitFlowModel model)
        {
            var set     = StateManager.GetFlowSet <FlowInstance>();
            var typeSet = StateManager.GetFlowSet <FlowType>();

            var type = await typeSet.GetByIdAsync(model.TypeId);

            if (type == null)
            {
                return(FlowResult <FlowInstance>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(type))));
            }

            var entity = FlowEntity.InitializeType(new FlowInstance()
            {
                Title         = model.Title,
                Payload       = model.Payload,
                TypeId        = type.Id,
                InitializerId = model.InitializerId,
                AccessPhrase  = model.AccessPhrase,
            });

            var result = await set.CreateAsync(entity);

            return(FlowResult <FlowInstance> .Successful(result));
        }
        public async Task <FlowResult <FlowState> > CreateFlowStateAsync(InitFlowStateModel model)
        {
            var set     = StateManager.GetFlowSet <FlowState>();
            var typeSet = StateManager.GetFlowSet <FlowType>();

            var type = await typeSet.GetByIdAsync(model.TypeId);

            if (type == null)
            {
                return(FlowResult <FlowState>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(type))));
            }

            var entity = FlowEntity.InitializeType(new FlowState()
            {
                Name      = model.Name,
                Title     = model.Title,
                StateType = (byte)model.StateType,
                TypeId    = type.Id,
                Tag       = model.Tag,
            });

            var result = await set.CreateAsync(entity);

            return(FlowResult <FlowState> .Successful(result));
        }
Exemple #5
0
        public async Task <FlowResult <PagedList <FlowType> > > GetPagedTypesByEntityAsync(Type entityType,
                                                                                           PageOptions pageOptions)
        {
            try
            {
                Logger.LogInfo("try to get paged list of types.");
                var typeSet  = StateManager.GetFlowSet <FlowType>();
                var stateSet = StateManager.GetFlowSet <FlowState>();
                var query    = from type in typeSet.GetAll()
                               let states = stateSet.GetAll().Where(x => x.TypeId == type.Id)
                                            where type.EntityType.Equals(entityType.FullName)
                                            select new FlowType()
                {
                    CreatedAt         = type.CreatedAt,
                    Deleted           = type.Deleted,
                    EntityPayloadType = type.EntityPayloadType,
                    EntityType        = type.EntityType,
                    Id         = type.Id,
                    ModifiedAt = type.ModifiedAt,
                    Name       = type.Name,
                    States     = states.ToList()
                };
                var pagedList = await typeSet.ToPagedListAsync(query, pageOptions);

                var result = new FlowResult <PagedList <FlowType> >();
                result.SetResult(pagedList);
                Logger.LogInfo($"paged list of types with count '{pagedList.Count}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <PagedList <FlowType> > .Failed(new FlowError(ex.Message)));
            }
        }
Exemple #6
0
        public async Task <FlowResult <IEnumerable <FlowType> > > GetTypesAsync()
        {
            try
            {
                Logger.LogInfo("try to get list of types.");
                var typeSet  = StateManager.GetFlowSet <FlowType>();
                var stateSet = StateManager.GetFlowSet <FlowState>();

                var query = from type in typeSet.GetAll()
                            let states = stateSet.GetAll().Where(x => x.TypeId == type.Id)
                                         select new FlowType()
                {
                    CreatedAt         = type.CreatedAt,
                    Deleted           = type.Deleted,
                    EntityPayloadType = type.EntityPayloadType,
                    EntityType        = type.EntityType,
                    Id         = type.Id,
                    ModifiedAt = type.ModifiedAt,
                    Name       = type.Name,
                    States     = states.ToList()
                };

                var types = await typeSet.ToListAsync(query);

                var result = new FlowResult <IEnumerable <FlowType> >();
                result.SetResult(types);
                Logger.LogInfo($"list of types with count '{types.Count()}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <IEnumerable <FlowType> > .Failed(new FlowError(ex.Message)));
            }
        }
Exemple #7
0
        public async Task <FlowResult <FlowTransition> > CreateFlowTransitionAsync(InitFlowTransitionModel model)
        {
            var set      = StateManager.GetFlowSet <FlowTransition>();
            var stateSet = StateManager.GetFlowSet <FlowState>();

            var source = await stateSet.GetByIdAsync(model.SourceId);

            if (source == null)
            {
                return(FlowResult <FlowTransition>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(source))));
            }

            var destination = await stateSet.GetByIdAsync(model.DestinationId);

            if (destination == null)
            {
                return(FlowResult <FlowTransition>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(destination))));
            }

            var entity = FlowEntity.InitializeType(new FlowTransition()
            {
                Name           = model.Name,
                Title          = model.Title,
                SourceId       = source.Id,
                DestinationId  = destination.Id,
                TransitionType = model.TransitionType,
                TypeId         = source.TypeId,
            });

            var result = await set.CreateAsync(entity);

            return(FlowResult <FlowTransition> .Successful(result));
        }
        public async Task <FlowResult <FlowState> > GetStateAsync(
            Expression <Func <FlowState, bool> > expression)
        {
            try
            {
                Logger.LogInfo("try to get a state of flow by expression.");
                var stateSet = StateManager.GetFlowSet <FlowState>();
                var state    = await stateSet.FirstOrDefaultAsync(expression);

                if (state == null)
                {
                    Logger.LogWarning("state not exist.");
                    return(FlowResult <FlowState> .Failed(
                               new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowState))));
                }
                var result = new FlowResult <FlowState>();
                result.SetResult(state);
                Logger.LogInfo($"state with id '{state.Id}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <FlowState> .Failed(new FlowError(ex.Message)));
            }
        }
        public async Task <FlowResult <FlowInstance> > GetInstanceAsync(
            Expression <Func <FlowInstance, bool> > expression)
        {
            try
            {
                Logger.LogInfo("try to get an instance of flow by expression.");
                var instanceSet = StateManager.GetFlowSet <FlowInstance>();
                var instance    = await instanceSet.FirstOrDefaultAsync(expression);

                if (instance == null)
                {
                    Logger.LogWarning("instance not exist.");
                    return(FlowResult <FlowInstance> .Failed(
                               new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowInstance))));
                }
                var result = new FlowResult <FlowInstance>();
                if (instance.Active == false)
                {
                    Logger.LogWarning("instance is inactive");
                    result.Warns.Add(new FlowWarn(FlowWarns.InstanceInactive));
                }
                result.SetResult(instance);
                Logger.LogInfo($"instance with id '{instance.Id}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <FlowInstance> .Failed(new FlowError(ex.Message)));
            }
        }
        private async Task <FlowResult> ValidatePossibleMoveAsync(IStateManager stateManager, MoveModel model)
        {
            var instanceSet = stateManager.GetFlowSet <FlowInstance>();

            var instance = await instanceSet.GetByIdAsync(model.InstanceId);

            if (instance == null)
            {
                return(FlowResult.Failed(new FlowError(FlowErrors.ItemNotFound, args: nameof(FlowInstance))));
            }

            var stepSet             = stateManager.GetFlowSet <FlowStep>();
            var instanceCurrentStep = await stepSet
                                      .FirstOrDefaultAsync(x => x.InstanceId.Equals(instance.Id) && x.IsCurrent);

            var transitionSet = stateManager.GetFlowSet <FlowTransition>();
            var transition    = await transitionSet.GetByIdAsync(model.TransitionId);

            if (transition == null)
            {
                return(FlowResult.Failed(
                           new FlowError(FlowErrors.ItemNotFound, args: nameof(FlowTransition))));
            }

            var instanceLastTransition = await transitionSet.GetByIdAsync(instanceCurrentStep.TransitionId);

            if (instanceCurrentStep == null)
            {
                return(FlowResult.Failed(new FlowError(FlowErrors.ItemNotFound, args: nameof(FlowTransition))));
            }

            var stateSet = stateManager.GetFlowSet <FlowState>();
            var state    = await stateSet.GetByIdAsync(instanceLastTransition.DestinationId);

            if (state == null)
            {
                return(FlowResult.Failed(new FlowError(FlowErrors.ItemNotFound, args: nameof(state))));
            }

            var possibleTransitions = await transitionSet.GetAllAsync(x => x.SourceId == state.Id);

            if (possibleTransitions.Select(x => x.Id).Contains(model.TransitionId) == false)
            {
                string sourceParam = transition.SourceId.HasValue ?
                                     transition.SourceId.Value.ToString() : FlowErrors.StateNull;
                string destinationParam = transition.DestinationId.ToString();

                return(FlowResult.Failed(new FlowError(FlowErrors.MoveImpossibleTransition,
                                                       sourceParam, destinationParam)));
            }

            return(FlowResult.Success);
        }
        public async Task <FlowResult <IEnumerable <FlowTransition> > > GetSourceTransitionsAsync(Guid sourceId)
        {
            //Get current instance
            if (sourceId.GuidIsEmpty())
            {
                throw new ArgumentNullException(nameof(sourceId));
            }

            var stateSet = StateManager.GetFlowSet <FlowState>();

            var targetSource = await stateSet
                               .FirstOrDefaultAsync(x => x.Id.Equals(sourceId));

            if (targetSource == null)
            {
                return(FlowResult <IEnumerable <FlowTransition> >
                       .Failed(new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowState))));
            }

            var transitionSet = StateManager.GetFlowSet <FlowTransition>();
            var typeSet       = StateManager.GetFlowSet <FlowType>();
            var reasonSet     = StateManager.GetFlowSet <FlowTransitionReason>();

            var query = from transition in transitionSet.GetAll()
                        join type in typeSet.GetAll() on transition.TypeId equals type.Id
                        join source in stateSet.GetAll() on transition.SourceId equals source.Id
                        join destination in stateSet.GetAll() on transition.DestinationId equals destination.Id
                        where transition.SourceId == sourceId
                        select new FlowTransition()
            {
                Id             = transition.Id,
                Type           = type,
                CreatedAt      = transition.CreatedAt,
                ModifiedAt     = transition.ModifiedAt,
                Deleted        = transition.Deleted,
                TypeId         = transition.TypeId,
                Name           = transition.Name,
                SourceId       = transition.SourceId,
                DestinationId  = transition.DestinationId,
                Destination    = destination,
                IsAutomatic    = transition.IsAutomatic,
                Source         = source,
                Title          = transition.Title,
                TransitionType = transition.TransitionType
            };

            var transitions = await transitionSet.ToListAsync(query);

            return(FlowResult <IEnumerable <FlowTransition> > .Successful(transitions));
        }
Exemple #12
0
        public async Task <FlowResult <FlowStep> > CreateFlowStepAsync(MoveModel model)
        {
            var set           = StateManager.GetFlowSet <FlowStep>();
            var instanceSet   = StateManager.GetFlowSet <FlowInstance>();
            var transitionSet = StateManager.GetFlowSet <FlowTransition>();
            var stateSet      = StateManager.GetFlowSet <FlowState>();

            var instance = await instanceSet.GetByIdAsync(model.InstanceId);

            if (instance == null)
            {
                return(FlowResult <FlowStep>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(instance))));
            }

            var transition = await transitionSet.GetByIdAsync(model.TransitionId);

            if (transition == null)
            {
                return(FlowResult <FlowStep>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(transition))));
            }

            var state = await stateSet.GetByIdAsync(transition.DestinationId);

            if (state == null)
            {
                return(FlowResult <FlowStep>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(state))));
            }

            var entity = FlowEntity.InitializeType(new FlowStep()
            {
                InstanceId        = instance.Id,
                IsCurrent         = true,
                TransitionId      = transition.Id,
                Payload           = model.Payload,
                Comment           = model.Comment,
                CurrentStateName  = state.Name,
                CurrentStateTitle = state.Title,
                CurrentStateType  = state.StateType,
            });

            var result = await set.CreateAsync(entity);

            return(FlowResult <FlowStep> .Successful(result));
        }
        public async Task <FlowResult <IEnumerable <FlowTransition> > > GetInstanceTransitionsAsync(Guid instanceId)
        {
            //Get current instance
            if (instanceId.GuidIsEmpty())
            {
                throw new ArgumentNullException(nameof(instanceId));
            }

            var instanceSet = StateManager.GetFlowSet <FlowInstance>();

            var targetInstance = await instanceSet.FirstOrDefaultAsync(x => x.Id.Equals(instanceId));

            if (targetInstance == null)
            {
                return(FlowResult <IEnumerable <FlowTransition> >
                       .Failed(new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowInstance))));
            }

            //Get current instance state
            var stepSet = StateManager.GetFlowSet <FlowStep>();

            var currentStep = await stepSet
                              .FirstOrDefaultAsync(x => x.InstanceId.Equals(targetInstance.Id) && x.IsCurrent);

            if (currentStep == null)
            {
                return(FlowResult <IEnumerable <FlowTransition> >
                       .Failed(new FlowError(FlowErrors.InstanceHasnostep)));
            }

            //Get current step transition
            var transitionSet = StateManager.GetFlowSet <FlowTransition>();

            var currentTransition = await transitionSet
                                    .FirstOrDefaultAsync(x => x.Id.Equals(currentStep.TransitionId));

            //Get current state
            var stateSet = StateManager.GetFlowSet <FlowState>();

            var currentState = await stateSet.FirstOrDefaultAsync(x => x.Id.Equals(currentTransition.DestinationId));

            //Get current state transitions
            var transitions = await transitionSet.GetAllAsync(x => x.SourceId.Equals(currentState.Id));

            return(FlowResult <IEnumerable <FlowTransition> > .Successful(transitions));
        }
Exemple #14
0
        public async Task <FlowResult <FlowType> > GetTypeAsync(
            Expression <Func <FlowType, bool> > expression)
        {
            try
            {
                Logger.LogInfo("try to get a type of flow by expression.");
                var typeSet  = StateManager.GetFlowSet <FlowType>();
                var stateSet = StateManager.GetFlowSet <FlowState>();

                var query = from type in typeSet.GetAll()
                            let states = stateSet.GetAll().Where(x => x.TypeId == type.Id)
                                         select new FlowType()
                {
                    CreatedAt         = type.CreatedAt,
                    Deleted           = type.Deleted,
                    EntityPayloadType = type.EntityPayloadType,
                    EntityType        = type.EntityType,
                    Id         = type.Id,
                    ModifiedAt = type.ModifiedAt,
                    Name       = type.Name,
                    States     = states.ToList()
                };

                query = query.Where(expression);

                var flowType = await typeSet.FirstOrDefaultAsync(query);

                if (flowType == null)
                {
                    Logger.LogWarning("type not exist.");
                    return(FlowResult <FlowType> .Failed(
                               new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowType))));
                }
                var result = new FlowResult <FlowType>();
                result.SetResult(flowType);
                Logger.LogInfo($"type with id '{flowType.Id}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <FlowType> .Failed(new FlowError(ex.Message)));
            }
        }
        private async Task <FlowResult <TResultModel> > HandleRequestAsync <TModel, TResultModel>(
            IFlowRequest <TModel, TResultModel> request, TModel model)
            where TModel : class where TResultModel : class
        {
            try
            {
                Logger.LogInfo(FlowLogs.RequestStarted, args: model.GetType().Name);
                if (request == null)
                {
                    throw new FlowException(FlowErrors.ServiceIsNull, nameof(request));
                }

                var validator = ObjectActivator.GetValidator <TModel>();

                var validateResult = await validator.ValidateAsync(StateManager, model);

                Logger.LogInfo(FlowLogs.RequestHasWarn, args: validateResult.Warns.Count.ToString());
                Logger.LogInfo(FlowLogs.RequestHasError, args: validateResult.Errors.Count.ToString());

                if (!validateResult.Succeeded)
                {
                    return(FlowResult <TResultModel> .Failed(validateResult.Errors.ToArray()));
                }


                Logger.LogInfo(FlowLogs.RequestOperationStarted, args: model.GetType().Name);
                var requestResult = await request.DoAsync(model);

                Logger.LogInfo(FlowLogs.RequestOperationFinished, args: model.GetType().Name);

                if (validateResult.Warned)
                {
                    requestResult.Warns.AddRange(validateResult.Warns);
                }

                Logger.LogInfo(FlowLogs.RequestFinished, args: model.GetType().Name);
                return(requestResult);
            }
            catch (Exception ex)
            {
                Logger.LogError(FlowLogs.ExceptionOccured, ex.Message);
                return(FlowResult <TResultModel> .Failed(new FlowError(FlowErrors.ErrorOccurred)));
            }
        }
        private async Task <FlowResult> ValidateInstanceAsync(IStateManager stateManager, MoveModel model)
        {
            var instanceSet = stateManager.GetFlowSet <FlowInstance>();

            var instance = await instanceSet.GetByIdAsync(model.InstanceId);

            if (instance == null)
            {
                return(FlowResult.Failed(
                           new FlowError(FlowErrors.ItemNotFound, args: nameof(FlowInstance))));
            }

            if (instance.Active == false)
            {
                return(FlowResult.Failed(new FlowError(FlowErrors.InstanceIsInactive)));
            }

            return(FlowResult.Success);
        }
Exemple #17
0
        public async Task <FlowResult <FlowStep> > DisableCurrentStepAsync(Guid instanceId)
        {
            var set         = StateManager.GetFlowSet <FlowStep>();
            var instanceSet = StateManager.GetFlowSet <FlowInstance>();

            var instance = await instanceSet.GetByIdAsync(instanceId);

            if (instance == null)
            {
                return(FlowResult <FlowStep>
                       .Failed(new FlowError(FlowErrors.ItemNotFound, nameof(instance))));
            }

            var currentStep = await set.FirstOrDefaultAsync(x => x.InstanceId.Equals(instanceId) && x.IsCurrent);

            currentStep.IsCurrent = false;
            var updateResult = await set.UpdateAsync(currentStep);

            return(FlowResult <FlowStep> .Successful(updateResult));
        }
Exemple #18
0
        public async Task <FlowResult <FlowType> > GetTypeByIdAsync(Guid id)
        {
            try
            {
                Logger.LogInfo("try to get a type of flow by id.");
                var typeSet  = StateManager.GetFlowSet <FlowType>();
                var stateSet = StateManager.GetFlowSet <FlowState>();
                var query    = from type in typeSet.GetAll()
                               join state in stateSet.GetAll() on type.Id equals state.TypeId into states
                               where type.Id.Equals(id)
                               select new FlowType()
                {
                    CreatedAt         = type.CreatedAt,
                    Deleted           = type.Deleted,
                    EntityPayloadType = type.EntityPayloadType,
                    EntityType        = type.EntityType,
                    Id         = type.Id,
                    ModifiedAt = type.ModifiedAt,
                    Name       = type.Name,
                    States     = states.ToList()
                };
                var flowType = await typeSet.FirstOrDefaultAsync(query);

                if (flowType == null)
                {
                    Logger.LogWarning("type not exist.");
                    return(FlowResult <FlowType> .Failed(
                               new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowType))));
                }
                var result = new FlowResult <FlowType>();
                result.SetResult(flowType);
                Logger.LogInfo($"type with id '{flowType.Id}' fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <FlowType> .Failed(new FlowError(ex.Message)));
            }
        }
        public async Task <FlowResult <IEnumerable <FlowState> > > GetStatesByTypeIdAsync(Guid flowTypeId)
        {
            try
            {
                Logger.LogInfo($"try to get states of a flow type by id '{flowTypeId}'.");
                var stateSet = StateManager.GetFlowSet <FlowState>();
                var query    = stateSet.GetAll()
                               .Where(x => x.TypeId == flowTypeId);

                var states = await stateSet.ToListAsync(query);

                var result = new FlowResult <IEnumerable <FlowState> >();
                result.SetResult(states);
                Logger.LogInfo($"list of flow states of flow type with id '{flowTypeId}' has been fetched.");
                return(result);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message);
                return(FlowResult <IEnumerable <FlowState> > .Failed(new FlowError(ex.Message)));
            }
        }
Exemple #20
0
        public async Task <FlowResult <IEnumerable <FlowStep> > > GetInstanceStepsAsync(Guid instanceId)
        {
            //Get current instance
            if (instanceId.GuidIsEmpty())
            {
                throw new ArgumentNullException(nameof(instanceId));
            }

            var instanceSet = StateManager.GetFlowSet <FlowInstance>();

            var targetInstance = await instanceSet.FirstOrDefaultAsync(x => x.Id.Equals(instanceId));

            if (targetInstance == null)
            {
                return(FlowResult <IEnumerable <FlowStep> >
                       .Failed(new FlowError(FlowErrors.ItemNotFound, args : nameof(FlowInstance))));
            }

            //Get all steps
            var stepSet = StateManager.GetFlowSet <FlowStep>();
            var steps   = await stepSet.GetAllAsync(x => x.InstanceId.Equals(targetInstance.Id));

            return(FlowResult <IEnumerable <FlowStep> > .Successful(steps));
        }