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)); }
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)); }
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()); }
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); }
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); }
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()); }
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); }
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()); }
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)}.'"); } }
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)); }); }
public static CosmosInt32 Create( IJsonNavigator jsonNavigator, IJsonNavigatorNode jsonNavigatorNode) { return(new LazyCosmosInt32(jsonNavigator, jsonNavigatorNode)); }
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)); }
/// <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}"); } } }
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);
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; }