Esempio n. 1
0
            public static LdValue ReadJsonValue(ref JReader reader)
            {
                var value = reader.Any();

                switch (value.Type)
                {
                case JsonStream.ValueType.Bool:
                    return(LdValue.Of(value.BoolValue));

                case JsonStream.ValueType.Number:
                    return(LdValue.Of(value.NumberValue));

                case JsonStream.ValueType.String:
                    return(LdValue.Of(value.StringValue.ToString()));

                case JsonStream.ValueType.Array:
                    var arrayBuilder = LdValue.BuildArray();
                    for (var arr = value.ArrayValue; arr.Next(ref reader);)
                    {
                        arrayBuilder.Add(ReadJsonValue(ref reader));
                    }
                    return(arrayBuilder.Build());

                case JsonStream.ValueType.Object:
                    var objBuilder = LdValue.BuildObject();
                    for (var obj = value.ObjectValue; obj.Next(ref reader);)
                    {
                        objBuilder.Add(obj.Name.ToString(), ReadJsonValue(ref reader));
                    }
                    return(objBuilder.Build());

                default:
                    return(LdValue.Null);
                }
            }
Esempio n. 2
0
        internal static SegmentRule ReadSegmentRule(ref JReader reader)
        {
            ImmutableList <Clause> clauses = null;
            int?          weight           = null;
            UserAttribute?bucketBy         = null;

            for (var obj = reader.Object(); obj.Next(ref reader);)
            {
                switch (obj.Name)
                {
                case var n when n == "clauses":
                    clauses = SerializationHelpers.ReadClauses(ref reader);
                    break;

                case var n when n == "weight":
                    weight = reader.IntOrNull();
                    break;

                case var n when n == "bucketBy":
                    var s = reader.StringOrNull();
                    bucketBy = s is null ? (UserAttribute?)null : UserAttribute.ForName(s);
                    break;
                }
            }
            return(new SegmentRule(clauses, weight, bucketBy));
        }
Esempio n. 3
0
        internal static PutData ParsePutData(byte[] json)
        {
            var r = JReader.FromUtf8Bytes(json);

            try
            {
                string path = null;
                FullDataSet <ItemDescriptor> data = new FullDataSet <ItemDescriptor>();

                for (var obj = r.Object().WithRequiredProperties(_putRequiredProperties); obj.Next(ref r);)
                {
                    if (obj.Name == "path")
                    {
                        path = r.String();
                    }
                    else if (obj.Name == "data")
                    {
                        data = ParseFullDataset(ref r);
                    }
                }
                return(new PutData(path, data));
            }
            catch (Exception e)
            {
                throw r.TranslateException(e);
            }
        }
 public FullDataSet <ItemDescriptor> Parse(string content, int version)
 {
     if (_alternateParser == null)
     {
         return(ParseJson(content, version));
     }
     else
     {
         if (content.Trim().StartsWith("{"))
         {
             try
             {
                 return(ParseJson(content, version));
             }
             catch (Exception)
             {
                 // we failed to parse it as JSON, so we'll just see if the alternate parser can do it
             }
         }
         // The alternate parser should produce the most basic .NET data structure that can represent
         // the file content, using types like Dictionary and String. We then convert this into a
         // JSON tree so we can use the JSON deserializer; this is inefficient, but it lets us reuse
         // our existing data model deserialization logic.
         var o = _alternateParser(content);
         var r = JReader.FromAdapter(ReaderAdapters.FromSimpleTypes(o, allowTypeCoercion: true));
         return(ParseJson(ref r, version));
     }
 }
Esempio n. 5
0
        internal static DeleteData ParseDeleteData(byte[] json)
        {
            var r = JReader.FromUtf8Bytes(json);

            try
            {
                DataKind kind    = null;
                string   key     = null;
                int      version = 0;
                for (var obj = r.Object().WithRequiredProperties(_deleteRequiredProperties); obj.Next(ref r);)
                {
                    if (obj.Name == "path")
                    {
                        TryParsePath(r.String(), out kind, out key);
                    }
                    else if (obj.Name == "version")
                    {
                        version = r.Int();
                    }
                }
                return(new DeleteData(kind, key, version));
            }
            catch (Exception e)
            {
                throw r.TranslateException(e);
            }
        }
