Example #1
0
        public ProgrammableServiceContext Build()
        {
            var context = new ProgrammableServiceContext();



            if (_configuration.Storage == null)
            {
                _configuration.Storage = new DefaultProgrammableServiceStorage();
            }
            //NOTE: the ordering of the LOC below is extremely important since context.DataBagKey directly depends on Request.SessionId
            context.Request = _request;
            context.Store   = _configuration.Storage;
            var dataBag = new ProgrammableServiceDataBag(_configuration.Storage, context.DataBagKey);

            context.DataBag = dataBag;

            return(context);
        }
Example #2
0
        private async Task <ProgrammableServiceResponse> OnResponse(ProgrammableServiceContext context, ProgrammableServiceControllerInfo controllerInfo)
        {
            while (true)
            {
                var exists = await context.Store.Exists(context.NextRouteKey);

                if (!exists)
                {
                    throw new Exception("Session does not exist.");
                }

                var routeInfoJson = await context.Store.Get(context.NextRouteKey);

                var routeInfo = ProgrammableServiceRoute.FromJson(routeInfoJson);


                if (controllerInfo.TheType.Name.Equals(routeInfo.FullControllerName))
                {
                    if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName))
                    {
                        return(new ProgrammableServiceResponse
                        {
                            Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            Type = ProgrammableServiceActionType.Release.ToString("G"),
                            Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            DataType = ProgrammableServiceDataTypes.Display,
                            FieldType = ProgrammableServiceFieldTypes.Text
                        });
                    }
                }

                else if (!_controllerActivator.ControllerCollection.ContainsKey(routeInfo.FullControllerName))
                {
                    return(new ProgrammableServiceResponse
                    {
                        Message = $"Could not find controller \"{routeInfo.FullControllerName}\"",
                        Type = ProgrammableServiceActionType.Release.ToString("G"),
                        Label = $"Could not find controller \"{routeInfo.FullControllerName}\"",
                        DataType = ProgrammableServiceDataTypes.Display,
                        FieldType = ProgrammableServiceFieldTypes.Text
                    });
                }
                else
                {
                    controllerInfo = _controllerActivator.ControllerCollection[routeInfo.FullControllerName];

                    if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName))
                    {
                        return(new ProgrammableServiceResponse
                        {
                            Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            Type = ProgrammableServiceActionType.Release.ToString("G"),
                            Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            DataType = ProgrammableServiceDataTypes.Display,
                            FieldType = ProgrammableServiceFieldTypes.Text
                        });
                    }
                }



                var controller =
                    (ProgrammableServiceControllerBase)_serviceProvider.GetRequiredService(controllerInfo.TheType);

                controller.Request = context.Request;
                controller.DataBag = context.DataBag;

                controller.Data     = new Dictionary <string, string>();
                controller.FormData = await controller.GetFormData();

                var      methodInfo = controllerInfo.Methods[routeInfo.ActionName].Method;
                object[] args       = { };


                var sessionResumeKey = $"_sessionResume.{context.Request.Mobile}";

                ProgrammableServiceResponse response;
                if (context.Request.GetActionType() == ProgrammableServiceActionType.Initiation)
                {
                    if (_configuration.EnableResumeSession)
                    {
                        //check if previous session exists
                        var sessionResumeValStr = await context.Store.Get(sessionResumeKey);

                        var sessionResumeList =
                            JsonConvert.DeserializeObject <List <ResumeSessionInfo> >(sessionResumeValStr);

                        if (await context.Store.Exists(sessionResumeKey) && string.Equals(controllerInfo.TheType.Name, sessionResumeList.LastOrDefault()?.ControllerName))
                        {
                            //if the previous last entry  is an initiation session...then just continue....
                            if (sessionResumeList.LastOrDefault().UserRequest.GetActionType() == ProgrammableServiceActionType.Initiation)
                            {
                                response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args);
                            }
                            else
                            {
                                var previousSessionId = sessionResumeList.FirstOrDefault().UserRequest.SessionId;



                                var keys = await context.Store.GetKeys();


                                var keysWithPreviousSessionId = keys.Where(k => k.StartsWith(previousSessionId)).ToList();
                                //copy everything from the previous session to the new session
                                foreach (var key in keysWithPreviousSessionId)
                                {
                                    var previousValue = await context.Store.Get(key);

                                    await
                                    context.Store.Set(key.Replace(previousSessionId, context.Request.SessionId),
                                                      previousValue);
                                }
                                controller.FormData = await controller.GetFormData(); //important step, if not, FormData is always NULL


                                var sessionResumeMethod = controllerInfo.Methods.Values.FirstOrDefault(m => m.IsSessionResumeMethod);

                                if (sessionResumeMethod == null)
                                {
                                    throw new Exception($"no method found that has HandleResumeSession attribute");
                                }

                                await context.Store.Delete(sessionResumeKey); //so we don't have chaff data for this user

                                response = await(Task <ProgrammableServiceResponse>) sessionResumeMethod.Method.Invoke(controller, new [] { sessionResumeList });
                            }
                        }
                        else
                        {
                            //just call the initiation handler...
                            response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args);
                        }
                    }
                    else
                    {
                        response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args);
                    }
                }
                else
                {
                    response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args);
                }



                if (!response.IsRelease)
                {
                    if (!response.IsRedirect)
                    {
                        if (_configuration.EnableResumeSession)
                        {
                            List <ResumeSessionInfo> sessionResumeList;

                            if (await context.Store.Exists(sessionResumeKey))
                            {
                                var sessionResumeValStr = await context.Store.Get(sessionResumeKey);

                                sessionResumeList =
                                    JsonConvert.DeserializeObject <List <ResumeSessionInfo> >(sessionResumeValStr);

                                sessionResumeList.Add(new ResumeSessionInfo
                                {
                                    UserRequest     = context.Request,
                                    ServiceResponse = response,
                                    MethodName      = methodInfo.Name,
                                    ControllerName  = controllerInfo.TheType.Name
                                });
                            }
                            else
                            {
                                sessionResumeList = new List <ResumeSessionInfo> {
                                    new ResumeSessionInfo
                                    {
                                        UserRequest     = context.Request,
                                        ServiceResponse = response,
                                        MethodName      = methodInfo.Name,
                                        ControllerName  = controllerInfo.TheType.Name
                                    }
                                };
                            }

                            await context.Store.Set(sessionResumeKey, JsonConvert.SerializeObject(sessionResumeList));
                        }
                    }
                    await context.Store.Set(context.NextRouteKey, response.NextRoute);
                }
                else
                {
                    if (_configuration.EnableResumeSession)
                    {
                        await context.Store.Delete(sessionResumeKey);
                    }
                }

                if (response.IsRedirect)
                {
                    continue;
                }

                return(response);
            }
        }
