private static Tuple <CosmosElement, string> ApplyPath(CosmosElement document, IEnumerable <Either <long, string> > tokens) { CosmosObject documentAsObject = (CosmosObject)document; if (!documentAsObject.TryGetValue <CosmosString>("_rid", out CosmosString ridToken)) { throw new ArgumentException("Document did not have a '_rid' field."); } string rid = ridToken.Value; // First token in optional Either <long, string> firstToken = tokens.First(); firstToken.Match( (long longToken) => { throw new InvalidOperationException(); }, (string stringToken) => { if (documentAsObject.TryGetValue(stringToken, out CosmosElement value)) { document = value; } }); foreach (Either <long, string> token in tokens.Skip(1)) { if (document == null) { break; } token.Match( (long arrayIndex) => { CosmosArray arraySubDocument = (CosmosArray)document; if (arrayIndex >= arraySubDocument.Count) { document = null; } else { document = arraySubDocument[(int)arrayIndex]; } }, (string propertyName) => { CosmosObject objectSubDocument = (CosmosObject)document; if (!objectSubDocument.TryGetValue(propertyName, out document)) { document = null; } }); } return(new Tuple <CosmosElement, string>(document, rid)); }
internal 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; 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++) { if (!pathTraversal.TryGetValue(tokens[i], out pathTraversal)) { return(PartitionKey.None); } } if (!pathTraversal.TryGetValue(tokens[tokens.Length - 1], out CosmosElement partitionKeyValue)) { return(PartitionKey.None); } return(this.CosmosElementToPartitionKeyObject(partitionKeyValue)); } finally { // MemoryStream casting leverage might change position stream.Position = 0; } }
public static bool TryCreateFromCosmosElement( CosmosObject parsedContinuationToken, out PipelineContinuationTokenV1 pipelinedContinuationTokenV1) { if (parsedContinuationToken == null) { throw new ArgumentNullException(nameof(parsedContinuationToken)); } if (!PipelineContinuationToken.TryParseVersion( parsedContinuationToken, out Version version)) { pipelinedContinuationTokenV1 = default; return(false); } if (version != PipelineContinuationTokenV1.VersionNumber) { pipelinedContinuationTokenV1 = default; return(false); } if (!parsedContinuationToken.TryGetValue( SourceContinuationTokenPropertyName, out CosmosElement sourceContinuationToken)) { pipelinedContinuationTokenV1 = default; return(false); } pipelinedContinuationTokenV1 = new PipelineContinuationTokenV1(sourceContinuationToken); return(true); }
public void TestPoco() { Person person = Person.GetRandomPerson(); ReadOnlyMemory <byte> result = JsonSerializer.Serialize(person); CosmosObject cosmosObject = (CosmosObject)CosmosElement.CreateFromBuffer(result); Assert.IsTrue(cosmosObject.TryGetValue("Name", out CosmosString personName)); Assert.AreEqual(person.Name, personName.Value.ToString()); Assert.IsTrue(cosmosObject.TryGetValue("Age", out CosmosNumber personAge)); Assert.AreEqual(person.Age, personAge.Value); Assert.IsTrue(cosmosObject.TryGetValue("Children", out CosmosArray personChildren)); Assert.AreEqual(person.Children.Count, personChildren.Count); }
public static IReadOnlyList <Record> GetRecords(this ReadFeedPage page) { using (MemoryStream memoryStream = new MemoryStream()) { page.Content.CopyTo(memoryStream); CosmosObject responseEnvolope = CosmosObject.CreateFromBuffer(memoryStream.ToArray()); if (!responseEnvolope.TryGetValue("Documents", out CosmosArray documents)) { throw new InvalidOperationException(); } List <Record> records = new List <Record>(); foreach (CosmosElement document in documents) { CosmosObject documentObject = (CosmosObject)document; ResourceId rid = ResourceId.Parse(((CosmosString)documentObject["_rid"]).Value); long ticks = Number64.ToLong(((CosmosNumber)documentObject["_ts"]).Value); string id = ((CosmosString)documentObject["id"]).Value; CosmosObject payload = documentObject; Record record = new Record(rid, new DateTime(ticks: ticks, DateTimeKind.Utc), id, payload); records.Add(record); } return(records); } }
private static HashSet <UInt128> Parse128BitHashes(CosmosObject hashDictionary, string propertyName) { HashSet <UInt128> hashSet = new HashSet <UInt128>(); if (!hashDictionary.TryGetValue(propertyName, out CosmosArray array)) { throw new MalformedContinuationTokenException( $"{nameof(UnorderdDistinctMap)} continuation token was malformed."); } foreach (CosmosElement item in array) { if (!(item is CosmosBinary binary)) { throw new MalformedContinuationTokenException( $"{nameof(UnorderdDistinctMap)} continuation token was malformed."); } // Todo have this method work with span<byte> instead to avoid the allocation. UInt128 uint128 = UInt128.FromByteArray(binary.Value.ToArray()); hashSet.Add(uint128); } return(hashSet); }
public async Task <CosmosObject> DecryptAsync( CosmosObject document, Encryptor encryptor, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { Debug.Assert(document != null); Debug.Assert(encryptor != null); Debug.Assert(diagnosticsContext != null); if (!document.TryGetValue(Constants.Properties.EncryptedInfo, out CosmosElement encryptedInfo)) { return(document); } EncryptionProperties encryptionProperties = JsonConvert.DeserializeObject <EncryptionProperties>(encryptedInfo.ToString()); JObject plainTextJObj = await this.DecryptContentAsync( encryptionProperties, encryptor, diagnosticsContext, cancellationToken); Dictionary <string, CosmosElement> documentContent = document.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); documentContent.Remove(Constants.Properties.EncryptedInfo); foreach (JProperty property in plainTextJObj.Properties()) { documentContent.Add(property.Name, property.Value.ToObject <CosmosElement>()); } return(CosmosObject.Create(documentContent)); }
private static bool TryParseTokenListForElement(CosmosObject pathTraversal, IReadOnlyList <string> tokens, out CosmosElement result) { result = null; for (int i = 0; i < tokens.Count - 1; i++) { if (!pathTraversal.TryGetValue(tokens[i], out pathTraversal)) { return(false); } } if (!pathTraversal.TryGetValue(tokens[tokens.Count - 1], out result)) { return(false); } return(true); }
private T GetAndAssertObjectProperty <T>(CosmosObject cosmosObject, string propertyName) where T : CosmosElement { Assert.IsTrue(cosmosObject.TryGetValue(propertyName, out CosmosElement lazyElement), $"Object does not contain the {propertyName} property."); T lazyPropertyValue = lazyElement as T; Assert.IsNotNull(lazyPropertyValue, $"Object property {propertyName} is not {typeof(T).Name}."); return(lazyPropertyValue); }
private static CosmosArray GetChanges(Stream stream) { using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); CosmosObject element = CosmosObject.CreateFromBuffer(memoryStream.ToArray()); if (!element.TryGetValue("Documents", out CosmosArray value)) { Assert.Fail(); } return(value); } }
private static int GetResponseCount(Stream stream) { using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); CosmosObject element = CosmosObject.CreateFromBuffer(memoryStream.ToArray()); if (!element.TryGetValue("_count", out CosmosElement value)) { Assert.Fail(); } return((int)Number64.ToLong(((CosmosNumber)value).Value)); } }
public CosmosElement Visit(CosmosObject cosmosObject, CosmosElement indexer) { if (!(indexer is CosmosString indexerAsString)) { return(Undefined); } string stringIndexValue = indexerAsString.Value; if (!cosmosObject.TryGetValue(stringIndexValue, out CosmosElement propertyValue)) { return(Undefined); } return(propertyValue); }
public async Task ChangeFeedIteratorCore_BreathFirst() { int expected = 500; CosmosObject previousToken = null; ContainerInternal itemsCore = await this.InitializeLargeContainerAsync(); await this.CreateRandomItems(itemsCore, expected, randomPartitionKey : true); ChangeFeedIteratorCore feedIterator = itemsCore.GetChangeFeedStreamIterator( ChangeFeedStartFrom.Beginning(), ChangeFeedMode.Incremental, new ChangeFeedRequestOptions() { PageSizeHint = 1, }) as ChangeFeedIteratorCore; while (true) { using (ResponseMessage responseMessage = await feedIterator.ReadNextAsync(this.cancellationToken)) { CosmosObject cosmosObject = CosmosObject.Parse(responseMessage.ContinuationToken); if (!cosmosObject.TryGetValue("Continuation", out CosmosArray cosmosArray)) { Assert.Fail(); throw new Exception(); } CosmosObject currentToken = (CosmosObject)cosmosArray[0]; if (previousToken != null) { // Verify that the token, even though it yielded results, it moved to a new range Assert.AreNotEqual(previousToken, currentToken); break; } previousToken = currentToken; if (responseMessage.StatusCode == HttpStatusCode.NotModified) { break; } } } }
private static bool TryParseSourceContinuationToken( CosmosObject parsedContinuationToken, out string sourceContinuationToken) { if (parsedContinuationToken == null) { throw new ArgumentNullException(nameof(parsedContinuationToken)); } if (!parsedContinuationToken.TryGetValue <CosmosString>( PipelineContinuationTokenV1.SourceContinuationTokenPropertyName, out CosmosString parsedSourceContinuationToken)) { sourceContinuationToken = default(string); return(false); } sourceContinuationToken = parsedSourceContinuationToken.Value; return(true); }
public RewrittenAggregateProjections(bool isValueAggregateQuery, CosmosElement raw) { if (raw == null) { throw new ArgumentNullException(nameof(raw)); } if (isValueAggregateQuery) { // SELECT VALUE [{"item": {"sum": SUM(c.blah), "count": COUNT(c.blah)}}] CosmosArray aggregates = raw as CosmosArray; if (aggregates == null) { throw new ArgumentException($"{nameof(RewrittenAggregateProjections)} was not an array for a value aggregate query. Type is: {raw.Type}"); } this.Payload = aggregates[0]; } else { CosmosObject cosmosObject = raw as CosmosObject; if (cosmosObject == null) { throw new ArgumentException($"{nameof(raw)} must not be an object."); } if (!cosmosObject.TryGetValue("payload", out CosmosElement cosmosPayload)) { throw new InvalidOperationException($"Underlying object does not have an 'payload' field."); } // SELECT {"$1": {"item": {"sum": SUM(c.blah), "count": COUNT(c.blah)}}} AS payload if (cosmosPayload == null) { throw new ArgumentException($"{nameof(RewrittenAggregateProjections)} does not have a 'payload' property."); } this.Payload = cosmosPayload; } }
private static bool TryParseQueryPlan( CosmosObject parsedContinuationToken, out PartitionedQueryExecutionInfo queryPlan) { if (parsedContinuationToken == null) { throw new ArgumentNullException(nameof(parsedContinuationToken)); } if (!parsedContinuationToken.TryGetValue( PipelineContinuationTokenV1_1.QueryPlanPropertyName, out CosmosElement parsedQueryPlan)) { queryPlan = default; return(false); } if (parsedQueryPlan is CosmosNull) { queryPlan = null; return(true); } else if (parsedQueryPlan is CosmosString queryPlanString) { if (!PartitionedQueryExecutionInfo.TryParse(queryPlanString.Value, out queryPlan)) { queryPlan = default; return(false); } } else { queryPlan = default; return(false); } return(true); }