private static IReadOnlyList <OnDeviceDecisioningRule> GetDetailsRules(RequestDetailsUnion details, OnDeviceDecisioningRuleSet ruleSet)
 {
     return(details.Match(
                _ => GetPageLoadRules(ruleSet),
                mboxRequest => GetMboxRules(ruleSet, mboxRequest),
                viewRequest => GetViewRules(ruleSet, viewRequest)));
 }
        private static bool HandleResult(
            IDictionary <string, object> consequence,
            OnDeviceDecisioningRule rule,
            RequestDetailsUnion details,
            PrefetchResponse prefetchResponse,
            ExecuteResponse executeResponse,
            IList <Notification> notifications,
            string globalMbox = "target-global-mbox")
        {
            if (consequence == null || consequence.Count == 0)
            {
                return(false);
            }

            consequence.TryGetValue(Name, out var nameObject);
            var consequenceName = (string)nameObject;

            consequence.TryGetValue(Options, out var optionsObject);
            var consequenceOptions = (List <Option>)optionsObject;

            consequence.TryGetValue(Metrics, out var metricsObject);
            var consequenceMetrics = GetMetrics(metricsObject);

            if (executeResponse != null)
            {
                var notification = CreateNotification(details, consequenceOptions, globalMbox);
                notifications.Add(notification);
            }

            return(details.Match(
                       _ => HandlePageLoad(prefetchResponse, executeResponse, consequenceOptions, consequenceMetrics),
                       mboxRequest => HandleMboxRequest(prefetchResponse, executeResponse, mboxRequest, consequenceOptions, consequenceMetrics),
                       _ => HandleViewRequest(prefetchResponse, consequenceName, consequenceOptions, consequenceMetrics)));
        }
 private static void UnhandledResponse(RequestDetailsUnion details, PrefetchResponse prefetchResponse, ExecuteResponse executeResponse)
 {
     _ = details.Match <object>(
         _ => UnhandledPageLoadResponse(prefetchResponse, executeResponse),
         mboxRequest => UnhandledMboxResponse(prefetchResponse, executeResponse, mboxRequest),
         _ => UnhandledViewResponse(prefetchResponse));
 }
예제 #4
0
        public IDictionary <string, object> ExecuteRule(
            IDictionary <string, object> localContext,
            RequestDetailsUnion details,
            string visitorId,
            OnDeviceDecisioningRule rule,
            ISet <string> responseTokens)
        {
            localContext.Remove(Allocation);
            localContext.Add(Allocation, this.ComputeAllocation(visitorId, rule));
            var matched = this.EvaluateRule((JObject)rule.Condition, localContext.ToExpandoObject());

            if (!matched)
            {
                return(null);
            }

            return(this.ReplaceCampaignMacros(rule, this.GetConsequence(responseTokens, rule, localContext), details));
        }
        private static Notification CreateNotification(RequestDetailsUnion details, List <Option> options, string globalMbox)
        {
            var id           = Guid.NewGuid().ToString();
            var impressionId = Guid.NewGuid().ToString();
            var timestamp    = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var tokens       = options == null ? new List <string>() : options.Select(option => option.EventToken).ToList();
            var notification = new Notification(id: id, type: MetricType.Display, impressionId: impressionId, timestamp: timestamp, tokens: tokens);

            return(details.Match(
                       _ =>
            {
                notification.Mbox = new NotificationMbox(globalMbox);
                return notification;
            }, mboxRequest =>
            {
                notification.Mbox = new NotificationMbox(mboxRequest.Name);
                return notification;
            }, viewRequest =>
            {
                notification.View = new NotificationView(viewRequest.Name, viewRequest.Key);
                return notification;
            }));
        }
예제 #6
0
        private IDictionary <string, object> ReplaceCampaignMacros(OnDeviceDecisioningRule rule, IDictionary <string, object> consequence, RequestDetailsUnion details)
        {
            if (consequence == null || !consequence.ContainsKey(DecisioningDetailsExecutor.Options))
            {
                return(consequence);
            }

            var campaignMacroReplacer = new CampaignMacroReplacer(rule, consequence, details);

            consequence[DecisioningDetailsExecutor.Options] = campaignMacroReplacer.GetOptions();
            return(consequence);
        }
        public void ExecuteDetails(
            TargetDeliveryRequest deliveryRequest,
            IDictionary <string, object> localContext,
            string visitorId,
            ISet <string> responseTokens,
            TraceHandler traceHandler,
            OnDeviceDecisioningRuleSet ruleSet,
            RequestDetailsUnion details,
            PrefetchResponse prefetchResponse,
            ExecuteResponse executeResponse,
            IList <Notification> notifications)
        {
            traceHandler?.UpdateRequest(deliveryRequest, details, executeResponse != null);
            var rules = GetDetailsRules(details, ruleSet);

            if (rules == null)
            {
                UnhandledResponse(details, prefetchResponse, executeResponse, traceHandler);
                return;
            }

            var propertyToken      = deliveryRequest.DeliveryRequest.Property?.Token;
            var handledAtLeastOnce = false;
            var skipKeySet         = new HashSet <string>();

            foreach (var rule in rules)
            {
                if (PropertyTokenMismatch(rule.PropertyTokens, propertyToken))
                {
                    continue;
                }

                if (rule.RuleKey != null && skipKeySet.Contains(rule.RuleKey))
                {
                    continue;
                }

                var consequence = this.ruleExecutor.ExecuteRule(localContext, details, visitorId, rule, responseTokens, traceHandler);
                if (!HandleResult(consequence, rule, details, prefetchResponse, executeResponse, notifications, traceHandler, ruleSet.GlobalMbox))
                {
                    continue;
                }

                handledAtLeastOnce = true;
                if (rule.RuleKey != null)
                {
                    skipKeySet.Add(rule.RuleKey);
                }

                if (details.Match(
                        _ => false,
                        _ => true,
                        _ => false))
                {
                    break;
                }
            }

            if (!handledAtLeastOnce)
            {
                UnhandledResponse(details, prefetchResponse, executeResponse, traceHandler);
            }
        }