Esempio n. 6
0
 internal static FullDataSet <ItemDescriptor> ParseFullDataset(ref JReader r)
 {
     try
     {
         var dataBuilder = ImmutableList.CreateBuilder <KeyValuePair <DataKind, KeyedItems <ItemDescriptor> > >();
         for (var topLevelObj = r.Object(); topLevelObj.Next(ref r);)
         {
             var name = topLevelObj.Name.ToString();
             var kind = DataModel.AllDataKinds.FirstOrDefault(k => name == PathNameForKind(k));
             if (kind == null)
             {
                 continue;
             }
             var itemsBuilder = ImmutableList.CreateBuilder <KeyValuePair <string, ItemDescriptor> >();
             for (var itemsObj = r.Object(); itemsObj.Next(ref r);)
             {
                 var key  = itemsObj.Name.ToString();
                 var item = kind.DeserializeFromJReader(ref r);
                 itemsBuilder.Add(new KeyValuePair <string, ItemDescriptor>(key, item));
             }
             dataBuilder.Add(new KeyValuePair <DataKind, KeyedItems <ItemDescriptor> >(kind,
                                                                                       new KeyedItems <ItemDescriptor>(itemsBuilder.ToImmutable())));
         }
         return(new FullDataSet <ItemDescriptor>(dataBuilder.ToImmutable()));
     }
     catch (Exception e)
     {
         throw r.TranslateException(e);
     }
 }
Esempio n. 7
0
 internal DataKind(
     string name,
     SerializerToJWriter internalSerializer,
     DeserializerFromJReader internalDeserializer)
 {
     _name = name;
     _internalSerializer   = internalSerializer;
     _internalDeserializer = internalDeserializer;
     _serializer           = item =>
     {
         var w = JWriter.New();
         if (item.Item is null)
         {
             var obj = w.Object();
             obj.Name("version").Int(item.Version);
             obj.Name("deleted").Bool(true);
             obj.End();
         }
         else
         {
             internalSerializer(item.Item, w);
         }
         return(w.GetString());
     };
     _deserializer = s =>
     {
         var r = JReader.FromString(s);
         return(_internalDeserializer(ref r));
     };
 }
        private static ItemDescriptor DeserializeFlag(ref JReader r)
        {
            var flag = FeatureFlagSerialization.Instance.ReadJson(ref r) as FeatureFlag;

            return(flag.Deleted ? ItemDescriptor.Deleted(flag.Version) :
                   new ItemDescriptor(flag.Version, flag));
        }
        private static ItemDescriptor DeserializeSegment(ref JReader r)
        {
            var segment = SegmentSerialization.Instance.ReadJson(ref r) as Segment;

            return(segment.Deleted ? ItemDescriptor.Deleted(segment.Version) :
                   new ItemDescriptor(segment.Version, segment));
        }
