Exemple #1
0
            public LazyCosmosObject(IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode)
            {
                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Object)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be a {JsonNodeType.Object} node. Got {type} instead.");
                }

                this.jsonNavigator     = jsonNavigator;
                this.jsonNavigatorNode = jsonNavigatorNode;
                this.cachedElements    = new ConcurrentDictionary <string, CosmosElement>();
                this.lazyCount         = new Lazy <int>(() => this.jsonNavigator.GetObjectPropertyCount(this.jsonNavigatorNode));
            }
Exemple #2
0
        internal async Task <PartitionKey> GetPartitionKeyValueFromStreamAsync(
            Stream stream,
            CancellationToken cancellation = default(CancellationToken))
        {
            if (!stream.CanSeek)
            {
                throw new ArgumentException("Stream is needs to be seekable", nameof(stream));
            }

            try
            {
                stream.Position = 0;

                MemoryStream memoryStream = stream as MemoryStream;
                if (memoryStream == null)
                {
                    memoryStream = new MemoryStream();
                    stream.CopyTo(memoryStream);
                }

                // TODO: Avoid copy
                IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
                IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
                CosmosObject       pathTraversal     = CosmosObject.Create(jsonNavigator, jsonNavigatorNode);

                string[] tokens = await this.GetPartitionKeyPathTokensAsync(cancellation);

                for (int i = 0; i < tokens.Length - 1; i++)
                {
                    pathTraversal = pathTraversal[tokens[i]] as CosmosObject;
                    if (pathTraversal == null)
                    {
                        return(PartitionKey.NonePartitionKeyValue);
                    }
                }

                CosmosElement partitionKeyValue = pathTraversal[tokens[tokens.Length - 1]];
                if (partitionKeyValue == null)
                {
                    return(PartitionKey.NonePartitionKeyValue);
                }

                return(new PartitionKey(this.CosmosElementToPartitionKeyObject(partitionKeyValue)));
            }
            finally
            {
                // MemoryStream casting leverage might change position
                stream.Position = 0;
            }
        }
        public static (QueryResponseCore queryResponse, IList <ToDoItem> items) Create(
            string itemIdPrefix,
            string continuationToken,
            string collectionRid,
            int itemCount = 50)
        {
            // Use -1 to represent a split response
            if (itemCount == QueryResponseMessageFactory.SPLIT)
            {
                return(CreateSplitResponse(collectionRid), new List <ToDoItem>().AsReadOnly());
            }

            IList <ToDoItem> items               = ToDoItem.CreateItems(itemCount, itemIdPrefix);
            MemoryStream     memoryStream        = (MemoryStream)cosmosSerializer.ToStream <IList <ToDoItem> >(items);
            long             responseLengthBytes = memoryStream.Length;

            IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
            IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
            CosmosArray        cosmosArray       = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);

            double requestCharge = 42;
            string activityId    = Guid.NewGuid().ToString();
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics("0",
                                         "SomeQueryMetricText",
                                         "SomeIndexUtilText",
                                         new PointOperationStatistics(
                                             activityId: Guid.NewGuid().ToString(),
                                             statusCode: HttpStatusCode.OK,
                                             subStatusCode: SubStatusCodes.Unknown,
                                             requestCharge: requestCharge,
                                             errorMessage: null,
                                             method: HttpMethod.Post,
                                             requestUri: new Uri("http://localhost.com"),
                                             clientSideRequestStatistics: null),
                                         new SchedulingStopwatch())
            };

            QueryResponseCore message = QueryResponseCore.CreateSuccess(
                result: cosmosArray,
                continuationToken: continuationToken,
                disallowContinuationTokenMessage: null,
                activityId: activityId,
                requestCharge: requestCharge,
                diagnostics: diagnostics,
                responseLengthBytes: responseLengthBytes);

            return(message, items);
        }
        public override async Task <PartitionKey> GetPartitionKeyValueFromStreamAsync(
            Stream stream,
            CancellationToken cancellation = default(CancellationToken))
        {
            if (!stream.CanSeek)
            {
                throw new ArgumentException("Stream needs to be seekable", nameof(stream));
            }

            try
            {
                stream.Position = 0;

                if (!(stream is MemoryStream memoryStream))
                {
                    memoryStream = new MemoryStream();
                    stream.CopyTo(memoryStream);
                }

                // TODO: Avoid copy
                IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
                IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
                CosmosObject       pathTraversal     = CosmosObject.Create(jsonNavigator, jsonNavigatorNode);

                IReadOnlyList <IReadOnlyList <string> > tokenslist = await this.GetPartitionKeyPathTokensAsync(cancellation);

                List <CosmosElement> cosmosElementList = new List <CosmosElement>(tokenslist.Count);

                foreach (IReadOnlyList <string> tokenList in tokenslist)
                {
                    CosmosElement element;
                    if (ContainerCore.TryParseTokenListForElement(pathTraversal, tokenList, out element))
                    {
                        cosmosElementList.Add(element);
                    }
                    else
                    {
                        cosmosElementList.Add(null);
                    }
                }

                return(ContainerCore.CosmosElementToPartitionKeyObject(cosmosElementList));
            }
            finally
            {
                // MemoryStream casting leverage might change position
                stream.Position = 0;
            }
        }
        public static CosmosString Create(
            IJsonNavigator jsonNavigator,
            IJsonNavigatorNode jsonNavigatorNode)
        {
            if (jsonNavigator == null)
            {
                throw new ArgumentNullException(nameof(jsonNavigator));
            }

            if (jsonNavigatorNode == null)
            {
                throw new ArgumentNullException(nameof(jsonNavigatorNode));
            }

            return(new LazyCosmosString(jsonNavigator, jsonNavigatorNode));
        }
