示例#1
0
        public static void RunForValidUserProperties(
            MessageCandidate messageCandidate,
            Func <object, ValueParseResult> parseFn,
            Action <string, object> fn)
        {
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.UserProperties)
            {
                string         formattedPropertyName = pair.Key;
                ObjectProperty objectProperty        = pair.Value;

                if (objectProperty.Origin == PropertyOrigin.SuperProperty)
                {
                    // Skip all non special super properties as they are not valid for people message
                    continue;
                }

                ValueParseResult result = parseFn(objectProperty.Value);
                if (!result.Success)
                {
                    continue;
                }

                fn(formattedPropertyName, result.Value);
            }
        }
        public static MessageBuildResult Build(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object distinctId,
            object alias)
        {
            MessageCandidate messageCandidate = TrackMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                null,
                distinctId,
                null,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>(2);

            message["event"] = "$create_alias";

            var properties = new Dictionary <string, object>(3);

            message["properties"] = properties;

            // token
            properties["token"] = messageCandidate.GetSpecialProperty(TrackSpecialProperty.Token).Value;

            // distinct_id
            ObjectProperty rawDistinctId = messageCandidate.GetSpecialProperty(TrackSpecialProperty.DistinctId);

            if (rawDistinctId == null)
            {
                return(MessageBuildResult.CreateFail($"'{TrackSpecialProperty.DistinctId}' is not set."));
            }

            ValueParseResult distinctIdParseResult = DistinctIdParser.Parse(rawDistinctId.Value);

            if (!distinctIdParseResult.Success)
            {
                return(MessageBuildResult.CreateFail(
                           $"Error parsing '{TrackSpecialProperty.DistinctId}'.", distinctIdParseResult.ErrorDetails));
            }

            properties["distinct_id"] = distinctIdParseResult.Value;

            // alias
            ValueParseResult aliasParseResult = DistinctIdParser.Parse(alias);

            if (!aliasParseResult.Success)
            {
                return(MessageBuildResult.CreateFail("Error parsing 'alias'. " + aliasParseResult.ErrorDetails));
            }
            properties["alias"] = aliasParseResult.Value;


            return(MessageBuildResult.CreateSuccess(message));
        }
示例#3
0
        public void When_SuperPropertiesAndRawPropertiesHasSameProperties_Then_RawPropertiesOverwritesSuperProperties()
        {
            var messageCandidate = new MessageCandidate(
                null,
                CreateSuperProperties(DistinctIdPropertyName, StringPropertyName, DecimalPropertyName),
                new Dictionary <string, object>
            {
                { DistinctIdPropertyName, DistinctId },
                { StringPropertyName, StringPropertyValue }
            },
                null,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.DistinctId);
            Assert.That(messageCandidate.SpecialProperties[TrackSpecialProperty.DistinctId].Value, Is.EqualTo(DistinctId));

            AssertUserProperties(
                messageCandidate.UserProperties,
                StringPropertyName,
                DecimalPropertyName);
            Assert.That(messageCandidate.UserProperties[StringPropertyName].Value, Is.EqualTo(StringPropertyValue));
            Assert.That(messageCandidate.UserProperties[DecimalPropertyName].Value, Is.Null);
        }
示例#4
0
        private void LogMessage <TState>(MessageCandidate <TState> candidate)
        {
            LoggingEvent loggingEvent = options.LoggingEventFactory.CreateLoggingEvent(candidate, logger, options);

            if (loggingEvent == null)
            {
                return;
            }

            this.logger.Log(loggingEvent);
        }
示例#5
0
        public static MessageCandidate CreateValidMessageCandidate(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config,
            out string errorMessage)
        {
            var messageCandidate = new MessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                PeopleSpecialPropertyMapper.RawNameToSpecialProperty);

            ObjectProperty tokenProp = messageCandidate.GetSpecialProperty(PeopleSpecialProperty.Token);

            if (tokenProp == null)
            {
                errorMessage = $"'{PeopleSpecialProperty.Token}' is not set.";
                return(null);
            }

            ValueParseResult tokenParseResult =
                PeopleSpecialPropertyParser.Parse(PeopleSpecialProperty.Token, tokenProp.Value);

            if (!tokenParseResult.Success)
            {
                errorMessage = $"Error parsing '{PeopleSpecialProperty.Token}'. {tokenParseResult.ErrorDetails}";
                return(null);
            }

            ObjectProperty distinctIdProp = messageCandidate.GetSpecialProperty(PeopleSpecialProperty.DistinctId);

            if (distinctIdProp == null)
            {
                errorMessage = $"'{PeopleSpecialProperty.DistinctId}' is not set.";
                return(null);
            }

            ValueParseResult distinctIdParseResult =
                PeopleSpecialPropertyParser.Parse(PeopleSpecialProperty.DistinctId, distinctIdProp.Value);

            if (!distinctIdParseResult.Success)
            {
                errorMessage = $"Error parsing '{PeopleSpecialProperty.DistinctId}'. {distinctIdParseResult.ErrorDetails}";
                return(null);
            }

            errorMessage = null;
            return(messageCandidate);
        }
        private static MessageBuildResult Build(
            string operation,
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config)
        {
            MessageCandidate messageCandidate = PeopleMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();
            var set     = new Dictionary <string, object>();

            message[operation] = set;

            // Special properties
            PeopleMessageBuilderBase.RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
                else
                {
                    set[specialPropertyName] = value;
                }
            });

            // User properties
            PeopleMessageBuilderBase.RunForValidUserProperties(
                messageCandidate,
                rawValue => GenericPropertyParser.Parse(rawValue, allowCollections: true),
                (formattedPropertyName, value) =>
            {
                set[formattedPropertyName] = value;
            });

            return(MessageBuildResult.CreateSuccess(message));
        }