Esempio n. 10
0
        /// <summary>
        /// Parses the user index from a JSON representation. If the JSON string is null or
        /// empty, it returns an empty user index.
        /// </summary>
        /// <param name="json">the JSON representation</param>
        /// <returns>the parsed data</returns>
        /// <exception cref="FormatException">if the JSON is malformed</exception>
        public static UserIndex Deserialize(string json)
        {
            if (string.IsNullOrEmpty(json))
            {
                return(new UserIndex());
            }
            var builder = ImmutableList.CreateBuilder <IndexEntry>();

            try
            {
                var r = JReader.FromString(json);
                for (var ar0 = r.Array(); ar0.Next(ref r);)
                {
                    var ar1 = r.Array();
                    if (ar1.Next(ref r))
                    {
                        var userId = r.String();
                        if (ar1.Next(ref r))
                        {
                            var timeMillis = r.Long();
                            builder.Add(new IndexEntry {
                                UserId = userId, Timestamp = UnixMillisecondTime.OfMillis(timeMillis)
                            });
                            ar1.Next(ref r);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new FormatException("invalid stored user index", e);
            }
            return(new UserIndex(builder.ToImmutable()));
        }
Esempio n. 11
0
        internal static FlagRule ReadFlagRule(ref JReader r)
        {
            string  id        = null;
            int?    variation = null;
            Rollout?rollout   = null;
            ImmutableList <Clause> clauses = null;
            bool trackEvents = false;

            for (var obj = r.Object(); obj.Next(ref r);)
            {
                switch (obj.Name)
                {
                case var n when n == "id":
                    id = r.StringOrNull();
                    break;

                case var n when n == "variation":
                    variation = r.IntOrNull();
                    break;

                case var n when n == "rollout":
                    rollout = ReadRollout(ref r);
                    break;

                case var n when n == "clauses":
                    clauses = SerializationHelpers.ReadClauses(ref r);
                    break;

                case var n when n == "trackEvents":
                    trackEvents = r.Bool();
                    break;
                }
            }
            return(new FlagRule(variation, rollout, id, clauses, trackEvents));
        }
        private TestStruct ReadStruct(ref JReader r)
        {
            var obj = r.ObjectOrNull();

            if (!obj.IsDefined)
            {
                return(null);
            }
            var ret = new TestStruct();

            while (obj.Next(ref r))
            {
                switch (obj.Name)
                {
                case var n when n == "str":
                    ret.Str = r.String();
                    break;

                case var n when n == "nums":
                    ret.Nums = ReadInts(ref r);
                    break;

                case var n when n == "bool":
                    ret.Bool = r.Bool();
                    break;

                case var n when n == "nested":
                    ret.Nested = ReadStruct(ref r);
                    break;
                }
            }
            return(ret);
        }
        public object ReadJson(ref JReader reader)
        {
            var valid = true;
            var flags = new Dictionary <string, FlagState>();

            for (var topLevelObj = reader.Object(); topLevelObj.Next(ref reader);)
            {
                var key = topLevelObj.Name.ToString();
                switch (key)
                {
                case "$valid":
                    valid = reader.Bool();
                    break;

                case "$flagsState":
                    for (var flagsObj = reader.Object(); flagsObj.Next(ref reader);)
                    {
                        var subKey = flagsObj.Name.ToString();
                        var flag   = flags.ContainsKey(subKey) ? flags[subKey] : new FlagState();
                        for (var metaObj = reader.Object(); metaObj.Next(ref reader);)
                        {
                            switch (metaObj.Name.ToString())
                            {
                            case "variation":
                                flag.Variation = reader.IntOrNull();
                                break;

                            case "version":
                                flag.Version = reader.IntOrNull();
                                break;

                            case "trackEvents":
                                flag.TrackEvents = reader.Bool();
                                break;

                            case "debugEventsUntilDate":
                                var n = reader.LongOrNull();
                                flag.DebugEventsUntilDate = n.HasValue ? UnixMillisecondTime.OfMillis(n.Value) :
                                                            (UnixMillisecondTime?)null;
                                break;

                            case "reason":
                                flag.Reason = EvaluationReasonConverter.ReadJsonNullableValue(ref reader);
                                break;
                            }
                        }
                        flags[subKey] = flag;
                    }
                    break;

                default:
                    var flagForValue = flags.ContainsKey(key) ? flags[key] : new FlagState();
                    flagForValue.Value = LdValueConverter.ReadJsonValue(ref reader);
                    flags[key]         = flagForValue;
                    break;
                }
            }
            return(new FeatureFlagsState(valid, flags));
        }
Esempio n. 14
0
 internal ItemDescriptor DeserializeFromJReader(ref JReader reader)
 {
     if (_internalDeserializer is null)
     {
         throw new ArgumentException("SDK tried to deserialize a non-built-in data kind");
     }
     return(_internalDeserializer(ref reader));
 }
        private List <TestStruct> ReadStructs(ref JReader r)
        {
            var ret = new List <TestStruct>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(ReadStruct(ref r));
            }
            return(ret);
        }
        private List <int> ReadInts(ref JReader r)
        {
            var ret = new List <int>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(r.Int());
            }
            return(ret);
        }
        private List <bool> ReadBools(ref JReader r)
        {
            var ret = new List <bool>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(r.Bool());
            }
            return(ret);
        }
