public void Run_With_Plan_Payload_Second_Run()
        {
            var configureUrl     = GetTerminalConfigureUrl();
            var requestActionDTO = CreateRequestActivityFixture();
            var dataDTO          = new Fr8DataDTO {
                ActivityDTO = requestActionDTO
            };

            dataDTO.ActivityDTO = HttpPostAsync <Fr8DataDTO, ActivityDTO>(configureUrl, dataDTO).Result;
            SetDuration(dataDTO.ActivityDTO);
            var runUrl           = GetTerminalRunUrl();
            var operationalState = new OperationalStateCM();

            operationalState.CallStack.PushFrame(new OperationalStateCM.StackFrame {
                CurrentActivityExecutionPhase = OperationalStateCM.ActivityExecutionPhase.ProcessingChildren
            });
            operationalState.CallStack.PushFrame(new OperationalStateCM.StackFrame {
                CurrentActivityExecutionPhase = OperationalStateCM.ActivityExecutionPhase.WasNotExecuted
            });
            operationalState.CallStack.StoreLocalData("Delay", "suspended");
            AddOperationalStateCrate(dataDTO, operationalState);

            var runResponse = HttpPostAsync <Fr8DataDTO, PayloadDTO>(runUrl, dataDTO).Result;

            Assert.NotNull(runResponse);
            var crateStorage          = Crate.GetStorage(runResponse);
            var operationalStateCrate = crateStorage.CrateContentsOfType <OperationalStateCM>().Single();

            Assert.AreEqual(ActivityResponse.Success.ToString(), operationalStateCrate.CurrentActivityResponse.Type);
        }
        public async void Run_With_Plan_Payload_Initial_Run()
        {
            var configureUrl     = GetTerminalConfigureUrl();
            var requestActionDTO = CreateRequestActivityFixture();

            var dataDTO = new Fr8DataDTO {
                ActivityDTO = requestActionDTO
            };

            var responseActionDTO = await HttpPostAsync <Fr8DataDTO, ActivityDTO>(configureUrl, dataDTO);

            var operationalState = new OperationalStateCM();

            operationalState.CallStack.PushFrame(new OperationalStateCM.StackFrame());
            AddOperationalStateCrate(dataDTO, operationalState);
            var runUrl = GetTerminalRunUrl();

            dataDTO.ActivityDTO = responseActionDTO;
            var runResponse = await HttpPostAsync <Fr8DataDTO, PayloadDTO>(runUrl, dataDTO);

            Assert.NotNull(runResponse);
            var crateStorage          = Crate.GetStorage(runResponse);
            var operationalStateCrate = crateStorage.CrateContentsOfType <OperationalStateCM>().Single();

            Assert.AreEqual(ActivityResponse.RequestSuspend.ToString(), operationalStateCrate.CurrentActivityResponse.Type);
        }
예제 #3
0
        /**********************************************************************************/

        public void Run(Guid id, ActivityExecutionMode executionMode, PayloadDTO payloadDto)
        {
            using (var storage = _crateManager.UpdateStorage(() => payloadDto.CrateStorage))
            {
                OperationalState = storage.CrateContentsOfType <OperationalStateCM>().First();
                Run(id, executionMode);
            }
        }
 public static void AddOperationalStateCrate(PayloadDTO payload)
 {
     using (var crateStorage = new CrateManager().GetUpdatableStorage(payload))
     {
         var operationalStatus = new OperationalStateCM();
         var operationsCrate   = Crate.FromContent("Operational Status", operationalStatus);
         crateStorage.Add(operationsCrate);
     }
 }
        private void UpdateOperationCrate(string errorMessage = null)
        {
            Storage.RemoveByManifestId((int)MT.OperationalStatus);
            var operationalStatus = new OperationalStateCM
            {
                CurrentActivityResponse = ActivityResponseDTO.Create(ActivityResponse.ExecuteClientActivity),
            };

            operationalStatus.CurrentActivityResponse.Body = "RunImmediately";

            var operationsCrate = Crate.FromContent("Operational Status", operationalStatus);

            Storage.Add(operationsCrate);
        }