示例#7
0
        public void When_AllInputsAreNull_Then_NoProperties()
        {
            var messageCandidate = new MessageCandidate(
                null,
                null,
                null,
                null,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            Assert.That(messageCandidate.SpecialProperties.Count, Is.EqualTo(0));
            Assert.That(messageCandidate.UserProperties.Count, Is.EqualTo(0));
        }
示例#8
0
        public static MessageBuildResult CreateMessage(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config,
            string actionName,
            Func <object, ValueParseResult> userPropertyParseFn)
        {
            MessageCandidate messageCandidate = CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();
            var action  = new Dictionary <string, object>();

            message[actionName] = action;

            // Special properties
            RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                // Ignore non-message specific special properties as they are not valid in profile update messages
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
            });

            // User properties
            RunForValidUserProperties(
                messageCandidate,
                userPropertyParseFn,
                (formattedPropertyName, value) =>
            {
                action[formattedPropertyName] = value;
            });

            return(MessageBuildResult.CreateSuccess(message));
        }
示例#9
0
        public void When_Token_Then_OnlyTokenIsSet()
        {
            var messageCandidate = new MessageCandidate(
                Token,
                null,
                null,
                null,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.Token);

            Assert.That(messageCandidate.UserProperties.Count, Is.EqualTo(0));
        }
示例#10
0
        public void When_DistinctId_Then_OnlyDistinctIdIsSet()
        {
            var messageCandidate = new MessageCandidate(
                null,
                null,
                null,
                DistinctId,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.DistinctId);

            Assert.That(messageCandidate.UserProperties.Count, Is.EqualTo(0));
        }
示例#11
0
        /// <inheritdoc/>
        public LoggingEvent CreateLoggingEvent <TState>(MessageCandidate <TState> messageCandidate, log4net.Core.ILogger logger, Log4NetProviderOptions options)
        {
            Type   callerStackBoundaryDeclaringType = typeof(LoggerExtensions);
            string message  = messageCandidate.Formatter(messageCandidate.State, messageCandidate.Exception);
            Level  logLevel = options.LogLevelTranslator.TranslateLogLevel(messageCandidate.LogLevel, options);

            if (logLevel == null || (string.IsNullOrEmpty(message) && messageCandidate.Exception == null))
            {
                return(null);
            }

            return(new LoggingEvent(
                       callerStackBoundaryDeclaringType: callerStackBoundaryDeclaringType,
                       repository: logger.Repository,
                       loggerName: logger.Name,
                       level: logLevel,
                       message: message,
                       exception: messageCandidate.Exception));
        }
示例#12
0
        public void When_RawProperties_Then_AllPropertiesSet()
        {
            var messageCandidate = new MessageCandidate(
                null,
                null,
                CreateRawProperties(DistinctIdPropertyName, StringPropertyName, DecimalPropertyName),
                null,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.DistinctId);

            AssertUserProperties(
                messageCandidate.UserProperties,
                StringPropertyName,
                DecimalPropertyName);
        }
        private void LogMessage(MessageCandidate candidate)
        {
            if (candidate.IsValid())
            {
                switch (candidate.LogLevel)
                {
                case LogLevel.Critical:
                    string overrideCriticalLevelWith = options.OverrideCriticalLevelWith;
                    if (!string.IsNullOrEmpty(overrideCriticalLevelWith) &&
                        overrideCriticalLevelWith.Equals(LogLevel.Critical.ToString(), StringComparison.OrdinalIgnoreCase))
                    {
                        this.log.Critical(candidate.Message, candidate.Exception);
                    }
                    else
                    {
                        this.log.Fatal(candidate.Message, candidate.Exception);
                    }

                    break;

                case LogLevel.Debug:
                    this.log.Debug(candidate.Message, candidate.Exception);
                    break;

                case LogLevel.Error:
                    this.log.Error(candidate.Message, candidate.Exception);
                    break;

                case LogLevel.Information:
                    this.log.Info(candidate.Message, candidate.Exception);
                    break;

                case LogLevel.Warning:
                    this.log.Warn(candidate.Message, candidate.Exception);
                    break;

                case LogLevel.Trace:
                    this.log.Trace(candidate.Message, candidate.Exception);
                    break;
                }
            }
        }