Exemple #6
0
        private static JsonToken[] GetTokensFromArrayNode(IJsonNavigatorNode node, IJsonNavigator navigator, bool performCorrectnessCheck)
        {
            // Get tokens once through IEnumerable
            List <JsonToken> tokensFromIEnumerable      = new List <JsonToken>();
            IEnumerable <IJsonNavigatorNode> arrayItems = navigator.GetArrayItems(node);

            tokensFromIEnumerable.Add(JsonToken.ArrayStart());
            foreach (IJsonNavigatorNode arrayItem in arrayItems)
            {
                tokensFromIEnumerable.AddRange(JsonNavigatorTests.GetTokensFromNode(arrayItem, navigator, performCorrectnessCheck));
            }

            tokensFromIEnumerable.Add(JsonToken.ArrayEnd());

            if (performCorrectnessCheck)
            {
                // Get tokens once again through indexer
                List <JsonToken> tokensFromIndexer = new List <JsonToken>();
                tokensFromIndexer.Add(JsonToken.ArrayStart());
                for (int i = 0; i < navigator.GetArrayItemCount(node); ++i)
                {
                    tokensFromIndexer.AddRange(JsonNavigatorTests.GetTokensFromNode(navigator.GetArrayItemAt(node, i), navigator, performCorrectnessCheck));
                }

                tokensFromIndexer.Add(JsonToken.ArrayEnd());

                Assert.AreEqual(arrayItems.Count(), navigator.GetArrayItemCount(node));
                Assert.IsTrue(tokensFromIEnumerable.SequenceEqual(tokensFromIndexer));

                try
                {
                    navigator.GetArrayItemAt(node, navigator.GetArrayItemCount(node) + 1);
                    Assert.Fail("Expected to get an index out of range exception from going one past the end of the array.");
                }
                catch (IndexOutOfRangeException)
                {
                    Assert.AreEqual(navigator.SerializationFormat, JsonSerializationFormat.Binary);
                }
                catch (ArgumentOutOfRangeException)
                {
                    Assert.AreEqual(navigator.SerializationFormat, JsonSerializationFormat.Text);
                }
            }

            return(tokensFromIEnumerable.ToArray());
        }
Exemple #7
0
        public static CosmosElement Dispatch(
            IJsonNavigator jsonNavigator,
            IJsonNavigatorNode jsonNavigatorNode)
        {
            JsonNodeType  jsonNodeType = jsonNavigator.GetNodeType(jsonNavigatorNode);
            CosmosElement item;

            switch (jsonNodeType)
            {
            case JsonNodeType.Null:
                item = CosmosNull.Create();
                break;

            case JsonNodeType.False:
                item = CosmosBoolean.Create(false);
                break;

            case JsonNodeType.True:
                item = CosmosBoolean.Create(true);
                break;

            case JsonNodeType.Number:
                item = CosmosNumber.Create(jsonNavigator, jsonNavigatorNode);
                break;

            case JsonNodeType.FieldName:
            case JsonNodeType.String:
                item = CosmosString.Create(jsonNavigator, jsonNavigatorNode);
                break;

            case JsonNodeType.Array:
                item = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);
                break;

            case JsonNodeType.Object:
                item = CosmosObject.Create(jsonNavigator, jsonNavigatorNode);
                break;

            default:
                throw new ArgumentException($"Unknown {nameof(JsonNodeType)}: {jsonNodeType}");
            }

            return(item);
        }
Exemple #8
0
        public static TimeSpan MeasureNavigationPerformance(IJsonNavigator jsonNavigator, int numberOfIterations = 1)
        {
            JsonToken[] tokensFromNode;
            Stopwatch   stopwatch = new Stopwatch();

            for (int i = 0; i < numberOfIterations; i++)
            {
                stopwatch.Start();
                tokensFromNode = JsonNavigatorTests.GetTokensFromNode(jsonNavigator.GetRootNode(), jsonNavigator, false);
                stopwatch.Stop();

                if (tokensFromNode.Length == 0)
                {
                    throw new InvalidOperationException("got back zero tokens");
                }
            }

            return(stopwatch.Elapsed);
        }