예제 #6
0
        private string GetResponseMessage(OperationalStateCM response)
        {
            string             responseMsg = "";
            ResponseMessageDTO responseMessage;

            if (response != null && response.CurrentActivityResponse != null && response.CurrentActivityResponse.TryParseResponseMessageDTO(out responseMessage))
            {
                if (responseMessage != null && !string.IsNullOrEmpty(responseMessage.Message))
                {
                    responseMsg = "\n" + responseMessage.Message;
                }
            }

            return(responseMsg);
        }
        /**********************************************************************************/
        // Functions
        /**********************************************************************************/

        private void InitializeInternalState(ActivityContext activityContext, ContainerExecutionContext containerExecutionContext)
        {
            _activityContext           = activityContext;
            _containerExecutionContext = containerExecutionContext;

            if (_containerExecutionContext != null)
            {
                _operationalState = Payload.CrateContentsOfType <OperationalStateCM>().FirstOrDefault();

                if (_operationalState == null)
                {
                    throw new InvalidOperationException("Operational state crate is not found");
                }
            }

            InitializeInternalState();
        }
예제 #8
0
        /// <summary>
        /// New Process object
        /// </summary>
        /// <param name="planId"></param>
        /// <param name="envelopeId"></param>
        /// <returns></returns>
        public ContainerDO Create(IUnitOfWork uow, PlanDO curPlan, params Crate[] curPayload)
        {
            var containerDO = new ContainerDO {
                Id = Guid.NewGuid()
            };

            containerDO.PlanId = curPlan.Id;
            containerDO.Name   = curPlan.Name;
            containerDO.State  = State.Unstarted;

            using (var crateStorage = _crate.UpdateStorage(() => containerDO.CrateStorage))
            {
                if (curPayload?.Length > 0)
                {
                    foreach (var crate in curPayload)
                    {
                        if (crate != null && !crate.IsOfType <OperationalStateCM>())
                        {
                            crateStorage.Add(crate);
                        }
                    }
                }

                var operationalState = new OperationalStateCM();

                operationalState.CallStack.PushFrame(new OperationalStateCM.StackFrame
                {
                    NodeName = "Starting subplan",
                    NodeId   = curPlan.StartingSubPlanId,
                });

                crateStorage.Add(Crate.FromContent("Operational state", operationalState));
            }

            uow.ContainerRepository.Add(containerDO);

            uow.SaveChanges();

            EventManager.ContainerCreated(containerDO);

            return(containerDO);
        }
            /**********************************************************************************/
            // this method is for updating Container's payload with the payload that activity returns.
            // We store all information related to container exectution inside the OperationalStateCM crate.
            // Some of this information is internal like the call stack. Call stack is the replacement of the previously used Conatiner.CurrentPlanNodeId.
            // Ideally call stack and the related stuff should not be inside OperationalStateCM. It should be placed inside the container, not the payload.
            // But due to implementation details of activities like Loop, or TestAndBrach we have to store entire call stack inside the payload.
            // We can't allow activity to change frames sequence inside the call stack.
            // Allowing this is just like allowing one process to write into the memory of another without restrictions.
            // But once again, implementation details of the activities mentioned about requires us to grand some limited access to the stack frames: we allow activity to store some
            // custom data "binded" to the its own stack frame. But we still don't allow activity to rearrage stack frames, otherwise Hub will lose control over the execution.
            // The following methods exists to enfore described constrainsts: it allow to change  custom data, but do not allow rearranging the stack frames.
            // FR-3560 we also want to mark crates with the Id of activity that produced it and we don't want activities to break it
            private void SyncPayload(ICrateStorage activityPayloadStorage, IUpdatableCrateStorage containerStorage, string currentActivityId)
            {
                if (activityPayloadStorage == null)
                {
                    return;
                }
                //Save the info about crates that already existed in payload
                var containerCrateSources = containerStorage.Where(x => x.ManifestType.Id != (int)Fr8.Infrastructure.Data.Constants.MT.OperationalStatus)
                                            .ToDictionary(x => x.Id, x => x.SourceActivityId);

                // Update container payload with the payload returned from the activity.
                containerStorage.Replace(activityPayloadStorage);
                // Update source activity Id info for all crates and if it is a crate produced by current activity then mark it with its Id
                foreach (var crate in containerStorage.Where(x => x.ManifestType.Id != (int)Fr8.Infrastructure.Data.Constants.MT.OperationalStatus))
                {
                    string sourceActivityId;
                    crate.SourceActivityId = containerCrateSources.TryGetValue(crate.Id, out sourceActivityId) ? sourceActivityId : currentActivityId;
                }
                // get OperationalStateCM after update.
                _operationalState = GetOperationalState(containerStorage);

                //_operationalState.CallStack.TopFrame.LocalData - is the data activity wants to store within the stack frame
                // store this data in the variable
                var localData = _operationalState.CallStack.TopFrame?.LocalData;

                // and replace call stack wihtin OperationalStateCM with the call stack Hub is using for this exectuion session.
                _operationalState.CallStack = _callStack;

                // We are 100% call stack is correct and was not corrupted by the activity.
                // But now we lost the data that activity asked us to persist within the stack frame.
                // Restore this data.
                if (_callStack.Count > 0)
                {
                    _callStack.TopFrame.LocalData = localData;
                }
            }
 public void AddOperationalStateCrate(Fr8DataDTO dataDTO, OperationalStateCM operationalState)
 {
     AddPayloadCrate(dataDTO, operationalState, "Operational Status");
 }
            /**********************************************************************************/
            // See https://maginot.atlassian.net/wiki/display/DDW/New+container+execution+logic for details
            public async Task Run()
            {
                while (_callStack.Count > 0)
                {
                    if (_callStack.Count > MaxStackSize)
                    {
                        throw new Exception($"Container execution stack overflow. Container: {_container.Id}. PlanId: {_container.PlanId}.");
                    }

                    var topFrame    = _callStack.TopFrame;
                    var currentNode = _uow.PlanRepository.GetById <PlanNodeDO>(topFrame.NodeId);

                    if (currentNode == null)
                    {
                        throw new Exception($"PlanNode with id: {topFrame.NodeId} was not found. Container: {_container.Id}. PlanId: {_container.PlanId}.");
                    }

                    try
                    {
                        try
                        {
                            using (var payloadStorage = _crate.UpdateStorage(() => _container.CrateStorage))
                            {
                                _operationalState = GetOperationalState(payloadStorage);

                                _operationalState.CallStack = _callStack;
                                // reset current activity response
                                _operationalState.CurrentActivityResponse = null;
                                // update container's payload
                                payloadStorage.Flush();

                                if (!_activityRateLimiter.CheckActivityExecutionRate(currentNode.Fr8AccountId))
                                {
                                    _callStack.Clear();
                                    _container.State = State.Failed;
                                    return;
                                }

                                if (topFrame.CurrentActivityExecutionPhase == OperationalStateCM.ActivityExecutionPhase.WasNotExecuted)
                                {
                                    await ExecuteNode(currentNode, payloadStorage, ActivityExecutionMode.InitialRun);

                                    topFrame.CurrentActivityExecutionPhase = OperationalStateCM.ActivityExecutionPhase.ProcessingChildren;

                                    // process op codes
                                    if (!ProcessActivityResponse(_operationalState.CurrentActivityResponse, OperationalStateCM.ActivityExecutionPhase.WasNotExecuted, topFrame))
                                    {
                                        break;
                                    }

                                    continue;
                                }

                                var nextChild = GetNextChildActivity(topFrame, currentNode);

                                // if there is a child that has not being executed yet - add it for execution by pushing to the call stack
                                if (nextChild != null)
                                {
                                    AddNodeForExecution(nextChild.Id);
                                    topFrame.CurrentChildId = nextChild.Id;
                                }
                                // or run current activity in ReturnFromChildren mode
                                else
                                {
                                    if (currentNode.ChildNodes.Count > 0)
                                    {
                                        await ExecuteNode(currentNode, payloadStorage, ActivityExecutionMode.ReturnFromChildren);
                                    }

                                    _callStack.RemoveTopFrame();

                                    // process op codes
                                    if (!ProcessActivityResponse(_operationalState.CurrentActivityResponse, OperationalStateCM.ActivityExecutionPhase.ProcessingChildren, topFrame))
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        catch
                        {
                            _container.State = State.Failed;
                            throw;
                        }
                        finally
                        {
                            _uow.SaveChanges();
                        }
                    }
                    catch (ErrorResponseException e)
                    {
                        throw new ActivityExecutionException(e.ContainerDTO, Mapper.Map <ActivityDO, ActivityDTO>((ActivityDO)currentNode), e.Message, e);
                    }
                    catch (InvalidTokenRuntimeException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        var curActivity = currentNode as ActivityDO;

                        if (curActivity != null)
                        {
                            var activityDTO = Mapper.Map <ActivityDO, ActivityDTO>(curActivity);
                            activityDTO.ActivityTemplate = Mapper.Map <ActivityTemplateSummaryDTO>(_uow.ActivityTemplateRepository.GetByKey(curActivity.ActivityTemplateId));
                            throw new ActivityExecutionException(Mapper.Map <ContainerDO, ContainerDTO>(_container), activityDTO, string.Empty, e);
                        }

                        throw;
                    }
                }

                if (_container.State == State.Executing)
                {
                    _container.State = State.Completed;
                    _uow.SaveChanges();
                }
            }
예제 #12
0
        private static FieldDTO FindField(OperationalStateCM operationalState, Crate crate, string fieldKey)
        {
            object searchArea;
            //let's check if we are in a loop
            //and this is a loop data?
            //check if this crate is loop related
            var loopState = operationalState.CallStack.FirstOrDefault(x =>
            {
                if (x.LocalData?.Type == "Loop")
                {
                    var loopStatus = x.LocalData.ReadAs <OperationalStateCM.LoopStatus>();

                    if (loopStatus != null && loopStatus.CrateManifest.CrateDescriptions[0].Label == crate.Label && loopStatus.CrateManifest.CrateDescriptions[0].ManifestType == crate.ManifestType.Type)
                    {
                        return(true);
                    }
                }

                return(false);
            });

            if (loopState != null) //this is a loop related data request
            {
                searchArea = GetDataListItem(crate, loopState.LocalData.ReadAs <OperationalStateCM.LoopStatus>().Index);
            }
            else
            {
                //hmmm this is a regular data request
                //lets search in complete crate
                searchArea = crate;
                //if we have a StandardTableDataCM and we are not in the loop and crate has Headers - we should search next row
                if (crate.IsOfType <StandardTableDataCM>())
                {
                    var tableCrate = crate.Get <StandardTableDataCM>();
                    if (tableCrate.FirstRowHeaders && tableCrate.Table.Count > 1)
                    {
                        //TODO it is weird to get just first row of table data while searching for a field
                        //note: GetDataListItem function skips header
                        TableRowDTO row = GetDataListItem(crate, 0) as TableRowDTO;
                        if (row != null)
                        {
                            return(row.Row.FirstOrDefault(a => a.Cell.Key == fieldKey)?.Cell);
                        }
                    }
                }
            }

            if (searchArea is Crate)
            {
                if (((Crate)searchArea).IsKnownManifest)
                {
                    searchArea = ((Crate)searchArea).Get();
                }
                else
                {
                    return(null);
                }
            }

            //we should find first related field and return
            var fields     = Fr8ReflectionHelper.FindFieldsRecursive(searchArea);
            var fieldMatch = fields.FirstOrDefault(f => f.Key == fieldKey);

            //let's return first match
            return(fieldMatch);
        }
예제 #13
0
        public override async Task FollowUp()
        {
            var activityTemplates = (await HubCommunicator.GetActivityTemplates(null, true))
                                    .Select(Mapper.Map <ActivityTemplateDO>)
                                    .ToList();

            try
            {
                var continueClicked = false;
                Storage.Remove <StandardQueryCM>();
                await UpdatePlanName();

                var queryCrate = ExtractQueryCrate(Storage);
                Storage.Add(queryCrate);

                var continueButton = GetControl <Button>("Continue");
                if (continueButton != null)
                {
                    continueClicked = continueButton.Clicked;

                    if (continueButton.Clicked)
                    {
                        continueButton.Clicked = false;
                    }
                }

                if (continueClicked)
                {
                    ActivityPayload.ChildrenActivities.Clear();

                    var queryFr8WarehouseActivityTemplate = activityTemplates
                                                            .FirstOrDefault(x => x.Name == "Query_Fr8_Warehouse");
                    if (queryFr8WarehouseActivityTemplate == null)
                    {
                        return;
                    }

                    var queryFr8WarehouseTemplate = await HubCommunicator.GetActivityTemplate("terminalFr8Core", "Query_Fr8_Warehouse");

                    var queryFr8WarehouseAction = await HubCommunicator.AddAndConfigureChildActivity(ActivityPayload, queryFr8WarehouseTemplate);

                    var crateStorage = queryFr8WarehouseAction.CrateStorage;

                    var upstreamManifestTypes = crateStorage
                                                .CrateContentsOfType <KeyValueListCM>(x => x.Label == "Upstream Crate ManifestType List")
                                                .FirstOrDefault();

                    var controls = crateStorage
                                   .CrateContentsOfType <StandardConfigurationControlsCM>()
                                   .FirstOrDefault();

                    var radioButtonGroup = controls
                                           .FindByName <RadioButtonGroup>("QueryPicker");

                    UpstreamCrateChooser upstreamCrateChooser = null;
                    if (radioButtonGroup != null &&
                        radioButtonGroup.Radios.Count > 0 &&
                        radioButtonGroup.Radios[0].Controls.Count > 0)
                    {
                        upstreamCrateChooser = radioButtonGroup.Radios[0].Controls[0] as UpstreamCrateChooser;
                    }

                    if (upstreamCrateChooser != null)
                    {
                        if (upstreamManifestTypes != null)
                        {
                            upstreamCrateChooser.SelectedCrates[0].ManifestType.selectedKey = upstreamManifestTypes.Values[0].Key;
                            upstreamCrateChooser.SelectedCrates[0].ManifestType.Value       = upstreamManifestTypes.Values[0].Value;
                        }

                        upstreamCrateChooser.SelectedCrates[0].Label.selectedKey = QueryCrateLabel;
                        upstreamCrateChooser.SelectedCrates[0].Label.Value       = QueryCrateLabel;
                    }

                    queryFr8WarehouseAction = await HubCommunicator.ConfigureChildActivity(
                        ActivityPayload,
                        queryFr8WarehouseAction
                        );

                    Storage.RemoveByManifestId((int)MT.OperationalStatus);
                    var operationalStatus = new OperationalStateCM();
                    operationalStatus.CurrentActivityResponse =
                        ActivityResponseDTO.Create(ActivityResponse.ExecuteClientActivity);
                    operationalStatus.CurrentActivityResponse.Body = "RunImmediately";
                    var operationsCrate = Crate.FromContent("Operational Status", operationalStatus);
                    Storage.Add(operationsCrate);
                }
            }
            catch (Exception)
            {
            }
        }
 public void AddOperationalStateCrate(ActivityDTO activityDTO, OperationalStateCM operationalState)
 {
     AddPayloadCrate(activityDTO, operationalState, "Operational Status");
 }
예제 #15
0
        public OperationalStateCM GetOperationalState(ICrateStorage crateStorage)
        {
            OperationalStateCM curOperationalState = crateStorage.CrateContentsOfType <OperationalStateCM>().Single();

            return(curOperationalState);
        }
예제 #16
0
 public Crate CreateOperationalStatusCrate(string label, OperationalStateCM operationalStatus)
 {
     return(Crate.FromContent(label, operationalStatus));
 }