Ejemplo n.º 1
0
        public async Task Cleanup(IControllerMessageContext context, ConsumeResult consumeResult, Func <Task> next)
        {
            await next();

            if (!context.Get(ContextItems.FlowContext, out FlowContext flowContext))
            {
                return;
            }

            if (flowContext.ContinuationMetadata.MethodName != MethodSerializer.Serialize(context.Binding.Method))
            {
                // Do not call when the controller method was filtered, if the same message has two methods
                return;
            }

            if (flowContext.FlowStateLock != null)
            {
                if (!flowContext.IsStoredOrDeleted())
                {
                    // The exception strategy can set the consume result to Success. Instead, check if the yield point
                    // was handled. The flow provider ensures we only end up here in case of an exception.
                    await flowContext.FlowStateLock.DeleteFlowState();
                }

                flowContext.FlowStateLock.Dispose();
            }
        }
Ejemplo n.º 2
0
        private static async Task CallConvergeMethod(IControllerMessageContext context, string methodName, bool sync)
        {
            IYieldPoint yieldPoint;

            var method = context.Controller.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);

            if (method == null)
            {
                throw new ArgumentException($"Unknown converge method in controller {context.Controller.GetType().Name}: {methodName}");
            }

            if (sync)
            {
                yieldPoint = (IYieldPoint)method.Invoke(context.Controller, new object[] {});
            }
            else
            {
                yieldPoint = await(Task <IYieldPoint>) method.Invoke(context.Controller, new object[] { });
            }

            if (yieldPoint == null)
            {
                throw new YieldPointException($"Yield point is required in controller {context.Controller.GetType().Name} for converge method {methodName}");
            }

            var flowHandler = context.Config.DependencyResolver.Resolve <IFlowHandler>();
            await flowHandler.Execute(new FlowHandlerContext(context), yieldPoint);
        }
Ejemplo n.º 3
0
        public async Task Handle(IControllerMessageContext context, Func <Task> next)
        {
            if (context.Get(ContextItems.FlowContext, out FlowContext flowContext))
            {
                Newtonsoft.Json.JsonConvert.PopulateObject(flowContext.FlowState.Data, context.Controller);

                // Remove Continuation now because the IYieldPoint result handler will store the new state
                flowContext.FlowState.Continuations.Remove(flowContext.ContinuationID);
                var converge = flowContext.FlowState.Continuations.Count == 0 &&
                               flowContext.ContinuationMetadata.ConvergeMethodName != null;

                if (converge)
                {
                    // Indicate to the FlowBindingMiddleware that the state must not to be stored
                    context.Store(ContextItems.FlowIsConverging, null);
                }

                await next();

                if (converge)
                {
                    await CallConvergeMethod(context,
                                             flowContext.ContinuationMetadata.ConvergeMethodName,
                                             flowContext.ContinuationMetadata.ConvergeMethodSync);
                }
            }
            else
            {
                await next();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// </summary>
        public FlowHandlerContext(IControllerMessageContext source)
        {
            if (source == null)
            {
                return;
            }

            Config     = source.Config;
            Controller = source.Controller;
            Method     = source.Binding.Method;
            ControllerMessageContext = source;
        }
Ejemplo n.º 5
0
        private static async Task <FlowContext> EnrichWithFlowContext(IControllerMessageContext context)
        {
            if (context.Get(ContextItems.FlowContext, out FlowContext flowContext))
            {
                return(flowContext);
            }


            if (context.Properties.CorrelationId == null)
            {
                return(null);
            }

            if (!Guid.TryParse(context.Properties.CorrelationId, out var continuationID))
            {
                return(null);
            }

            var flowStore = context.Config.DependencyResolver.Resolve <IFlowStore>();

            var flowID = await flowStore.FindFlowID(continuationID);

            if (!flowID.HasValue)
            {
                return(null);
            }

            var flowStateLock = await flowStore.LockFlowState(flowID.Value);

            var flowState = await flowStateLock.GetFlowState();

            if (flowState == null)
            {
                return(null);
            }

            flowContext = new FlowContext
            {
                HandlerContext = new FlowHandlerContext(context),

                FlowStateLock = flowStateLock,
                FlowState     = flowState,

                ContinuationID       = continuationID,
                ContinuationMetadata = flowState.Continuations.TryGetValue(continuationID, out var continuation) ? continuation : null
            };

            // IDisposable items in the IMessageContext are automatically disposed
            context.Store(ContextItems.FlowContext, flowContext);
            return(flowContext);
        }
Ejemplo n.º 6
0
        private static Task HandleParallelResponse(IControllerMessageContext context)
        {
            if (context.Get <object>(ContextItems.FlowIsConverging, out _))
            {
                return(Task.CompletedTask);
            }

            var flowHandler = context.Config.DependencyResolver.Resolve <IFlowHandler>();

            return(flowHandler.Execute(new FlowHandlerContext(context), new DelegateYieldPoint(async flowContext =>
            {
                await flowContext.Store(context.Binding.QueueType == QueueType.Durable);
            })));
        }
Ejemplo n.º 7
0
        private async Task <bool> FilterAllowed(IControllerMessageContext context)
        {
            var allowed = false;
            await MiddlewareHelper.GoAsync(
                bindingInfo.FilterMiddleware,
                async (handler, next) => await handler.Filter(context, next),
                () =>
            {
                allowed = true;
                return(Task.CompletedTask);
            });

            return(allowed);
        }
Ejemplo n.º 8
0
        public async Task Filter(IControllerMessageContext context, Func <Task> next)
        {
            var flowContext = await EnrichWithFlowContext(context);

            if (flowContext?.ContinuationMetadata == null)
            {
                return;
            }

            if (flowContext.ContinuationMetadata.MethodName != MethodSerializer.Serialize(context.Binding.Method))
            {
                return;
            }

            await next();
        }
Ejemplo n.º 9
0
        private static Task HandleYieldPoint(IControllerMessageContext context, IYieldPoint yieldPoint)
        {
            var flowHandler = context.Config.DependencyResolver.Resolve <IFlowHandler>();

            return(flowHandler.Execute(new FlowHandlerContext(context), yieldPoint));
        }