Exemple #9
0
        internal static JsonToken[] GetTokensFromObjectNode(IJsonNavigatorNode node, IJsonNavigator navigator, bool performCorrectnessCheck)
        {
            // Get the tokens through .GetObjectProperties
            List <JsonToken>             tokensFromGetProperties = new List <JsonToken>();
            IEnumerable <ObjectProperty> properties = navigator.GetObjectProperties(node);

            tokensFromGetProperties.Add(JsonToken.ObjectStart());
            foreach (ObjectProperty property in properties)
            {
                string fieldname = navigator.GetStringValue(property.NameNode);
                tokensFromGetProperties.Add(JsonToken.FieldName(fieldname));
                tokensFromGetProperties.AddRange(JsonNavigatorTests.GetTokensFromNode(property.ValueNode, navigator, performCorrectnessCheck));
            }
            tokensFromGetProperties.Add(JsonToken.ObjectEnd());

            if (performCorrectnessCheck)
            {
                // Get the tokens again through .TryGetObjectProperty
                List <JsonToken> tokensFromTryGetProperty = new List <JsonToken>();

                tokensFromTryGetProperty.Add(JsonToken.ObjectStart());
                foreach (ObjectProperty objectProperty in properties)
                {
                    ObjectProperty propertyFromTryGetProperty;
                    string         fieldname = navigator.GetStringValue(objectProperty.NameNode);
                    if (navigator.TryGetObjectProperty(node, fieldname, out propertyFromTryGetProperty))
                    {
                        tokensFromTryGetProperty.Add(JsonToken.FieldName(fieldname));
                        tokensFromTryGetProperty.AddRange(JsonNavigatorTests.GetTokensFromNode(propertyFromTryGetProperty.ValueNode, navigator, performCorrectnessCheck));
                    }
                    else
                    {
                        Assert.Fail($"Failed to get object property with name: {fieldname}");
                    }
                }
                tokensFromTryGetProperty.Add(JsonToken.ObjectEnd());
                Assert.AreEqual(properties.Count(), navigator.GetObjectPropertyCount(node));
                Assert.IsTrue(tokensFromGetProperties.SequenceEqual(tokensFromTryGetProperty));
            }

            return(tokensFromGetProperties.ToArray());
        }
Exemple #10
0
        public static QueryResponseCore CreateQueryResponse(
            IList <ToDoItem> items,
            bool isOrderByQuery,
            string continuationToken,
            string collectionRid)
        {
            MemoryStream memoryStream;
            string       json;

            if (isOrderByQuery)
            {
                memoryStream = SerializeForOrderByQuery(items);
                using (StreamReader sr = new StreamReader(SerializeForOrderByQuery(items)))
                {
                    json = sr.ReadToEnd();
                }
            }
            else
            {
                memoryStream = (MemoryStream)cosmosSerializer.ToStream <IList <ToDoItem> >(items);
            }

            long responseLengthBytes = memoryStream.Length;

            IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
            IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
            CosmosArray        cosmosArray       = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);

            QueryResponseCore message = QueryResponseCore.CreateSuccess(
                result: cosmosArray,
                requestCharge: 4,
                activityId: Guid.NewGuid().ToString(),
                queryMetricsText: null,
                queryMetrics: null,
                requestStatistics: null,
                responseLengthBytes: responseLengthBytes,
                disallowContinuationTokenMessage: null,
                continuationToken: continuationToken);

            return(message);
        }
        public static QueryResponse CreateQueryResponse(
            IList <ToDoItem> items,
            bool isOrderByQuery,
            string continuationToken,
            string collectionRid)
        {
            MemoryStream memoryStream;
            string       json;

            if (isOrderByQuery)
            {
                memoryStream = SerializeForOrderByQuery(items);
                using (StreamReader sr = new StreamReader(SerializeForOrderByQuery(items)))
                {
                    json = sr.ReadToEnd();
                }
            }
            else
            {
                memoryStream = (MemoryStream)cosmosSerializer.ToStream <IList <ToDoItem> >(items);
            }

            long responseLengthBytes = memoryStream.Length;

            IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
            IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
            CosmosArray        cosmosArray       = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);

            Headers headers = new Headers();

            headers.ContinuationToken = continuationToken;
            headers.ActivityId        = Guid.NewGuid().ToString();

            QueryResponse message = QueryResponse.CreateSuccess(
                result: cosmosArray,
                count: items.Count,
                responseHeaders: CosmosQueryResponseMessageHeaders.ConvertToQueryHeaders(headers, ResourceType.Document, collectionRid),
                responseLengthBytes: responseLengthBytes);

            return(message);
        }
Exemple #12
0
        private static void ExecuteNavigatorBenchmark(
            CurratedDocsPayload payload,
            SerializationFormat sourceFormat,
            SerializationFormat destinationFormat)
        {
            IJsonNavigator navigator = sourceFormat switch
            {
                SerializationFormat.Text => JsonNavigator.Create(payload.Text),
                SerializationFormat.Binary => JsonNavigator.Create(payload.Binary),
                _ => throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: '{sourceFormat}'"),
            };

            IJsonWriter writer = destinationFormat switch
            {
                SerializationFormat.Text => JsonWriter.Create(JsonSerializationFormat.Text),
                SerializationFormat.Binary => JsonWriter.Create(JsonSerializationFormat.Binary),
                _ => throw new ArgumentException($"Unexpected {nameof(destinationFormat)} of type: {destinationFormat}"),
            };

            writer.WriteJsonNode(navigator, navigator.GetRootNode());
        }