Esempio n. 18
0
        internal static ImmutableList <LdValue> ReadValues(ref JReader r)
        {
            var builder = ImmutableList.CreateBuilder <LdValue>();

            for (var arr = r.ArrayOrNull(); arr.Next(ref r);)
            {
                builder.Add(LdValueConverter.ReadJsonValue(ref r));
            }
            return(builder.ToImmutable());
        }
 public void JsonExceptionTest()
 {
     try
     {
         var v = JReader.Parse(File.ReadAllText("FilePath"));
     }
     catch
     {
     }
 }
Esempio n. 20
0
        internal static ImmutableList <string> ReadStrings(ref JReader r)
        {
            var builder = ImmutableList.CreateBuilder <string>();

            for (var arr = r.ArrayOrNull(); arr.Next(ref r);)
            {
                builder.Add(r.String());
            }
            return(builder.ToImmutable());
        }
        /// <summary>
        /// Advances to the next array element if any, and returns <see langword="true"/> if successful.
        /// </summary>
        /// <remarks>
        /// <para>
        /// It returns <see langword="false"/> if the <c>JReader</c> has reached the end of the array, or
        /// if the array was empty or null.
        /// </para>
        /// <para>
        /// If <c>Next</c> returns <see langword="true"/>, you can then use <see cref="JReader"/> methods
        /// such as <see cref="JReader.Bool"/> to read the element value. If you do not care about the
        /// value, simply calling <c>Next</c> again without calling a <c>JReader</c> method will discard
        /// the value.
        /// </para>
        /// <para>
        /// For more information about why <c>Next</c> requires a <c>ref</c> parameter, see
        /// <see cref="JReader"/>.
        /// </para>
        /// </remarks>
        /// <param name="reader">the original <see cref="JReader"/> (must be passed by reference)</param>
        /// <returns><see langword="true"/> if there is a next array element</returns>
        public bool Next(ref JReader reader)
        {
            if (!_defined)
            {
                return(false);
            }
            var hasNext = reader.ArrayNext(!_afterFirst);

            _afterFirst = true;
            return(hasNext);
        }
Esempio n. 22
0
 public object ReadJson(ref JReader reader)
 {
     try
     {
         return(ReadJsonValue(ref reader));
     }
     catch (Exception e)
     {
         throw reader.TranslateException(e);
     }
 }
        public object ReadJson(ref JReader reader)
        {
            string key = null;
            int    version = 0;
            bool   deleted = false;
            ImmutableList <string>      included = null, excluded = null;
            ImmutableList <SegmentRule> rules = null;
            string salt = null;

            for (var obj = reader.Object().WithRequiredProperties(_requiredProperties); obj.Next(ref reader);)
            {
                switch (obj.Name)
                {
                case var n when n == "key":
                    key = reader.String();
                    break;

                case var n when n == "version":
                    version = reader.Int();
                    break;

                case var n when n == "deleted":
                    deleted = reader.Bool();
                    break;

                case var n when n == "included":
                    included = SerializationHelpers.ReadStrings(ref reader);
                    break;

                case var n when n == "excluded":
                    excluded = SerializationHelpers.ReadStrings(ref reader);
                    break;

                case var n when n == "rules":
                    var rulesBuilder = ImmutableList.CreateBuilder <SegmentRule>();
                    for (var rulesArr = reader.Array(); rulesArr.Next(ref reader);)
                    {
                        rulesBuilder.Add(ReadSegmentRule(ref reader));
                    }
                    rules = rulesBuilder.ToImmutable();
                    break;

                case var n when n == "salt":
                    salt = reader.StringOrNull();
                    break;
                }
            }
            if (key is null && !deleted)
            {
                throw new RequiredPropertyException("key", 0);
            }
            return(new Segment(key, version, deleted, included, excluded, rules, salt));
        }