示例#14
0
        public void When_DistinctId_Then_DistinctIdOverwritesSuperPropertiesAndRawProperties()
        {
            var messageCandidate = new MessageCandidate(
                null,
                CreateSuperProperties(DistinctIdPropertyName),
                new Dictionary <string, object>
            {
                { DistinctIdPropertyName, DistinctId }
            },
                DistinctIdInt,
                null,
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.DistinctId);
            Assert.That(messageCandidate.SpecialProperties[TrackSpecialProperty.DistinctId].Value, Is.EqualTo(DistinctIdInt));

            Assert.That(messageCandidate.UserProperties.Count, Is.EqualTo(0));
        }
示例#15
0
        public static void RunForValidSpecialProperties(
            MessageCandidate messageCandidate,
            Action <string, bool, object> fn)
        {
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.SpecialProperties)
            {
                string         specialPropertyName = pair.Key;
                ObjectProperty objectProperty      = pair.Value;

                ValueParseResult result = PeopleSpecialPropertyParser.Parse(specialPropertyName, objectProperty.Value);
                if (!result.Success)
                {
                    continue;
                }

                bool isMessageSpecialProperty = PeopleSpecialProperty.IsMessageSpecialProperty(specialPropertyName);

                fn(specialPropertyName, isMessageSpecialProperty, result.Value);
            }
        }
示例#16
0
        public void When_ConfigHasNameFormatting_Then_AllUserPropetiesFormatted()
        {
            var messageCandidate = new MessageCandidate(
                null,
                CreateSuperProperties(DistinctIdPropertyName, "PropertyOne"),
                CreateRawProperties("PropertyTwo"),
                null,
                new MixpanelConfig {
                MixpanelPropertyNameFormat = MixpanelPropertyNameFormat.TitleCase
            },
                TrackSpecialPropertyMapper.RawNameToSpecialProperty);

            AssertSpecialProperties(
                messageCandidate.SpecialProperties,
                TrackSpecialProperty.DistinctId);

            AssertUserProperties(
                messageCandidate.UserProperties,
                "Property One",
                "Property Two");
        }
        // Message example:
        // {
        //     "$token": "36ada5b10da39a1347559321baf13063",
        //     "$distinct_id": "13793",
        //     "$unset": [ "Days Overdue" ]
        // }

        public static MessageBuildResult Build(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            IEnumerable <string> propertyNames,
            object distinctId,
            MixpanelConfig config)
        {
            MessageCandidate messageCandidate = PeopleMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                null,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();

            // Special properties
            PeopleMessageBuilderBase.RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                // Ignore non-message specific special properties as they are not valid in profile update messages
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
            });

            message["$unset"] = propertyNames ?? new string[0];

            return(MessageBuildResult.CreateSuccess(message));
        }
示例#18
0
        public static MessageBuildResult Build(
            string token,
            string @event,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config)
        {
            if (string.IsNullOrWhiteSpace(@event))
            {
                return(MessageBuildResult.CreateFail($"'{nameof(@event)}' is not set."));
            }

            MessageCandidate messageCandidate = TrackMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>(2);

            message["event"] = @event;

            var properties = new Dictionary <string, object>();

            message["properties"] = properties;

            // Special properties
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.SpecialProperties)
            {
                string         specialPropertyName = pair.Key;
                ObjectProperty objectProperty      = pair.Value;

                ValueParseResult result =
                    TrackSpecialPropertyParser.Parse(specialPropertyName, objectProperty.Value);
                if (!result.Success)
                {
                    // The only required special properties are 'event' and 'token' which are controlled separately
                    continue;
                }

                properties[specialPropertyName] = result.Value;
            }

            // User properties
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.UserProperties)
            {
                string         formattedPropertyName = pair.Key;
                ObjectProperty objectProperty        = pair.Value;

                ValueParseResult result = GenericPropertyParser.Parse(objectProperty.Value, allowCollections: true);
                if (!result.Success)
                {
                    continue;
                }

                properties[formattedPropertyName] = result.Value;
            }

            return(MessageBuildResult.CreateSuccess(message));
        }