Exemple #13
0
            static void Navigate(IJsonNavigator navigator, IJsonNavigatorNode node)
            {
                switch (navigator.GetNodeType(node))
                {
                case JsonNodeType.Null:
                case JsonNodeType.False:
                case JsonNodeType.True:
                case JsonNodeType.Number64:
                case JsonNodeType.Int8:
                case JsonNodeType.Int16:
                case JsonNodeType.Int32:
                case JsonNodeType.Int64:
                case JsonNodeType.UInt32:
                case JsonNodeType.Float32:
                case JsonNodeType.Float64:
                case JsonNodeType.String:
                case JsonNodeType.Binary:
                case JsonNodeType.Guid:
                    break;

                case JsonNodeType.Array:
                    foreach (IJsonNavigatorNode arrayItem in navigator.GetArrayItems(node))
                    {
                        Navigate(navigator, arrayItem);
                    }
                    break;

                case JsonNodeType.Object:
                    foreach (ObjectProperty objectProperty in navigator.GetObjectProperties(node))
                    {
                        IJsonNavigatorNode nameNode  = objectProperty.NameNode;
                        IJsonNavigatorNode valueNode = objectProperty.ValueNode;
                        Navigate(navigator, valueNode);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException($"Unknown {nameof(JsonNodeType)}: '{navigator.GetNodeType(node)}.'");
                }
            }
Exemple #14
0
        public void NavigatorToWriter(
            CurratedDocsPayload payload,
            SerializationFormat sourceFormat,
            SerializationFormat destinationFormat)
        {
            IJsonNavigator navigator = sourceFormat switch
            {
                SerializationFormat.Text => JsonNavigator.Create(payload.Text),
                SerializationFormat.Binary => JsonNavigator.Create(payload.Binary),
                _ => throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: '{sourceFormat}'"),
            };

            IJsonWriter writer = destinationFormat switch
            {
                SerializationFormat.Text => JsonWriter.Create(JsonSerializationFormat.Text),
                SerializationFormat.Binary => JsonWriter.Create(JsonSerializationFormat.Binary),
                SerializationFormat.NewtonsoftText => NewtonsoftToCosmosDBWriter.CreateTextWriter(),
                _ => throw new ArgumentException($"Unexpected {nameof(destinationFormat)} of type: {destinationFormat}"),
            };

            navigator.WriteNode(navigator.GetRootNode(), writer);
        }
            public LazyCosmosObject(IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode)
            {
                if (jsonNavigator == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigator)}");
                }

                if (jsonNavigatorNode == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigatorNode)}");
                }

                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Object)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be a {JsonNodeType.Object} node. Got {type} instead.");
                }

                this.jsonNavigator     = jsonNavigator;
                this.jsonNavigatorNode = jsonNavigatorNode;
            }
            public LazyCosmosArray(
                IJsonNavigator jsonNavigator,
                IJsonNavigatorNode jsonNavigatorNode)
            {
                if (jsonNavigator == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigator)}");
                }

                if (jsonNavigatorNode == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigatorNode)}");
                }

                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Array)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be an {JsonNodeType.Array} node. Got {type} instead.");
                }

                this.jsonNavigator     = jsonNavigator;
                this.jsonNavigatorNode = jsonNavigatorNode;

                this.lazyCosmosElementArray = new Lazy <Lazy <CosmosElement>[]>(() =>
                {
                    Lazy <CosmosElement>[] lazyArray = new Lazy <CosmosElement> [this.jsonNavigator.GetArrayItemCount(this.jsonNavigatorNode)];
                    int index = 0;
                    // Using foreach instead of indexer, since the navigator doesn't support random seeks efficiently.
                    foreach (IJsonNavigatorNode arrayItem in this.jsonNavigator.GetArrayItems(this.jsonNavigatorNode))
                    {
                        lazyArray[index] = new Lazy <CosmosElement>(() => CosmosElement.Dispatch(this.jsonNavigator, arrayItem));
                        index++;
                    }

                    return(lazyArray);
                });
            }
        private void VerifyNavigator(string input, Exception expectedException, bool performExtraChecks = true)
        {
            IJsonReader jsonReader = JsonReader.Create(Encoding.UTF8.GetBytes(input));

            JsonTokenInfo[] tokensFromReader = JsonNavigatorTests.GetTokensWithReader(jsonReader);

            // Test text
            IJsonNavigator     textNavigator = JsonNavigator.Create(Encoding.UTF8.GetBytes(input));
            IJsonNavigatorNode textRootNode  = textNavigator.GetRootNode();

            JsonTokenInfo[] tokensFromTextNavigator = JsonNavigatorTests.GetTokensFromNode(textRootNode, textNavigator, performExtraChecks);

            Assert.IsTrue(tokensFromTextNavigator.SequenceEqual(tokensFromReader));

            // Test binary
            byte[]             binaryInput     = JsonTestUtils.ConvertTextToBinary(input);
            IJsonNavigator     binaryNavigator = JsonNavigator.Create(binaryInput);
            IJsonNavigatorNode binaryRootNode  = binaryNavigator.GetRootNode();

            JsonTokenInfo[] tokensFromBinaryNavigator = JsonNavigatorTests.GetTokensFromNode(binaryRootNode, binaryNavigator, performExtraChecks);

            Assert.IsTrue(tokensFromBinaryNavigator.SequenceEqual(tokensFromReader));

            // Test binary + user string encoding
            JsonStringDictionary jsonStringDictionary = new JsonStringDictionary(capacity: 4096);

            byte[] binaryWithUserStringEncodingInput = JsonTestUtils.ConvertTextToBinary(input, jsonStringDictionary);
            if (jsonStringDictionary.TryGetStringAtIndex(index: 0, value: out string temp))
            {
                Assert.IsFalse(binaryWithUserStringEncodingInput.SequenceEqual(binaryInput), "Binary should be different with user string encoding");
            }
            IJsonNavigator     binaryNavigatorWithUserStringEncoding = JsonNavigator.Create(binaryInput, jsonStringDictionary);
            IJsonNavigatorNode binaryRootNodeWithUserStringEncoding  = binaryNavigatorWithUserStringEncoding.GetRootNode();

            JsonTokenInfo[] tokensFromBinaryNavigatorWithUserStringEncoding = JsonNavigatorTests.GetTokensFromNode(binaryRootNode, binaryNavigator, performExtraChecks);

            Assert.IsTrue(tokensFromBinaryNavigatorWithUserStringEncoding.SequenceEqual(tokensFromReader));
        }
            public LazyCosmosFloat64(
                IJsonNavigator jsonNavigator,
                IJsonNavigatorNode jsonNavigatorNode)
            {
                if (jsonNavigator == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigator)}");
                }

                if (jsonNavigatorNode == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigatorNode)}");
                }

                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Float64)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be a {JsonNodeType.Float64} node. Got {type} instead.");
                }

                this.lazyNumber = new Lazy <double>(() => jsonNavigator.GetFloat64Value(jsonNavigatorNode));
            }
        private void VerifyNavigator(string input, Exception expectedException, bool performExtraChecks = true)
        {
            IJsonReader jsonReader = JsonReader.Create(Encoding.UTF8.GetBytes(input));

            JsonTokenInfo[] tokensFromReader = JsonNavigatorTests.GetTokensWithReader(jsonReader);

            // Test text
            IJsonNavigator     textNavigator = JsonNavigator.Create(Encoding.UTF8.GetBytes(input));
            IJsonNavigatorNode textRootNode  = textNavigator.GetRootNode();

            JsonTokenInfo[] tokensFromTextNavigator = JsonNavigatorTests.GetTokensFromNode(textRootNode, textNavigator, performExtraChecks);

            Assert.IsTrue(tokensFromTextNavigator.SequenceEqual(tokensFromReader));

            // Test binary
            byte[]             binaryInput     = JsonTestUtils.ConvertTextToBinary(input);
            IJsonNavigator     binaryNavigator = JsonNavigator.Create(binaryInput);
            IJsonNavigatorNode binaryRootNode  = binaryNavigator.GetRootNode();

            JsonTokenInfo[] tokensFromBinaryNavigator = JsonNavigatorTests.GetTokensFromNode(binaryRootNode, binaryNavigator, performExtraChecks);

            Assert.IsTrue(tokensFromBinaryNavigator.SequenceEqual(tokensFromReader));
        }
            public LazyCosmosBinary(
                IJsonNavigator jsonNavigator,
                IJsonNavigatorNode jsonNavigatorNode)
            {
                if (jsonNavigator == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigator)}");
                }

                if (jsonNavigatorNode == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigatorNode)}");
                }

                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Binary)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be a {JsonNodeType.Binary} node. Got {type} instead.");
                }

                this.jsonNavigator     = jsonNavigator;
                this.jsonNavigatorNode = jsonNavigatorNode;
                this.lazyBytes         = new Lazy <ReadOnlyMemory <byte> >(() =>
                {
                    if (!this.jsonNavigator.TryGetBufferedBinaryValue(
                            this.jsonNavigatorNode,
                            out ReadOnlyMemory <byte> bufferedBinaryValue))
                    {
                        bufferedBinaryValue = this.jsonNavigator.GetBinaryValue(
                            this.jsonNavigatorNode);
                    }

                    return(bufferedBinaryValue);
                });
            }
            public LazyCosmosGuid(IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode)
            {
                if (jsonNavigator == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigator)}");
                }

                if (jsonNavigatorNode == null)
                {
                    throw new ArgumentNullException($"{nameof(jsonNavigatorNode)}");
                }

                JsonNodeType type = jsonNavigator.GetNodeType(jsonNavigatorNode);

                if (type != JsonNodeType.Guid)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(jsonNavigatorNode)} must be a {JsonNodeType.Guid} node. Got {type} instead.");
                }

                this.lazyGuid = new Lazy <Guid>(() =>
                {
                    return(jsonNavigator.GetGuidValue(jsonNavigatorNode));
                });
            }