Esempio n. 24
0
        internal static PatchData ParsePatchData(byte[] json)
        {
            var r = JReader.FromUtf8Bytes(json);

            try
            {
                DataKind kind = null;
                string   key  = null;
                for (var obj = r.Object().WithRequiredProperties(_patchRequiredProperties); obj.Next(ref r);)
                {
                    if (obj.Name == "path")
                    {
                        TryParsePath(r.String(), out kind, out key);
                        if (kind is null)
                        {
                            // An unrecognized path isn't considered an error; we'll just return a null kind,
                            // indicating that we should ignore this event.
                            return(new PatchData(null, null, new ItemDescriptor()));
                        }
                    }
                    else if (obj.Name == "data")
                    {
                        if (kind != null)
                        {
                            // If kind is null here, it means we happened to read the "data" property before
                            // the "path" property, so we don't yet know what kind of data model object this
                            // is, so we can't parse it yet and we'll have to do a second pass.
                            var item = kind.DeserializeFromJReader(ref r);
                            return(new PatchData(kind, key, item));
                        }
                    }
                }
                // If we got here, it means we couldn't parse the data model object yet because we saw the
                // "data" property first. But we definitely saw both properties (otherwise we would've got
                // an error due to using WithRequiredProperties) so kind is now non-null.
                var r1 = JReader.FromUtf8Bytes(json);
                for (var obj = r1.Object(); obj.Next(ref r1);)
                {
                    if (obj.Name == "data")
                    {
                        return(new PatchData(kind, key, kind.DeserializeFromJReader(ref r1)));
                    }
                }
                throw new RequiredPropertyException("data", json.Length);
            }
            catch (Exception e)
            {
                throw r.TranslateException(e);
            }
        }
 public void JsonCorrectExceptionTest()
 {
     try
     {
         var v = JReader.Parse(File.ReadAllText("FilePath"));
     }
     catch (IOException ex)
     {
         //Chyba v načítání souboru
     }
     catch (JsonException ex)
     {
         //Chyba ve formátu souboru
     }
 }
        private static FullDataSet <ItemDescriptor> ParseJson(ref JReader r, int version)
        {
            var flagsBuilder    = ImmutableList.CreateBuilder <KeyValuePair <string, ItemDescriptor> >();
            var segmentsBuilder = ImmutableList.CreateBuilder <KeyValuePair <string, ItemDescriptor> >();

            for (var obj = r.Object(); obj.Next(ref r);)
            {
                switch (obj.Name.ToString())
                {
                case "flags":
                    for (var subObj = r.ObjectOrNull(); subObj.Next(ref r);)
                    {
                        var key  = subObj.Name.ToString();
                        var flag = FeatureFlagSerialization.Instance.ReadJson(ref r) as FeatureFlag;
                        flagsBuilder.Add(new KeyValuePair <string, ItemDescriptor>(key, new ItemDescriptor(version,
                                                                                                           FlagWithVersion(flag, version))));
                    }
                    break;

                case "flagValues":
                    for (var subObj = r.ObjectOrNull(); subObj.Next(ref r);)
                    {
                        var key   = subObj.Name.ToString();
                        var value = LdValueConverter.ReadJsonValue(ref r);
                        var flag  = FlagWithValue(key, value, version);
                        flagsBuilder.Add(new KeyValuePair <string, ItemDescriptor>(key, new ItemDescriptor(version, flag)));
                    }
                    break;

                case "segments":
                    for (var subObj = r.ObjectOrNull(); subObj.Next(ref r);)
                    {
                        var key     = subObj.Name.ToString();
                        var segment = SegmentSerialization.Instance.ReadJson(ref r) as Segment;
                        segmentsBuilder.Add(new KeyValuePair <string, ItemDescriptor>(key, new ItemDescriptor(version,
                                                                                                              SegmentWithVersion(segment, version))));
                    }
                    break;
                }
            }
            return(new FullDataSet <ItemDescriptor>(ImmutableList.Create <KeyValuePair <DataKind, KeyedItems <ItemDescriptor> > >(
                                                        new KeyValuePair <DataKind, KeyedItems <ItemDescriptor> >(DataModel.Features,
                                                                                                                  new KeyedItems <ItemDescriptor>(flagsBuilder.ToImmutable())),
                                                        new KeyValuePair <DataKind, KeyedItems <ItemDescriptor> >(DataModel.Segments,
                                                                                                                  new KeyedItems <ItemDescriptor>(segmentsBuilder.ToImmutable()))
                                                        )));
        }
        internal static Rollout?ReadRollout(ref JReader r)
        {
            ImmutableList <WeightedVariation> variations = null;
            UserAttribute?bucketBy = null;
            var           obj      = r.ObjectOrNull();

            if (!obj.IsDefined)
            {
                return(null);
            }
            while (obj.Next(ref r))
            {
                switch (obj.Name)
                {
                case var n when n == "variations":
                    var listBuilder = ImmutableList.CreateBuilder <WeightedVariation>();
                    for (var arr = r.ArrayOrNull(); arr.Next(ref r);)
                    {
                        int variation = 0, weight = 0;
                        for (var wvObj = r.Object(); wvObj.Next(ref r);)
                        {
                            switch (wvObj.Name)
                            {
                            case var nn when nn == "variation":
                                variation = r.Int();
                                break;

                            case var nn when nn == "weight":
                                weight = r.Int();
                                break;
                            }
                        }
                        listBuilder.Add(new WeightedVariation(variation, weight));
                    }
                    variations = listBuilder.ToImmutable();
                    break;

                case var n when n == "bucketBy":
                    var s = r.StringOrNull();
                    bucketBy = s is null ? (UserAttribute?)null : UserAttribute.ForName(s);
                    break;
                }
            }
            return(new Rollout(variations, bucketBy));
        }