Example #3
0
        private async Task <ProgrammableServiceResponse> OnResponse(ProgrammableServiceContext context, ProgrammableServiceControllerInfo controllerInfo)
        {
            while (true)
            {
                var exists = await context.Store.Exists(context.NextRouteKey);

                if (!exists)
                {
                    throw new Exception("Session does not exist.");
                }

                var routeInfoJson = await context.Store.Get(context.NextRouteKey);

                var routeInfo = ProgrammableServiceRoute.FromJson(routeInfoJson);


                if (controllerInfo.TheType.Name.Equals(routeInfo.FullControllerName))
                {
                    if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName))
                    {
                        return(new ProgrammableServiceResponse
                        {
                            Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            Type = ProgrammableServiceActionType.Release.ToString("G"),
                            Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            DataType = ProgrammableServiceDataTypes.Display,
                            FieldType = ProgrammableServiceFieldTypes.Text
                        });
                    }
                }

                else if (!_controllerActivator.ControllerCollection.ContainsKey(routeInfo.FullControllerName))
                {
                    return(new ProgrammableServiceResponse
                    {
                        Message = $"Could not find controller \"{routeInfo.FullControllerName}\"",
                        Type = ProgrammableServiceActionType.Release.ToString("G"),
                        Label = $"Could not find controller \"{routeInfo.FullControllerName}\"",
                        DataType = ProgrammableServiceDataTypes.Display,
                        FieldType = ProgrammableServiceFieldTypes.Text
                    });
                }
                else
                {
                    controllerInfo = _controllerActivator.ControllerCollection[routeInfo.FullControllerName];

                    if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName))
                    {
                        return(new ProgrammableServiceResponse
                        {
                            Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            Type = ProgrammableServiceActionType.Release.ToString("G"),
                            Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist",
                            DataType = ProgrammableServiceDataTypes.Display,
                            FieldType = ProgrammableServiceFieldTypes.Text
                        });
                    }
                }



                var controller =
                    (ProgrammableServiceControllerBase)_serviceProvider.GetRequiredService(controllerInfo.TheType);

                controller.Request = context.Request;
                controller.DataBag = context.DataBag;

                controller.Data     = new Dictionary <string, string>();
                controller.FormData = await controller.GetFormData();

                var      methodInfo = controllerInfo.Methods[routeInfo.ActionName].Method;
                object[] args       = { };
                var      response   = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args);


                if (!response.IsRelease)
                {
                    await context.Store.Set(context.NextRouteKey, response.NextRoute);
                }

                if (response.IsRedirect)
                {
                    continue;
                }

                return(response);
            }
        }