Exemple #22
0
 public static CosmosInt32 Create(
     IJsonNavigator jsonNavigator,
     IJsonNavigatorNode jsonNavigatorNode)
 {
     return(new LazyCosmosInt32(jsonNavigator, jsonNavigatorNode));
 }
Exemple #23
0
        private DocumentFeedResponse <CosmosElement> GetFeedResponse(
            DocumentServiceRequest documentServiceRequest,
            DocumentServiceResponse documentServiceResponse)
        {
            // Execute the callback an each element of the page
            // For example just could get a response like this
            // {
            //    "_rid": "qHVdAImeKAQ=",
            //    "Documents": [{
            //        "id": "03230",
            //        "_rid": "qHVdAImeKAQBAAAAAAAAAA==",
            //        "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/",
            //        "_etag": "\"410000b0-0000-0000-0000-597916b00000\"",
            //        "_attachments": "attachments\/",
            //        "_ts": 1501107886
            //    }],
            //    "_count": 1
            // }
            // And you should execute the callback on each document in "Documents".
            MemoryStream memoryStream = new MemoryStream();

            documentServiceResponse.ResponseBody.CopyTo(memoryStream);
            long responseLengthBytes = memoryStream.Length;

            ReadOnlyMemory <byte> content;

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> buffer))
            {
                content = buffer;
            }
            else
            {
                content = memoryStream.ToArray();
            }

            IJsonNavigator jsonNavigator = null;

            // Use the users custom navigator first. If it returns null back try the
            // internal navigator.
            if (this.feedOptions.CosmosSerializationFormatOptions != null)
            {
                jsonNavigator = this.feedOptions.CosmosSerializationFormatOptions.CreateCustomNavigatorCallback(content);
                if (jsonNavigator == null)
                {
                    throw new InvalidOperationException("The CosmosSerializationOptions did not return a JSON navigator.");
                }
            }
            else
            {
                jsonNavigator = JsonNavigator.Create(content);
            }

            string resourceName = this.GetRootNodeName(documentServiceRequest.ResourceType);

            if (!jsonNavigator.TryGetObjectProperty(
                    jsonNavigator.GetRootNode(),
                    resourceName,
                    out ObjectProperty objectProperty))
            {
                throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}");
            }

            IJsonNavigatorNode cosmosElements = objectProperty.ValueNode;

            if (!(CosmosElement.Dispatch(
                      jsonNavigator,
                      cosmosElements) is CosmosArray cosmosArray))
            {
                throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}");
            }

            int itemCount = cosmosArray.Count;

            return(new DocumentFeedResponse <CosmosElement>(
                       cosmosArray,
                       itemCount,
                       documentServiceResponse.Headers,
                       documentServiceResponse.RequestStats,
                       responseLengthBytes));
        }
