Ejemplo n.º 1
0
        private static RuleExecutionResponseType ParseResponseType(RuleExecutionResponse response)
        {
            // take response type string and convert it to enum

            var responseTypeEnum = (RuleExecutionResponseType)0;

            if (String.IsNullOrEmpty(response.ResponseType))
            {
                responseTypeEnum      = RuleExecutionResponseType.NotSpecified;
                response.ResponseType = RuleExecutionResponseType.NotSpecified.ToString();
            }
            else
            {
                var responseTypesList = response.ResponseType.Split(Delimeter.ToCharArray()).ToList();
                foreach (var responseType in responseTypesList)
                {
                    if (!Enum.IsDefined(typeof(RuleExecutionResponseType), responseType))
                    {
                        throw new Exception("The requested response type is not a valid option.  Invalid response type: " + responseType);
                    }
                    responseTypeEnum |= (RuleExecutionResponseType)Enum.Parse(typeof(RuleExecutionResponseType), responseType);
                }
            }

            return(responseTypeEnum);
        }
Ejemplo n.º 2
0
        public static void HandleWebException(Exception ex, RuleExecutionResponse response)
        {
            try
            {
                LogException(ex);
            }
            catch (Exception logEx)
            {
                // do not let logging failures affect the ability to return a response
                response.Error += String.Format("\r\n\r\nError logging failed on server: {0}", logEx.Message);
            }

            if (WebOperationContext.Current.IncomingRequest.Method == "POST")
            {
                var debug             = OperationContext.Current.Host.Description.Behaviors.Find <ServiceDebugBehavior>();
                var includeStackTrace = (debug != null && debug.IncludeExceptionDetailInFaults);
                response.Error = includeStackTrace ? ex.ToString() : ex.Message;

                //WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
                //WebOperationContext.Current.OutgoingResponse.StatusDescription = WebUtility.HtmlEncode(ex.Message.Replace("\n", " ").Replace("\r", " "));
                WebOperationContext.Current.OutgoingResponse.ContentType = ResponseContentType;
            }
            else
            {
                // rethrow on GET verb
                throw ex;
            }
        }
Ejemplo n.º 3
0
        private static void ProcessResponseTypes(bool isPost, RuleExecutionResponse response, RuleExecutionResponseType responseTypeEnum, out bool useResponseContainer, out string contentType)
        {
            var responseTypeCount = (response.ResponseType == null) ? 0 : response.ResponseType.Split(Delimeter.ToCharArray()).Length;
            var usingXml          = false;
            var usingReport       = false;

            useResponseContainer = false;

            // if it is a post, we always return the RuleExecutionResponse
            if (isPost)
            {
                contentType          = ResponseContentType;
                useResponseContainer = true;
                return;
            }

            if (
                responseTypeEnum.HasFlag(RuleExecutionResponseType.NotificationsXml) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.EntityXml) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.ValidationsXml) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.RuleExecutionResponseXml) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.NotSpecified)
                )
            {
                usingXml = true;
            }

            if (
                responseTypeEnum.HasFlag(RuleExecutionResponseType.NotificationsText) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.PerformanceStatisticsReport) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.RuleExecutionReport) ||
                responseTypeEnum.HasFlag(RuleExecutionResponseType.ValidationsText)
                )
            {
                usingReport = true;
            }

            // special case for allowing notification and validation text
            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.NotificationsText) &&
                responseTypeEnum.HasFlag(RuleExecutionResponseType.ValidationsText) && responseTypeCount == 2)
            {
                contentType = ResponseContentType;
                return;
            }

            if ((usingXml && usingReport) || (usingReport && responseTypeCount > 1))
            {
                throw new Exception("The requested response types are not a valid combination.  Invalid response types: " + response.ResponseType.Replace(Delimeter, ", "));
            }

            contentType = usingReport ? "text/html" : ResponseContentType;
            if (responseTypeCount > 1 || responseTypeEnum.HasFlag(RuleExecutionResponseType.RuleExecutionResponseXml) || responseTypeEnum.HasFlag(RuleExecutionResponseType.NotSpecified))
            {
                useResponseContainer = true;
            }
        }