Esempio n. 28
0
        // Currently there is only one serialization schema, but it is possible that future
        // SDK versions will require a richer model. In that case we will need to design the
        // serialized format to be distinguishable from previous formats and allow reading
        // of older formats, while only writing the new format.

        internal static FullDataSet DeserializeV1Schema(string serializedData)
        {
            var builder = ImmutableList.CreateBuilder <KeyValuePair <string, ItemDescriptor> >();
            var r       = JReader.FromString(serializedData);

            try
            {
                for (var or = r.Object(); or.Next(ref r);)
                {
                    var flag = FeatureFlagJsonConverter.ReadJsonValue(ref r);
                    builder.Add(new KeyValuePair <string, ItemDescriptor>(or.Name.ToString(), flag.ToItemDescriptor()));
                }
            }
            catch (Exception e)
            {
                throw new InvalidDataException(ParseErrorMessage, r.TranslateException(e));
            }
            return(new FullDataSet(builder.ToImmutable()));
        }
Esempio n. 29
0
        internal static VariationOrRollout ReadVariationOrRollout(ref JReader r)
        {
            int?    variation = null;
            Rollout?rollout   = null;

            for (var obj = r.ObjectOrNull(); obj.Next(ref r);)
            {
                switch (obj.Name)
                {
                case var n when n == "variation":
                    variation = r.IntOrNull();
                    break;

                case var n when n == "rollout":
                    rollout = ReadRollout(ref r);
                    break;
                }
            }
            return(new VariationOrRollout(variation, rollout));
        }
Esempio n. 30
0
        internal static Target ReadTarget(ref JReader r)
        {
            ImmutableList <string> values = null;
            int variation = 0;

            for (var obj = r.Object(); obj.Next(ref r);)
            {
                switch (obj.Name)
                {
                case var n when n == "values":
                    values = SerializationHelpers.ReadStrings(ref r);
                    break;

                case var n when n == "variation":
                    variation = r.Int();
                    break;
                }
            }
            return(new Target(values, variation));
        }