Exemple #24
0
        /// <summary>
        /// Writes a json node to the internal buffer.
        /// </summary>
        /// <param name="jsonNavigator">The navigator to use to navigate the node</param>
        /// <param name="jsonNavigatorNode">The node to write.</param>
        public void WriteJsonNode(IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode)
        {
            if (jsonNavigator == null)
            {
                throw new ArgumentNullException($"{nameof(jsonNavigator)} can not be null");
            }

            if (jsonNavigatorNode == null)
            {
                throw new ArgumentNullException($"{nameof(jsonNavigatorNode)} can not be null");
            }

            // For now short circuit this to false until we figure out how to optimize this.
            bool sameFormat = jsonNavigator.SerializationFormat == this.SerializationFormat && (this.SerializationFormat == JsonSerializationFormat.Binary || this.SerializationFormat == JsonSerializationFormat.HybridRow);

            JsonNodeType jsonNodeType = jsonNavigator.GetNodeType(jsonNavigatorNode);

            // See if we can write the node without looking at it's value
            switch (jsonNodeType)
            {
            case JsonNodeType.Null:
                this.WriteNullValue();
                return;

            case JsonNodeType.False:
                this.WriteBoolValue(false);
                return;

            case JsonNodeType.True:
                this.WriteBoolValue(true);
                return;
            }

            // If the navigator has the same format as this writer then we try to retrieve the node raw JSON
            IReadOnlyList <byte> bufferedRawJson;

            if (sameFormat && jsonNavigator.TryGetBufferedRawJson(jsonNavigatorNode, out bufferedRawJson))
            {
                // Token type really doesn't make any difference other than whether this is a field name
                JsonTokenType jsonTokenType = (jsonNodeType == JsonNodeType.FieldName ? JsonTokenType.FieldName : JsonTokenType.Null);
                this.WriteRawJsonToken(jsonTokenType, bufferedRawJson);
            }
            else
            {
                // Either the formats did not match or we couldn't retrieve the buffered raw JSON
                switch (jsonNodeType)
                {
                case JsonNodeType.Number:
                    double numberValue = jsonNavigator.GetNumberValue(jsonNavigatorNode);
                    this.WriteNumberValue(numberValue);
                    break;

                case JsonNodeType.String:
                case JsonNodeType.FieldName:
                    bool fieldName = jsonNodeType == JsonNodeType.FieldName;
                    IReadOnlyList <byte> bufferedStringValue;
                    if (jsonNavigator.TryGetBufferedStringValue(jsonNavigatorNode, out bufferedStringValue))
                    {
                        if (fieldName)
                        {
                            this.WriteRawJsonToken(JsonTokenType.FieldName, bufferedStringValue);
                        }
                        else
                        {
                            this.WriteRawJsonToken(JsonTokenType.String, bufferedStringValue);
                        }
                    }
                    else
                    {
                        string value = jsonNavigator.GetStringValue(jsonNavigatorNode);
                        if (fieldName)
                        {
                            this.WriteFieldName(value);
                        }
                        else
                        {
                            this.WriteStringValue(value);
                        }
                    }

                    break;

                case JsonNodeType.Int8:
                {
                    sbyte number = jsonNavigator.GetInt8Value(jsonNavigatorNode);
                    this.WriteInt8Value(number);
                    break;
                }

                case JsonNodeType.Int16:
                {
                    short number = jsonNavigator.GetInt16Value(jsonNavigatorNode);
                    this.WriteInt16Value(number);
                    break;
                }

                case JsonNodeType.Int32:
                {
                    int number = jsonNavigator.GetInt32Value(jsonNavigatorNode);
                    this.WriteInt32Value(number);
                    break;
                }

                case JsonNodeType.Int64:
                {
                    long number = jsonNavigator.GetInt64Value(jsonNavigatorNode);
                    this.WriteInt64Value(number);
                    break;
                }

                case JsonNodeType.UInt32:
                {
                    uint number = jsonNavigator.GetUInt32Value(jsonNavigatorNode);
                    this.WriteUInt32Value(number);
                    break;
                }

                case JsonNodeType.Float32:
                {
                    float number = jsonNavigator.GetFloat32Value(jsonNavigatorNode);
                    this.WriteFloat32Value(number);
                    break;
                }

                case JsonNodeType.Float64:
                {
                    double number = jsonNavigator.GetFloat64Value(jsonNavigatorNode);
                    this.WriteFloat64Value(number);
                    break;
                }

                case JsonNodeType.Guid:
                {
                    Guid number = jsonNavigator.GetGuidValue(jsonNavigatorNode);
                    this.WriteGuidValue(number);
                    break;
                }

                case JsonNodeType.Binary:
                {
                    IReadOnlyList <byte> bufferedBinaryValue;
                    if (jsonNavigator.TryGetBufferedBinaryValue(jsonNavigatorNode, out bufferedBinaryValue))
                    {
                        this.WriteRawJsonToken(JsonTokenType.Binary, bufferedBinaryValue);
                    }
                    else
                    {
                        IReadOnlyList <byte> value = jsonNavigator.GetBinaryValue(jsonNavigatorNode);
                        this.WriteBinaryValue(value);
                    }

                    break;
                }

                case JsonNodeType.Array:
                    this.WriteArrayStart();
                    foreach (IJsonNavigatorNode arrayItem in jsonNavigator.GetArrayItems(jsonNavigatorNode))
                    {
                        this.WriteJsonNode(jsonNavigator, arrayItem);
                    }

                    this.WriteArrayEnd();
                    break;

                case JsonNodeType.Object:
                    this.WriteObjectStart();
                    foreach (ObjectProperty objectProperty in jsonNavigator.GetObjectProperties(jsonNavigatorNode))
                    {
                        this.WriteJsonNode(jsonNavigator, objectProperty.NameNode);
                        this.WriteJsonNode(jsonNavigator, objectProperty.ValueNode);
                    }

                    this.WriteObjectEnd();
                    break;

                default:
                    throw new ArgumentException($"Unexpected JsonNodeType: {jsonNodeType}");
                }
            }
        }