Ejemplo n.º 4
0
 public static void SetResponseValidations(RuleSession session, RuleExecutionResponse response)
 {
     if (session.GetValidations().Count > 0)
     {
         response.Validations = new List <Validation>();
         foreach (var val in session.GetValidations())
         {
             var validation = new Validation {
                 Message = val.Target + " - " + val.Message
             };
             response.Validations.Add(validation);
         }
     }
 }
Ejemplo n.º 5
0
 public static void SetResponseNotifications(RuleSession session, RuleExecutionResponse response)
 {
     if (session.GetNotifications().Count > 0)
     {
         response.Notifications = new List <Notification>();
         foreach (var note in session.GetNotifications())
         {
             var notification = new Notification {
                 Message = note.Message, Type = note.Type.ToString()
             };
             response.Notifications.Add(notification);
         }
     }
 }
Ejemplo n.º 6
0
        public static void SetResponseText(RuleSession session, Entity entity, RuleExecutionResponse response)
        {
            response.ResponseText = "";
            var isPost = WebOperationContext.Current.IncomingRequest.Method == "POST";

            // force local cache expiration for future requests
            WebOperationContext.Current.OutgoingResponse.Headers.Add(HttpResponseHeader.Expires, DateTime.Now.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'"));
            WebOperationContext.Current.OutgoingResponse.Headers.Add(HttpResponseHeader.CacheControl, "no-cache");

            var responseTypeEnum = ParseResponseType(response);

            // validate response types and set content type
            bool   useResponseContainer;
            string contentType;

            ProcessResponseTypes(isPost, response, responseTypeEnum, out useResponseContainer, out contentType);

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.EntityXml))
            {
                if (entity != null)
                {
                    var xml = GetEntityXml(entity);
                    if (useResponseContainer || isPost)
                    {
                        response.EntityXml = xml;
                    }
                    else
                    {
                        response.ResponseText = xml;
                    }
                }
                else
                {
                    response.ResponseText = "Warning: Entity is null or not found";
                }
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.NotificationsXml))
            {
                SetResponseNotifications(session, response);
                if (!useResponseContainer)
                {
                    response.ResponseText = Serialize(response.Notifications, "Notifications");
                }
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.ValidationsXml))
            {
                SetResponseValidations(session, response);
                if (!useResponseContainer)
                {
                    response.ResponseText = Serialize(response.Validations, "Validations");
                }
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.ExecutionLogXml))
            {
                var xml = GetExecutionLogXml(session.LastRuleExecutionLog);
                if (useResponseContainer || isPost)
                {
                    response.ExecutionLogXml = xml;
                }
                else
                {
                    response.ResponseText = xml;
                }
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.NotificationsText))
            {
                response.ResponseText += GetNotificationText(session);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.ValidationsText))
            {
                response.ResponseText += GetValidationText(session);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.ExecutionLogText))
            {
                response.ResponseText = GetExecutionLogText(session);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.RuleExecutionResponseXml) || responseTypeEnum.HasFlag(RuleExecutionResponseType.NotSpecified))
            {
                // always uses container
                response.EntityXml       = GetEntityXml(entity);
                response.ExecutionLogXml = GetExecutionLogXml(session.LastRuleExecutionLog);
                SetResponseNotifications(session, response);
                SetResponseValidations(session, response);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.RuleExecutionReport))
            {
                response.ResponseText = GetRuleExecutionReport(session, entity);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.PerformanceStatisticsReport))
            {
                response.ResponseText = GetPerformanceStatisticsReport(session);
            }

            if (responseTypeEnum.HasFlag(RuleExecutionResponseType.Invalid))
            {
                response.ResponseText = "Warning: Invalid ResponseType Specified";
                contentType           = ResponseContentType;
            }

            if (WebOperationContext.Current != null)
            {
                WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
            }

            if (useResponseContainer && !isPost)
            {
                response.ResponseText = Serialize(response);
            }
        }
        /// <summary>
        ///    Method used when performing a POST request and by public GET methods to centralize all rule execution.
        ///    Auto, explicit and independent rules can be executed in the method, based on the type of request specified.
        /// </summary>
        /// <param name="request">A RuleExecutionRequest that contains all execution information required to run rules.</param>
        /// <returns>RuleExecutionResponse</returns>
        public RuleExecutionResponse ExecuteRuleRequest(RuleExecutionRequest request)
        {
            var response = new RuleExecutionResponse();

            try
            {
                // get rule application using settings from web.config
                var ruleApp = GetRuleApp(request.RuleApp);

                using (var session = new RuleSession(ruleApp))
                {
                    // override end points
                    RuleServiceHelper.OverrideEndPoints(session, request);

                    // if the performance stats report was requested, turn on the details
                    if (request.ResponseType != null && request.ResponseType.Contains(RuleExecutionResponseType.PerformanceStatisticsReport.ToString()))
                    {
                        session.Settings.LogOptions = EngineLogOptions.SummaryStatistics | EngineLogOptions.DetailStatistics;
                    }

                    // if the execution report or execution log was requested, turn on the execution and state change settings
                    if (request.ResponseType != null && (request.ResponseType.Contains(RuleExecutionResponseType.RuleExecutionReport.ToString()) ||
                                                         request.ResponseType.Contains(RuleExecutionResponseType.ExecutionLogText.ToString()) ||
                                                         request.ResponseType.Contains(RuleExecutionResponseType.ExecutionLogXml.ToString())))
                    {
                        session.Settings.LogOptions = EngineLogOptions.Execution | EngineLogOptions.StateChanges;
                    }

                    response.ResponseType = request.ResponseType;

                    Entity entity = null;

                    if (!String.IsNullOrEmpty(request.Entity))
                    {
                        // if an entity was specified, this is an entity based rule set
                        entity = session.CreateEntity(request.Entity);

                        // if state was passed in, load it
                        if (!String.IsNullOrEmpty(request.EntityXml))
                        {
                            entity.ParseXml(request.EntityXml);
                        }

                        // if an explicit rule set was not specified, call ApplyRules
                        if (String.IsNullOrEmpty(request.RuleSet))
                        {
                            session.ApplyRules();
                        }
                        else
                        {
                            // this is an explicit rule set, if parameters were passed in, pass them to the explicit rule set
                            if (request.Parameters.Count > 0)
                            {
                                var parameters = BuildRuleSetParameters(request, session);
                                entity.ExecuteRuleSet(request.RuleSet, parameters.ToArray());
                            }
                            else
                            {
                                entity.ExecuteRuleSet(request.RuleSet);
                            }
                        }
                    }
                    else
                    {
                        // if no entity name was passed in, this is an independent rule set, pass parameters if applicable
                        if (request.Parameters.Count > 0)
                        {
                            var parameters = BuildRuleSetParameters(request, session);
                            session.ExecuteIndependentRuleSet(request.RuleSet, parameters.ToArray());
                        }
                        else
                        {
                            session.ExecuteIndependentRuleSet(request.RuleSet);
                        }
                    }

                    // if output entity was specified,
                    Entity returnEntity;
                    if (string.IsNullOrEmpty(request.ReturnEntity))
                    {
                        returnEntity = entity;
                    }
                    else
                    {
                        // retrieve output entity
                        returnEntity = RuleServiceHelper.GetEntityFromRuleSession(session, request.ReturnEntity);
                    }

                    // set the response text based on the request type
                    RuleServiceHelper.SetResponseText(session, returnEntity, response);
                }
            }
            catch (Exception ex)
            {
                RuleServiceHelper.HandleWebException(ex, response);
            }
            return(response);
        }