Exemple #25
0
 public static void DrainNavigator(IJsonNavigator jsonNavigator)
 {
     if (jsonNavigator == null)
     {
         throw new ArgumentNullException(nameof(jsonNavigator));
     }
 public static CosmosBinary Create(
     IJsonNavigator jsonNavigator,
     IJsonNavigatorNode jsonNavigatorNode)
 {
     return(new LazyCosmosBinary(jsonNavigator, jsonNavigatorNode));
 }
 public static CosmosFloat64 Create(
     IJsonNavigator jsonNavigator,
     IJsonNavigatorNode jsonNavigatorNode)
 {
     return(new LazyCosmosFloat64(jsonNavigator, jsonNavigatorNode));
 }
        /// <summary>
        /// Converts a list of CosmosElements into a memory stream.
        /// </summary>
        /// <param name="memoryStream">The memory stream response from Azure Cosmos</param>
        /// <param name="resourceType">The resource type</param>
        /// <param name="cosmosSerializationOptions">The custom serialization options. This allows custom serialization types like BSON, JSON, or other formats</param>
        /// <returns>Returns a memory stream of cosmos elements. By default the memory stream will contain JSON.</returns>
        internal static CosmosArray ToCosmosElements(
            MemoryStream memoryStream,
            ResourceType resourceType,
            CosmosSerializationFormatOptions cosmosSerializationOptions = null)
        {
            if (!memoryStream.CanRead)
            {
                throw new InvalidDataException("Stream can not be read");
            }

            // Execute the callback an each element of the page
            // For example just could get a response like this
            // {
            //    "_rid": "qHVdAImeKAQ=",
            //    "Documents": [{
            //        "id": "03230",
            //        "_rid": "qHVdAImeKAQBAAAAAAAAAA==",
            //        "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/",
            //        "_etag": "\"410000b0-0000-0000-0000-597916b00000\"",
            //        "_attachments": "attachments\/",
            //        "_ts": 1501107886
            //    }],
            //    "_count": 1
            // }
            // And you should execute the callback on each document in "Documents".

            long responseLengthBytes = memoryStream.Length;
            ReadOnlyMemory <byte> content;

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> buffer))
            {
                content = buffer;
            }
            else
            {
                content = memoryStream.ToArray();
            }

            IJsonNavigator jsonNavigator;

            // Use the users custom navigator
            if (cosmosSerializationOptions != null)
            {
                jsonNavigator = cosmosSerializationOptions.CreateCustomNavigatorCallback(content);
                if (jsonNavigator == null)
                {
                    throw new InvalidOperationException("The CosmosSerializationOptions did not return a JSON navigator.");
                }
            }
            else
            {
                jsonNavigator = JsonNavigator.Create(content);
            }

            string resourceName = CosmosElementSerializer.GetRootNodeName(resourceType);

            CosmosArray documents;

            if ((jsonNavigator.SerializationFormat == JsonSerializationFormat.Binary) && jsonNavigator.TryGetObjectProperty(
                    jsonNavigator.GetRootNode(),
                    "stringDictionary",
                    out ObjectProperty stringDictionaryProperty))
            {
                // Payload is string dictionary encode so we have to decode using the string dictionary.
                IJsonNavigatorNode   stringDictionaryNode = stringDictionaryProperty.ValueNode;
                JsonStringDictionary jsonStringDictionary = JsonStringDictionary.CreateFromStringArray(
                    jsonNavigator
                    .GetArrayItems(stringDictionaryNode)
                    .Select(item => jsonNavigator.GetStringValue(item))
                    .ToList());

                if (!jsonNavigator.TryGetObjectProperty(
                        jsonNavigator.GetRootNode(),
                        resourceName,
                        out ObjectProperty resourceProperty))
                {
                    throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}");
                }

                IJsonNavigatorNode resources = resourceProperty.ValueNode;

                if (!jsonNavigator.TryGetBufferedBinaryValue(resources, out ReadOnlyMemory <byte> resourceBinary))
                {
                    resourceBinary = jsonNavigator.GetBinaryValue(resources);
                }

                IJsonNavigator navigatorWithStringDictionary = JsonNavigator.Create(resourceBinary, jsonStringDictionary);

                if (!(CosmosElement.Dispatch(
                          navigatorWithStringDictionary,
                          navigatorWithStringDictionary.GetRootNode()) is CosmosArray cosmosArray))
                {
                    throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}");
                }

                documents = cosmosArray;
            }
            else
            {
                // Payload is not string dictionary encoded so we can just do for the documents as is.
                if (!jsonNavigator.TryGetObjectProperty(
                        jsonNavigator.GetRootNode(),
                        resourceName,
                        out ObjectProperty objectProperty))
                {
                    throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}");
                }

                if (!(CosmosElement.Dispatch(
                          jsonNavigator,
                          objectProperty.ValueNode) is CosmosArray cosmosArray))
                {
                    throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}");
                }

                documents = cosmosArray;
            }

            return(documents);
        }
 public static CosmosArray Create(
     IJsonNavigator jsonNavigator,
     IJsonNavigatorNode jsonNavigatorNode) => new LazyCosmosArray(jsonNavigator, jsonNavigatorNode);
Exemple #30
0
        public static async Task RewriteStreamAsTextAsync(ResponseMessage responseMessage, QueryRequestOptions requestOptions)
        {
            // Rewrite the payload to be in the specified format.
            // If it's already in the correct format, then the following will be a memcpy.
            MemoryStream memoryStream;

            if (responseMessage.Content is MemoryStream responseContentAsMemoryStream)
            {
                memoryStream = responseContentAsMemoryStream;
            }
            else
            {
                memoryStream = new MemoryStream();
                await responseMessage.Content.CopyToAsync(memoryStream);
            }

            ReadOnlyMemory <byte> buffer;

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> segment))
            {
                buffer = segment.Array.AsMemory().Slice(start: segment.Offset, length: segment.Count);
            }
            else
            {
                buffer = memoryStream.ToArray();
            }

            IJsonNavigator jsonNavigator = JsonNavigator.Create(buffer);

            if (jsonNavigator.SerializationFormat == JsonSerializationFormat.Text)
            {
                // Exit to avoid the memory allocation.
                return;
            }

            IJsonWriter jsonWriter;

            if (requestOptions?.CosmosSerializationFormatOptions != null)
            {
                jsonWriter = requestOptions.CosmosSerializationFormatOptions.CreateCustomWriterCallback();
            }
            else
            {
                jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text);
            }

            jsonNavigator.WriteTo(jsonNavigator.GetRootNode(), jsonWriter);

            ReadOnlyMemory <byte> result = jsonWriter.GetResult();
            MemoryStream          rewrittenMemoryStream;

            if (MemoryMarshal.TryGetArray(result, out ArraySegment <byte> rewrittenSegment))
            {
                rewrittenMemoryStream = new MemoryStream(rewrittenSegment.Array, index: rewrittenSegment.Offset, count: rewrittenSegment.Count, writable: false, publiclyVisible: true);
            }
            else
            {
                byte[] toArray = result.ToArray();
                rewrittenMemoryStream = new MemoryStream(toArray, index: 0, count: toArray.Length, writable: false, publiclyVisible: true);
            }

            responseMessage.Content = rewrittenMemoryStream;
        }